Gin框架集成Zap日志库

2023-03-22 20:16:12 490

在go语言gin框架中,日志是默认输出到终端的,但是我们在实际工作中,一般来说是需要记录服务器日志的。而最常用的日志库就是zap日志库,我们需要将gin在终端输出的内容通过zap日志库记录到文件中

假设你已配置好了Gin/Zap

ginDefault := gin.New()
ginDefault.Use(GinLogger(), GinRecovery(true))
// GinLogger 接收gin框架默认的日志
func GinLogger() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()
		path := c.Request.URL.Path
		query := c.Request.URL.RawQuery
		c.Next()
		cost := time.Since(start).Milliseconds()

		if query != "" {
			path = path + "?" + query
		}

		// 写入日志
		global.GLog.Info(fmt.Sprintf("[GIN] |%s|%9s |%17s |%s \"%s\"", colorfulStatus(c.Writer.Status()),
			fmt.Sprintf("%dms", cost),
			c.ClientIP(), colorfulMethod(c.Request.Method), path),
			zap.String("User-Agent", c.Request.UserAgent()))
	}
}

func colorfulStatus(status int) string {
	var colorCode string
	if status == 200 {
		colorCode = "\033[0;42m %d \033[0m"
	} else if status == 404 {
		colorCode = "\033[0;43;30m %d \033[0m"
	} else {
		colorCode = "\033[0;41m %d \033[0m"
	}
	return fmt.Sprintf(colorCode, status)
}

func colorfulMethod(method string) string {
	var colorCode string
	switch method {
	case "POST":
		colorCode = "\033[0;48;2;120;220;232;38;2;255;255;255m %-8s\033[0m"
	case "GET":
		colorCode = "\033[0;48;2;252;152;103;38;2;255;255;255m %-8s\033[0m"
	case "PUT":
		colorCode = "\033[0;43;30m %-8s\033[0m"
	case "DELETE":
		colorCode = "\033[0;48;2;255;97;136;97m %-8s\033[0m"
	case "OPTIONS":
		colorCode = "\033[0;48;2;147;146;147;38;2;98;88;98m %-8s\033[0m"
	default:
		colorCode = " %-8s"
	}
	return fmt.Sprintf(colorCode, method)
}

// GinRecovery recover掉项目可能出现的panic
// 此函数是捕获panic,根据gin框架内的Recovery修改的
func GinRecovery(stack bool) gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				var brokenPipe bool
				if ne, ok := err.(*net.OpError); ok {
					if se, ok := ne.Err.(*os.SyscallError); ok {
						if strings.Contains(strings.ToLower(se.Error()), "broken pipe") ||
							strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
							brokenPipe = true
						}
					}
				}

				httpRequestByteArr, _ := httputil.DumpRequest(c.Request, true)
				httpRequestString := strings.ReplaceAll(string(httpRequestByteArr), "\r\n", " ")

				var errInfo string
				if brokenPipe {
					errInfo = c.Request.URL.Path
				} else {
					errInfo = "[Recovery from panic]"
				}

				global.GLog.Error(errInfo, zap.Any("error", err), zap.String("request", httpRequestString))

				if brokenPipe {
					_ = c.Error(err.(error))
					c.Abort()
					return
				}

				if stack {
					stack := string(debug.Stack())
					global.GLog.Error(stack)
				}

				c.JSON(http.StatusInternalServerError, resp.Response{
					Code: resp.Error,
					Msg:  "server error",
				})
			}
		}()
		c.Next()
	}
}

1.png

这个时候再访问一下127.0.0.1就会发现你的当前目录下多了一个info.log的文件,打开后可以看到里面的内容是一条日志

简易Mac历史剪切板

简易Mac历史剪切板

基于go-fyne, 自动存储剪切板历史记录 (只支持文本)main.gopackage main import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/d
2024-11-28

Gin框架集成Zap日志库

在go语言gin框架中,日志是默认输出到终端的,但是我们在实际工作中,一般来说是需要记录服务器日志的。而最常用的日志库就是zap日志库,我们需要将gin在终端输出的内容通过zap日志库记录到文件中假设你已配置好了Gin/ZapginDefault := gin.New() ginDefault.Us
2023-03-22

Ubuntu Golang 编译 + Docker部署

配置Golang编译环境下载go环境 https://studygolang.com/dl 选择go1.20.2.linux-amd64.tar.gztar -zxvf go1.20.2.linux-amd64.tar.gz 解压到 /usr/local/go创建 /usr/local/go-pat
2023-03-22

Go的方法接收: 值接收与指针接收

package main import "fmt" type Circle struct { r uint } func (c *Circle) add() uint { c.r++ return c.r } func (c Circle) show() uint { c.r++
2023-03-04

快速上手Go以及实战Gin+Gorm

阅读本文需要一定的java开发经验以及一点c/c++的基础语法特性变量命名一般是名称在前, 类型在后匿名变量使用_标记忽略常量使用 const, 例const c_name1, c_name2 = value1, value2. 关键字: iota, 索引自增进行初始化常量package main
2022-12-20

解决GoLand无法Debug

go 1.20rc1goland 2022.2.3无法进行debug控制台提示WARNING: undefined behavior - version of Delve is too old for Go version 1.20.-1 (maximum supported version 1.1
2022-12-14

freemarker 时间显示不正常 设置时区

项目在本地开发的时候显示正常,部署上服务器就一直差8个小时,最后发现freemarker官方文档有这样的说明time_zone:时区的名称来显示并格式化时间。 默认情况下,使用JVM的时区。 也可以是 Java 时区 API 接受的值,或者 "JVM default" (从 FreeMarker 2
2020-03-28
IDEA 2019.1 xml 不高亮

IDEA 2019.1 xml 不高亮

前几天更新了idea后,发现xml里的代码都没有了高亮,变得跟记事本一个德性了打开setting ,搜索 File Types,找到xml项, 查看下方的匹配格式,果然没有xml,(idea真是厉害)点击右方的+,输入*.xml,点击ok,解决问题
2020-03-28

npm install 淘宝镜像

npm install --registry=https://registry.npm.taobao.org
2020-03-28
Java中方法的参数传递机制

Java中方法的参数传递机制

来看一段代码 public class Man { private String name; private Integer age; public String getName() { return name; } publi
2020-03-28
基于自定义注解手写权限控制

基于自定义注解手写权限控制

方法一: AOP 方法二: 拦截器项目结构项目依赖<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-w
2020-03-28

Docker 部署 详细全过程 附代码

Docker 部署本站 全过程环境:CentOS7.61. 安装Docker其他版本CentOS可以参考这个https://help.aliyun.com/document_detail/187598.html查看本机内核版本,内核版本需高于 3.10uname -r 确保 yum 包最新yum u
2020-03-28

SpringBoot 启动普通java工程

引入依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.0.9</version> </dependency>
2020-03-28

Vue.js DOM操作

<template> <input type="button" @click="reply($event)" value="回复"> </template> export default { methods: { replyFun(e) {
2020-03-29
CentOS7编译调试OpenJDK12

CentOS7编译调试OpenJDK12

1. 下载源码https://hg.openjdk.java.net/jdk/jdk12点击左侧的browse,再点击zip,就可以下载zip格式的源码压缩包。unzip xxx.zip 解压文件2. 安装jdkyum install java-11-openjdk-devel -y3. 运行con
2020-04-23
编写自己的Spring Boot Starter

编写自己的Spring Boot Starter

1.新建一个maven项目命名规则统一是xxx-spring-boot-starter完整pom.xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"
2020-06-29