14、Go Gin打印日志

1、使用标准库log包

使用Go的标准库log包,可以快速打印日志到控制台或者文件。

package mainimport ("github.com/gin-gonic/gin""log"
)func main() {r := gin.Default()r.GET("/ping", func(c *gin.Context) {log.Println("请求方式" + c.Request.Method)c.JSON(200, gin.H{"message": "pong",})})r.Run()
}

2、使用Gin的内置日志功能

Gin框架提供了内置的日志功能,可以通过设置Logger来开启。

package mainimport ("github.com/gin-gonic/gin"
)func main() {r := gin.Default()// 开启日志r.Use(gin.Logger())r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong",})})r.Run()
}

3、自定义日志

如果你需要更复杂的日志处理,比如将日志输出到不同的目的地,或者添加自定义的日志格式,你可以使用中间件来实现。

package mainimport ("github.com/gin-gonic/gin""log""time"
)func Logger() gin.HandlerFunc {return func(c *gin.Context) {// 在调用后续的处理函数之前,打印请求信息t := time.Now()c.Next() // 调用后续的处理函数// 在调用后续的处理函数之后,打印响应信息latency := time.Since(t)log.Printf("%s %s %s %d %s\n", c.ClientIP(), c.Request.Method, c.Request.URL.Path, c.Writer.Status(), latency)}
}func main() {r := gin.Default()// 使用自定义的Logger中间件r.Use(Logger())r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong",})})r.Run()
}

 4、日志打印输出

package mainimport ("github.com/gin-gonic/gin""log""net/http""os"
)func main() {// 创建 Gin 实例r := gin.Default()// 创建日志文件f, err := os.OpenFile("gin.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err != nil {log.Fatalf("无法设置日志文件: %v", err)}defer f.Close()// 设置日志输出到文件log.SetOutput(f)gin.DefaultWriter = f // 将Gin的默认输出改为这个文件// 配置 Gin 的日志r.Use(gin.LoggerWithWriter(f))// 设置路由r.GET("/ping", func(c *gin.Context) {log.Printf(c.Request.RemoteAddr)log.Printf(c.Request.Proto)log.Printf(c.Request.Host)log.Printf(c.Request.Method)log.Printf(c.Request.RequestURI)c.String(http.StatusOK, "Hello World!")})// 启动服务器r.Run()
}

5、使用第三方日志库

你还可以使用第三方的日志库,如zaplogrus等,来提供更强大的日志功能。

zap: 

package mainimport ("github.com/gin-gonic/gin""go.uber.org/zap"
)var logger *zap.Loggerfunc init() {logger, _ = zap.NewProduction()defer logger.Sync() // flushes buffer, if any
}func main() {r := gin.Default()r.Use(func(c *gin.Context) {logger.Info("正在处理请求", zap.String("path", c.Request.URL.Path))c.Next()})r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong",})})r.Run()
}

 logrus:

package mainimport ("github.com/gin-gonic/gin""github.com/sirupsen/logrus""os"
)var log = logrus.New()
var logFile *os.Filefunc init() {// 以JSON格式而不是默认的ASCII格式器进行日志记录。log.Formatter = &logrus.JSONFormatter{}//输出到stdout而不是默认的stderr//可以是任何io.Writer,请参阅下面的文件示例//logFile, _ := os.Create("./gin.log")//使用os.Create函数创建文件时,默认情况下新创建的文件是空的,任何写入都会追加到文件末尾// 使用os.OpenFile而不是os.Create// flag参数设置为os.O_CREATE和os.O_APPEND,这意味着文件将被创建(如果它不存在)并且写入将追加到文件末尾// perm参数设置文件的权限(例如0644),这是一个常用的选项,表示文件对所有用户可读写,但只对拥有者可执行logFile, err := os.OpenFile("./gin.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)if err != nil {log.Fatal(err)}//defer f.Close()log.Out = logFilegin.SetMode(gin.ReleaseMode)gin.DefaultWriter = log.Out// 仅记录警告严重性或更高级别输出log.Level = logrus.InfoLevel
}func main() {// 创建一个默认的路由引擎r := gin.Default()defer logFile.Close()// GET:请求方式;/hello:请求的路径// 当客户端以GET方法请求/hello路径时,会执行后面的匿名函数r.GET("/hello", func(c *gin.Context) {log.WithFields(logrus.Fields{"animal": "狼","size":   10,}).Warn("一群狼在丛林中出现")// c.JSON:返回JSON格式的数据c.JSON(200, gin.H{"message": "Hello 狼!",})})r.Run(":8080")
}

 6、gin 日志高级配置

1)配置Gin的Logger中间件

Gin框架的Logger中间件允许你配置日志的输出格式和级别。

go get -u gopkg.in/natefinch/lumberjack.v2
package mainimport ("github.com/gin-gonic/gin""gopkg.in/natefinch/lumberjack.v2""log"
)func main() {// 创建 lumberjack.Logger 实例lumberjackLogger := &lumberjack.Logger{Filename:   "gin.log", // 日志文件路径MaxSize:    100,       // 日志文件最大大小(MB)MaxBackups: 5,         // 日志文件最大备份数MaxAge:     30,        // 日志文件最大保存时间(天)Compress:   true,      // 是否压缩/归档旧文件}// 将标准库的 log 输出重定向到 lumberjack.Loggerlog.SetOutput(lumberjackLogger)// 创建 Gin 路由器r := gin.New()// 使用 lumberjack.Logger 作为 Gin 的日志输出r.Use(gin.LoggerWithWriter(lumberjackLogger))// 你的路由和中间件配置r.GET("/ping", func(c *gin.Context) {log.Println("请求方式" + c.Request.Method) // 这将输出到 lumberjack 配置的文件中c.JSON(200, gin.H{"message": "pong",})})// 运行 Gin 服务器r.Run()
}

无论是你的自定义日志输出还是 Gin 框架的日志输出,都会被写入到 lumberjack 配置的 gin.log 文件中。如果你使用的是其他日志库(如 zaplogrus),你需要根据该库的文档来配置输出到 lumberjack.Logger

2)Gin集成zap&lumberjack

package mainimport (ginzap "github.com/gin-contrib/zap""github.com/gin-gonic/gin""go.uber.org/zap""go.uber.org/zap/zapcore""gopkg.in/natefinch/lumberjack.v2""time"
)// 初始化zap logger
func initZapLogger() (*zap.Logger, error) {// lumberjack 日志切割lumberJackLogger := &lumberjack.Logger{Filename:   "./gin.log", // 日志文件路径MaxSize:    100,         // 日志文件最大大小(MB)MaxBackups: 5,           // 日志文件最大备份数MaxAge:     30,          // 日志文件最大保存时间(天)Compress:   true,        // 是否压缩/归档旧文件}// 配置zap核心encoderConfig := zap.NewProductionEncoderConfig()encoderConfig.EncodeTime = zapcore.RFC3339TimeEncoderencoderConfig.EncodeLevel = zapcore.LowercaseLevelEncodercore := zapcore.NewCore(zapcore.NewJSONEncoder(encoderConfig),zapcore.AddSync(lumberJackLogger),       // 使用 lumberjack 作为日志输出zap.NewAtomicLevelAt(zapcore.InfoLevel), // 设置日志级别)// 创建zap loggerreturn zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1)), nil
}var logger *zap.Loggerfunc main() {// 初始化zap loggervar err errorlogger, err = initZapLogger()if err != nil {panic("初始化zap logger失败: " + err.Error())}defer logger.Sync() // flushes buffer, if any// 创建Gin路由器r := gin.New()// 使用zap logger中间件r.Use(ginzap.Ginzap(logger, time.RFC3339, true))// 其他Gin配置...// 你的路由和中间件配置r.GET("/ping", func(c *gin.Context) {logger.Info("收到一个到/ping的GET请求")c.JSON(200, gin.H{"message": "pong",})})// 运行Gin服务器r.Run()
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/14241.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7和centos8安装mysql5.6 5.7 8.0

https://dev.mysql.com/downloads/repo/yum/ 注意构造下http://repo.mysql.com/mysql-community-release-el*-*.noarch.rpm 【以centos7为例】 安装mysql5.6 wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5…

byzer plugin install log

离线插件参考地址: Byzer Documentation 离线安装方式(错误过程记录): 参考文档:https://docs.byzer.org/#/byzer-lang/zh-cn/extension/README Byzer-lang 支持插件安装,删除,获取列表等。安装…

探索Linux中的神奇工具:深入了解find命令

探索Linux中的神奇工具:深入了解find命令 在Linux系统中,find命令是一个强大且灵活的工具,用于在文件系统中查找符合条件的文件和目录。本文将详细介绍find命令的基本用法和一些常见选项,帮助读者更好地理解和运用这个命令。 了…

力扣3152. 特殊数组 II

如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组 。 周洋哥有一个整数数组 nums 和一个二维整数矩阵 queries,对于 queries[i] [fromi, toi],请你帮助周洋哥检查子数组 nums[fromi..toi] 是不是一个 特殊…

hcip—VLAN实验

目录 实验拓扑: 实验目的: 实验思路: 实验步骤: 1.创建VLAN 2.将接口放进相应VLAN当中,并配置接口类型(hybrid口配置撕tag表) 3.配置路由器接口 4.配置DHCP服务 pc1 ping pc4的过程分析…

esp32 编程指南核心文件

ESP-IDF 编程指南 - ESP32-C3 - — ESP-IDF 编程指南 v5.1 文档 (espressif.com) ESP-IDF 入门指南 | 乐鑫科技 (espressif.com)

linux下的docker使用

docker是什么,docker翻译过来的意思就是码头工人,顾名思义,docker本质上就是一个搬运工,只不过从搬运货物改成了搬运程序,使搬运的不同的程序能够独立的运行在码头上的不同容器内,互不干扰,而他…

“腾讯云 AI 代码助手”体验

一、“腾讯云 AI 代码助手”体验 1、注册账号并进行实名认证 2、进入开发环境 3、体验javascript简单函数 代码如下: //请写一个两个日期计算的函数 function dateDiff(date1, date2) {return date2.getTime() - date1.getTime(); } var date1 new Date("2…

智享无人直播系统(三代)融合AI智能互动,成就无人直播行业的新巨星!

随着直播行业的不断发展,智享直播(三代)作为首家自主研发的智能AI直播软件引领了行业的新潮流。相比市场上的其他同类软件,我们的软件通过创新的功能实现了直播间的AI智能互动,提供了丰富而个性化的直播体验。最重要的…

fmql入门之对标zynq差异(2)

还是有很多地方需要注意的,细节又繁琐。 AXI 接上一篇,Program bit后,IAR debug无现象: prinft没有打印出字符串;GPIO初始化失败。 不知道是不是vivado补丁失败的原因: 但是重新分析综合后还是这样。 …

Lc43---- 1221. 分割平衡字符串(java版)---(贪心)(字符串)

1.题目描述 2.知识点和思路 (1)贪心算法的基本思想 选择性质:在每一步中,选择当前最优的选项,不考虑未来的后果。 局部最优解:通过一系列局部最优选择,构建全局最优解。 不可回溯:一…

2024电工杯A题详细思路代码分析数学建模:园区微电网风光储协调优化配置

题目分析:园区微电网风光储协调优化配置 我们会先给出三个问题总体的分析,最后会详细分析问题一的建模和详细内容。 背景: 园区微电网由风光发电和主电网联合为负荷供电,为了尽量提高风光电量的负荷占比,需配置较高比…

SpringBoot 实现图片防盗链功能

前言 出于安全考虑,我们需要后端返回的图片只允许在某个网站内展示,不想被爬虫拿到图片地址后被下载。或者,不想浏览器直接访问图片链接。 出于性能考虑,不想要别人的网站,拿着我们的图片链接去展示,白白…

【Spring】Spring事务管理——声明式事务管理代码示例

1、声明式事务管理 步骤一&#xff1a;添加Spring和JDBC的依赖 <dependencies> <!-- Spring Core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>你的S…

python+opencv提取.mp4 视频的每一帧并将其保存为图片

提取 .mp4 视频的每一帧并将其保存为图片&#xff0c;可以使用 cv2 库&#xff08;OpenCV&#xff09;。下面是一个完整的示例代码&#xff0c;演示如何使用 OpenCV 提取视频的每一帧并将其保存为图片&#xff0c;使用时需要将mp4文件及路径放至video_path &#xff0c;提取的图…

02--大数据Hadoop集群实战

前言&#xff1a; 前面整理了hadoop概念内容&#xff0c;写了一些概念和本地部署和伪分布式两种&#xff0c;比较偏向概念或实验&#xff0c;今天来整理一下在项目中实际使用的一些知识点。 1、基础概念 1.1、完全分布式 Hadoop是一个开源的分布式存储和计算框架&#xff0…

C++对C的扩充

C既可用于面向过程的程序设计&#xff0c;也可用于面向对象的程序设计。在面向过程程序设计的领域&#xff0c;C继承了C语言提供的绝大部分功能和语法规定&#xff0c;并在此基础上做了不少扩充&#xff0c;主要有一下几个方面&#xff1a; 1.C的输入输出 C为了方便用户&…

Spring 事务源码分析

前言&#xff1a; 我们知道 Spring 声明式事务是通过 AOP 来实现的&#xff0c;日常项目开发中我们只需要使用 Transactional 注解就可以实现声明式事务&#xff0c;那你知道通过 Transactional 注解怎样实现事务的吗&#xff1f;本篇我们将从源码来分析 Spring 声明式事务的执…

STM32定时器四大功能之定时器编码接口

1什么是编码器接口&#xff1f; 编码器接口接受编码器的正交信号&#xff0c;根据编码器产生的正交信号脉冲控制CNT的自增和自减&#xff0c;从而指示编码器的旋转方向和旋转速度。 每个高级定时器和通用定时器都有一个编码器接口&#xff0c;同时正交编码器产生的正交信号分…

Redis 的持久化(真的好细)

前言 Redis 是一个内存数据库&#xff0c;把数据存储在内存中&#xff0c;而内存中的数据是不持久的&#xff0c;要想数据持久就得将数据存储到硬盘中&#xff0c;而 Redis 相比于 Mysql 这样的关系型数据库最大的优势就在于将数据存储在内存中从而效率更高&#xff0c;速度更快…