uber-go/zap sirupsen/logrus

news2024/9/23 1:23:25

文章目录

      • `uber-go/zap` 和 `sirupsen/logrus`日志库对比
        • 1. **性能**
        • 2. **易用性和灵活性**
        • 3. **结构化日志**
        • 4. **生态系统和可扩展性**
        • 5. **输出格式**
        • 6. **使用场景**
        • 总结
      • Zap库在Gin中的实践
        • 1. **安装 `zap`**
        • 2. **封装 `zap` 日志**
        • `logger.go` - 封装 `zap` 日志
        • 3. **将 `zap` 集成到 `gin` 中**
        • `main.go` - 集成 `zap` 日志到 `gin`
        • 4. **说明**
        • 5. **运行项目**
      • logrus在GIN中的实践
        • 1. **安装 `logrus`**
        • 2. **封装 `logrus` 日志**
        • `logger.go` - 封装 `logrus` 日志
        • 3. **将 `logrus` 集成到 `gin` 中**
        • `main.go` - 集成 `logrus` 日志到 `gin`
        • 4. **说明**
        • 5. **运行项目**

uber-go/zapsirupsen/logrus日志库对比

uber-go/zapsirupsen/logrus 是 Go 中两个常用的日志库,各有其优点和适用场景。以下是对这两个库的对比以及它们的使用场景:

1. 性能
  • Zap

    • 以高性能和低内存分配著称。
    • 以效率为核心设计,使用预分配的 JSON 编码器,避免了反射的使用。
    • 适用于日志记录频繁、对性能要求极高的高吞吐量应用(例如微服务、实时系统)。
  • Logrus

    • 更易用,但性能较 Zap 慢。
    • 使用反射,提供更简单的接口,但会带来一定的性能开销。
    • 适合那些易用性和灵活性比纯性能更重要的应用(例如命令行工具、内部工具)。
2. 易用性和灵活性
  • Zap

    • 提供两种模式:SugaredLogger(更易用,性能略低)和 Logger(高性能,灵活性较低)。
    • 创建结构化日志时相对更冗长,灵活性不如 Logrus。
    • 由于注重性能,设置较复杂,学习曲线更陡峭。
  • Logrus

    • 用户友好的 API,可轻松创建结构化日志。
    • 使用反射提供更直观的结构化日志接口。
    • 更灵活,上手更容易,适合初学者或简单项目。
3. 结构化日志
  • Zap

    • 默认专注于结构化日志。

    • 使用强类型字段,提高类型安全性,减少运行时错误的可能性。

    • 示例:

      logger.Info("User login",
          zap.String("username", "john_doe"),
          zap.Int("user_id", 42),
      )
      
  • Logrus

    • 支持使用字段的结构化日志,在添加字段方面更灵活。

    • 示例:

      logrus.WithFields(logrus.Fields{
          "username": "john_doe",
          "user_id":  42,
      }).Info("User login")
      
4. 生态系统和可扩展性
  • Zap

    • 与 Logrus 相比,内置钩子较少,更关注核心性能。
    • 支持自定义编码器和高级配置,用于不同的输出格式。
  • Logrus

    • 丰富的生态系统,包含许多内置钩子和第三方扩展。
    • 易于扩展并集成到不同的日志后端,例如将日志发送到外部系统(例如 ElasticSearch、Logstash)。
5. 输出格式
  • Zap

    • 主要输出 JSON 格式,适合结构化日志和机器解析。
    • 支持控制台编码,但在输出定制方面灵活性不如 Logrus。
  • Logrus

    • 默认提供更易读的人类可读格式,如文本格式,方便在开发或调试期间阅读。
    • 也支持 JSON 输出,允许轻松定制输出格式。
6. 使用场景
  • Zap

    • 高性能服务、微服务、实时系统以及日志记录可能成为瓶颈的应用。
    • 需要结构化日志以进行日志解析和分析的系统。
  • Logrus

    • 当易用性和灵活性比性能更重要的应用。
    • 命令行工具、开发环境或内部工具,适合需要人类可读日志的场景。
总结
  • 使用 Zap 如果你需要最高的性能,且应用的高吞吐量对结构化日志和最小化开销有严格要求。
  • 使用 Logrus 如果你更注重易用性和灵活性,应用的性能不是首要考虑因素,或者需要与各种日志后端轻松集成。

在许多情况下,选择取决于应用的具体需求,比如所需的性能水平以及对易用性和效率的重视程度。

Zap库在Gin中的实践

要在 gin 项目中使用 uber-go/zap 并将其封装成一个可复用的函数,可以按照以下步骤进行:

1. 安装 zap

首先,确保你的项目中安装了 zap

go get -u go.uber.org/zap
2. 封装 zap 日志

创建一个封装 zap 日志初始化和使用的函数。以下是一个示例代码,包括了如何将 zap 日志集成到 gin 中:

logger.go - 封装 zap 日志
package logger

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"time"
)

// InitZapLogger initializes a zap logger
func InitZapLogger() (*zap.Logger, error) {
	// Customizing the zap logger
	config := zap.Config{
		Encoding:         "json", // or "console"
		Level:            zap.NewAtomicLevelAt(zap.InfoLevel),
		OutputPaths:      []string{"stdout"},
		ErrorOutputPaths: []string{"stderr"},
		EncoderConfig: zapcore.EncoderConfig{
			TimeKey:        "time",
			LevelKey:       "level",
			NameKey:        "logger",
			CallerKey:      "caller",
			MessageKey:     "msg",
			StacktraceKey:  "stacktrace",
			LineEnding:     zapcore.DefaultLineEnding,
			EncodeLevel:    zapcore.LowercaseLevelEncoder, // Lowercase level names
			EncodeTime:     zapcore.ISO8601TimeEncoder,    // ISO8601 time format
			EncodeDuration: zapcore.SecondsDurationEncoder,
			EncodeCaller:   zapcore.ShortCallerEncoder,
		},
	}
	
	return config.Build()
}
3. zap 集成到 gin

gin 项目中,使用中间件将 zap 集成到 HTTP 请求处理流程中。

main.go - 集成 zap 日志到 gin
package main

import (
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"your_project/logger" // Replace with the correct path to logger.go
	"time"
)

func main() {
	// Initialize zap logger
	zapLogger, err := logger.InitZapLogger()
	if err != nil {
		panic(err)
	}
	defer zapLogger.Sync() // Flush any buffered log entries

	// Create a new Gin router
	r := gin.New()

	// Custom middleware to log requests with zap
	r.Use(func(c *gin.Context) {
		startTime := time.Now()
		
		// Process request
		c.Next()
		
		// Log request details
		zapLogger.Info("Incoming request",
			zap.String("method", c.Request.Method),
			zap.String("path", c.Request.URL.Path),
			zap.Int("status", c.Writer.Status()),
			zap.Duration("latency", time.Since(startTime)),
			zap.String("client_ip", c.ClientIP()),
		)
	})

	// Define routes
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})

	// Start the server
	r.Run(":8080")
}
4. 说明
  • InitZapLogger: 封装了 zap 的初始化逻辑,创建了一个 json 格式的日志配置。可以根据需要调整日志级别、输出路径和编码格式。
  • Gin 中间件: 在 gin 中注册一个中间件,记录 HTTP 请求的基本信息(如方法、路径、状态码、耗时等)到 zap 日志。
  • 日志输出: 日志被格式化为 JSON 格式,并输出到标准输出(stdout),但你也可以将其配置为输出到文件或其他位置。
5. 运行项目

运行项目后,访问 http://localhost:8080/ping,你将在控制台看到 zap 格式化的日志输出,如:

{"level":"info","time":"2024-09-19T12:34:56.789+0800","caller":"main.go:23","msg":"Incoming request","method":"GET","path":"/ping","status":200,"latency":0.001234,"client_ip":"127.0.0.1"}

通过这种方式,你可以将 zap 日志记录集成到 gin 项目中,并通过中间件捕获和记录 HTTP 请求的相关信息。

要在 gin 项目中使用 sirupsen/logrus 并封装成一个可复用的函数,可以按照以下步骤进行:

logrus在GIN中的实践

1. 安装 logrus

首先,确保在你的项目中安装了 logrus

go get -u github.com/sirupsen/logrus
2. 封装 logrus 日志

创建一个封装 logrus 日志初始化和使用的函数。以下是一个示例代码,包括了如何将 logrus 日志集成到 gin 中:

logger.go - 封装 logrus 日志
package logger

import (
	"os"

	"github.com/sirupsen/logrus"
)

// InitLogrusLogger initializes a logrus logger
func InitLogrusLogger() *logrus.Logger {
	// Create a new instance of the logger
	logger := logrus.New()

	// Set the output to stdout
	logger.Out = os.Stdout

	// Set the log level (e.g., Info, Warn, Error)
	logger.SetLevel(logrus.InfoLevel)

	// Set the log format to JSON (or Text)
	logger.SetFormatter(&logrus.JSONFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
	})
	
	// Alternatively, use TextFormatter for more readable output
	// logger.SetFormatter(&logrus.TextFormatter{
	//     FullTimestamp: true,
	// })

	return logger
}
3. logrus 集成到 gin

gin 项目中,使用中间件将 logrus 集成到 HTTP 请求处理流程中。

main.go - 集成 logrus 日志到 gin
package main

import (
	"time"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"your_project/logger" // Replace with the correct path to logger.go
)

func main() {
	// Initialize logrus logger
	log := logger.InitLogrusLogger()

	// Create a new Gin router
	r := gin.New()

	// Custom middleware to log requests with logrus
	r.Use(func(c *gin.Context) {
		startTime := time.Now()

		// Process request
		c.Next()

		// Log request details
		log.WithFields(logrus.Fields{
			"method":     c.Request.Method,
			"path":       c.Request.URL.Path,
			"status":     c.Writer.Status(),
			"latency":    time.Since(startTime),
			"client_ip":  c.ClientIP(),
		}).Info("Incoming request")
	})

	// Define routes
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})

	// Start the server
	r.Run(":8080")
}
4. 说明
  • InitLogrusLogger: 这个函数初始化了一个 logrus 日志实例。你可以根据需要设置日志级别和输出格式(如 JSON 或文本)。
  • Gin 中间件: 在 gin 中注册一个中间件,记录 HTTP 请求的基本信息(如方法、路径、状态码、耗时等)到 logrus 日志。
  • 日志输出: 日志被格式化为 JSON 格式,并输出到标准输出(stdout)。你也可以选择 TextFormatter 来生成更易读的输出。
5. 运行项目

运行项目后,访问 http://localhost:8080/ping,你将在控制台看到 logrus 格式化的日志输出,例如:

{"client_ip":"127.0.0.1","latency":0.001234,"method":"GET","path":"/ping","status":200,"time":"2024-09-19T12:34:56+08:00","msg":"Incoming request","level":"info"}

或者使用 TextFormatter 时:

time="2024-09-19 12:34:56" level=info msg="Incoming request" client_ip=127.0.0.1 latency=0.001234 method=GET path=/ping status=200

通过这种方式,你可以将 logrus 日志记录集成到 gin 项目中,并通过中间件捕获和记录 HTTP 请求的相关信息。

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

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

相关文章

Fyne ( go跨平台GUI )中文文档- 架构 (八)完结

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章: Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…

Java集合HashSet——HashSet在底层原理

可点击此处:HashSet在底层原理 创建一个默认长度16,默认加载因子为0.75的数组,数组名table 16*0.75 12,如果存入的数据达到12,则数组自动扩容为原来的2倍 根据元素的哈希值跟数组的长度计算出应存入的位置 int index…

JAVA基础:正则表达式,String的intern方法,StringBuilder可变字符串特点与应用,+连接字符串特点

1 String中的常用方法2 1.1 split方法 将字符串按照指定的内容进行分割,将分割成的每一个子部分组成一个数组 分割内容不会出现在数组中 实际上该方法不是按照指定的简单的符号进行分割的,而是按照正则表达式进行分割 1.2 正则表达式 用简单的符号组合…

思维商业篇(4)—产业上下游定

思维商业篇(4)—产业上下游定位(微笑曲线) 产业上下游定位,帮助我们去观察一个企业在产业上下游中处于一个什么样的生态位。 上游 处于产业链开始端,百川东到海,百川的的起始端就是上游,东到海的海就是下游。 处在上游的企业一…

用友网络交付总监刘伟伟受邀为第四届中国项目经理大会演讲嘉宾

全国项目经理专业人士年度盛会 用友网络科技股份有限公司区域交付总监刘伟伟先生受邀为PMO评论主办的全国项目经理专业人士年度盛会——2024第四届中国项目经理大会演讲嘉宾,演讲议题为“如何有效提升项目经理领导力”。大会将于10月26-27日在北京举办,主…

UE学习篇ContentExample解读-----------Blueprint_Overview

文章目录 总览描述批次阅览1.1 Blueprint- Hello World1.2 Blueprint- Components1.3 Blueprint- Variables1.4 Blueprint- ConstructionScript1.5 Blueprint- Event Graph1.6 Blueprint- Simple Math1.7 Blueprint- Flow Control 概念总结致谢: 总览描述 打开关卡后…

机械设计中倒角与倒圆角

我们常说,机械设计要做到“一切尽在掌握中”。 包含两层意思:一是所有的结构细节都是仔细思考过并且完整表达,不能靠在制造过程中猜测设计意图、由制造人员再设计或自由发挥。 二是所有的设计都是有根据的,不能靠拍脑袋任意发挥…

【路径规划】自动泊车的 Simulink 模型

摘要 本文介绍了一个用于自主机器人路径规划和导航的 Simulink 模型,该模型结合了路径跟踪算法(如 Pure Pursuit)和动态机器人模型,实现了复杂环境中的路径跟随和导航控制。实验结果表明,模型能够在给定路径上精确控制…

【neo4j】neo4j和Cypher 查询语言相关知识点

【neo4j】neo4j和Cypher 查询语言相关知识点 1.什么是neo4j Neo4j 是一个广泛使用的图形数据库管理系统(Graph Database Management System)。它是一种NoSQL数据库,专为存储和查询图形数据而设计。Neo4j 支持图形数据模型,允许用…

误差评估,均方误差、均方根误差、标准差、方差

均方根误差 RMSE/RMS 定义 RMSE是观察值与真实值偏差的平方,对于一组观测值 y i y_i yi​ 和对应的真值 t i t_i ti​ R M S E 1 n ∑ i 1 n ( y i − t i ) ,其中n是观测次数 RMSE\sqrt{\frac1n \sum_{i1}^n (y_i-t_i)} \text{,其中n是…

Python|OpenCV-实现识别目标图像中的圆圈(20)

前言 本文是该专栏的第22篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 在处理图像检测项目的时候,可能会遇到需要检测目标图像中的“圆圈”需求。笔者在这里举个例子,如下图所示: 在图中有一个篮球,但是我们要找的目标对象并不是篮球,而是篮球它本身的这个…

智能BI平台项目

1.项目介绍 BI商业智能:数据可视化、报表可视化系统 4)发布订阅 Resource 是基于名称进行查找的,而Spring框架中更常用的 Autowired 则是基于类型进行查找的。如果找不到匹配的bean,Autowired 会抛出异常,而 Resource…

java项目之基于spring boot的多维分类的知识管理系统的设计与实现源码

项目简介 基于spring boot的多维分类的知识管理系统的设计与实现实现了以下功能: 基于spring boot的多维分类的知识管理系统的设计与实现的主要使用者管理员可以管理用户信息,知识分类,知识信息等,用户可以查看和下载管理员发布…

如何创建标准操作规程(SOP)[+模板]

创建、分发和管理流程文档和逐步说明的能力是确定企业成功的关键因素。许多组织依赖标准操作规程(SOP)作为基本形式的文档,指导他们的工作流程操作。 然而,SOP不仅仅是操作路线图;它们就像高性能车辆中的先进GPS系统一…

01_RabbitMQ安装及工作模式

一、消息队列MQ 中间件 1.1 什么是消息队列 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。 消息队列(Message Queue)是一…

5.工欲善其事,必先利其器!收集金融数据你必须先做这个!

在正式从网络上获取数据并存储到我们的数据库之前,我们还需要做一些准备工作。其中最重要的无疑是把Python环境配置好。 你可以不好好学习Python,毕竟我后边会一步步教大家,也会提供现成的Python脚本。但是你必须得在你的电脑上把Python安装…

YOLOv10改进,YOLOv10替换主干网络为PP-HGNetV2(百度飞桨视觉团队自研,独家手把手教程,助力涨点)

摘要 PP-HGNetV2(High Performance GPU Network V2) 是百度飞桨视觉团队自研的 PP-HGNet 的下一代版本,其在 PP-HGNet 的基础上,做了进一步优化和改进,最终在 NVIDIA GPU 设备上,将 “Accuracy-Latency Balance” 做到了极致,精度大幅超过了其他同样推理速度的模型。其在…

如何用ChatGPT制作一款手机游戏应用

有没有想过自己做一款手机游戏,并生成apk手机应用呢?有了人工智能,这一切就成为可能。今天,我们就使用ChatGPT来创建一个简单的井字棋游戏(Tic-Tac-Toe),其实这个过程非常轻松且高效。 通过Cha…

828 华为云征文|华为 Flexus 云服务器搭建萤火商城 2.0

在今天这个意义非凡的日子,我怀揣着满心的期待与憧憬,毅然踏上了利用华为 Flexus 云服务器搭建轻量级、高性能、前后端分离的电商系统萤火商城 2.0 的征程。这一旅程,注定充满了挑战与惊喜,犹如在浩瀚的数字海洋中探索未知的宝藏。…

java-----方法

目录 什么是方法? 方法的作用? 方法的格式: 方法的重载: 方法的内存原理 方法的值传递: 什么是方法? :程序中最小的执行单元(要么全执行,要么全不执行) public class methoddeom3 {public static void main(String[] args) {System.out.println("hello…