Gin框架原生方式切割日志,Go语言原生日志切割

这篇具有很好参考价值的文章主要介绍了Gin框架原生方式切割日志,Go语言原生日志切割。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

摘要

痛点

正文

1.分析 io.Writer 接口

2.实现 io.Writer 接口

3.将它作为原生输出

4.将它作为 Gin 框架的输出


摘要

自定义一个日志输出,将go语言和gin框架的日志自动按天拆分。本文通过实现io.Writer接口的方式,替换原生和gin框架的默认Writer,并植入了自定义的逻辑。该示例只讲述了如何按天切分日志,如果需要更多定制的内容,可以很方便的改写demo代码。

痛点

网络上没有原生日志切割相关的内容,动不动就讲引入第三方库。例如logrus,但我不想为了一个很简单的需求,即“按天记录日志”,去引入一整个库。这个需求的原因是,在linux下运行的nohup.out文件总是积累的很快,删了看不到日志,不删又怕哪天堵满磁盘。

正文

注意:本文内容的顺序与思考顺序不同,是按知识点排序的。

1.分析 io.Writer 接口

以下代码来自 go1.19,在 io包 [ io.go:90 ]左右的内容

// Writer is the interface that wraps the basic Write method.
//
// Write writes len(p) bytes from p to the underlying data stream.
// It returns the number of bytes written from p (0 <= n <= len(p))
// and any error encountered that caused the write to stop early.
// Write must return a non-nil error if it returns n < len(p).
// Write must not modify the slice data, even temporarily.
//
// Implementations must not retain p.
type Writer interface {
	Write(p []byte) (n int, err error)
}

可以见到,Writer 这个接口非常的简单,只包含了一个 Write 函数,接受一个二进制切片,返回一个数字和一个异常。注释似乎是说:返回的数字是写成功的长度,如果和输入的切片长度不等,应当返回一个异常。

2.实现 io.Writer 接口

import (
	"io"
	"os"
	"time"
)

// 自定义writer的对象
var myWriter dateFileWriter

// 当前要写入日志的文件
var targetFile *os.File

// 自定义一个writer专门用于写日志
type dateFileWriter struct {
	io.Writer
}

// 为自定义writer实现Write接口
func (b *dateFileWriter) Write(p []byte) (n int, err error) {
	return targetFile.Write(p)
}

// RefreshLogFileUsage 刷新指向的日志文件
func RefreshLogFileUsage() {

	fileName := time.Now().Format("2006_01_02") + ".log"

	tryFile, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, 0777)
	if err != nil {
		os.WriteFile(fileName, []byte(""), 0777)
		targetFile, _ = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0777)
	} else {
		targetFile = tryFile
	}
}

// MyLogWriter 返回自定义的 writer
func MyLogWriter() io.Writer {
	RefreshLogFileUsage()
	return &myWriter
}

首先我们定义一个文件指针 targetFile,这就是我们自定义 Writer 会写入内容的文件。

然后我们自定义一个 dateFileWriter,实现了 io.Writer 接口,做的事情非常简单,就是把接收的内容直接写入到指向的文件里面去。

我的需求是按日期拆分,所以定义了一个辅助函数 RefreshLogFileUsage(),它会判断当前日期的日志是否存在,如果不存在,他会新建一个以当前日期命名的文件。需要用定时任务在每天凌晨触发这个函数,才能实现完整的功能。如果你没有引入过定时任务,也可以在每次写入之前执行这个函数。

所以这段代码的逻辑是:一个 Writer 接口的实现会接收一些内容,将他们写入指定的文件,可以手动修改这个指定的文件,以实现根据运行时间将日志写到不同文件的需求。

同理你可以自己扩展一些其他内容,例如拆分 error 和 info 的输出文件等。

3.将它作为原生输出

你只需要在项目伊始执行这段代码

log.SetOutput(MyLogWriter())

将原生 log 包的输出指定为自己的实现类就可以了。

注意,fmt不能这样操作

另外,如果你希望log的内容同时输出在控制台和日志文件中,需要这样改写

log.SetOutput(io.MultiWriter(os.Stdout,MyLogWriter()))

这里可以顺便看下 io.MultiWriter() 是干啥的,在 io 包 [ multi.go:120 ] 左右

// MultiWriter creates a writer that duplicates its writes to all the
// provided writers, similar to the Unix tee(1) command.
//
// Each write is written to each listed writer, one at a time.
// If a listed writer returns an error, that overall write operation
// stops and returns the error; it does not continue down the list.
func MultiWriter(writers ...Writer) Writer {
	allWriters := make([]Writer, 0, len(writers))
	for _, w := range writers {
		if mw, ok := w.(*multiWriter); ok {
			allWriters = append(allWriters, mw.writers...)
		} else {
			allWriters = append(allWriters, w)
		}
	}
	return &multiWriter{allWriters}
}

可以看到这个 Writer 就是接收了多个 Writer,他可以把写入行为分发给多个 Writer 同时执行。

注意:原生的 log 包可以随时通过 SetOutput 函数修改日志输出行为,也就是说,如果你只想处理原生日志,无需自定义一个结构体,只需要在需要的时候通过 SetOutput 修改文件指向就行了。

4.将它作为 Gin 框架的输出

参见上面这条 注意 中的内容,显然,Gin框架的输出行为不能随时改变,他的函数是这个

// 设置 gin 默认的日志输出
gin.DefaultWriter = MyLogWriter()

// 创建 gin 实例
Router = gin.Default()

重点:一旦 gin 的实例被创建,就不能通过 gin.DefaultWriter() 这种方式修改他的日志输出了。我简单的看了一下,gin.Default() 函数会创建一个 Engine 对象,日志作为一个中间件被设置在了这个对象里。而 Engine 对象在运行时支持添加中间件,并不支持删除或者修改中间件。

此处的不支持修改其实不严谨,但我确实没找到 Gin 提供的修改这些中间件相关的函数,但其实他们是支持修改的,只不过呢,操作起来可能有些麻烦。你可以通过这种方式找到这些中间件,当然也包括需要动态修改的日志 Writer

你的gin实例.RouterGroup.Handlers

这里是一个 HandlerFunc 接口的数组,感觉这样改起来应该很复杂,所以我不建议通过这种方式实现。

所以咱们就老老实实的,在 gin 的实例被创建前,设置默认输出到我们自定义的 Writer,然后通过动态修改我们自己对象的方式,实现动态输出 gin 的日志。

实现效果:

Gin框架原生方式切割日志,Go语言原生日志切割

 文章来源地址https://www.toymoban.com/news/detail-486762.html

到了这里,关于Gin框架原生方式切割日志,Go语言原生日志切割的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Go语言Web框架Gin常见用法

    Gin是目前Go语言最为常用的Web框架,日常工作中也少不了使用此框架,编写此使用总结文档以备后用。 此文档参考官方文档编写,仅用于自我学习总结和参考。 我一直认为编写文档的意义一方面是给其他人提供了些许帮助,另一方面则是让自己加深了对知识的理解并为自己提

    2024年02月03日
    浏览(40)
  • 基于go语言gin框架的web项目骨架

    节省时间与精力,更高效地打造稳定可靠的Web项目:基于Go语言和Gin框架的完善Web项目骨架。无需从零开始,直接利用这个骨架,快速搭建一个功能齐全、性能优异的Web应用。充分发挥Go语言和Gin框架的优势,轻松处理高并发、大流量的请求。构建可扩展性强、易于维护的代码

    2024年02月08日
    浏览(35)
  • Go语言项目后端使用gin框架接收前端发送的三种格式数据(form-data,json,Params)

    使用gin框架的BindJSON方法,将前端的json格式数据将后端的结构体相绑定,从而获取到前端所发送的数据,并返回给前端 1.将前端发送过来的数据全部返回 2.将前端发送过来的json格式数据选择性返回   使用gin框架的PostForm方法,从而获取到前端form格式的参数 使用gin框架中的

    2024年02月01日
    浏览(36)
  • gin+gorm增删改查目录框架

    从网上找资料,发现,很多都是直接的结构 路由,后端的controller层,还有model层,都是放在了同一个main.go文件中,如果写项目的话,还得自己去拆文件,拆代码,经过查询和自己总结,下面放一个目录框架 总体目录结构 按照业务流程顺序,解释说明 1、加载自定义封装函数文

    2024年01月19日
    浏览(34)
  • Go(四)gin框架

    1.1、下载和安装gin 下载包:go get github.com/gin-gonic/gin 使用go mod管理包: 1)初始化 Go Modules :go mod init your_module_name,这将创建一个 go.mod 文件,记录你的项目的模块信息和当前依赖关系; 2)复制依赖包到vendor目录 :\\\"go mod vendor\\\" 会将项目的所有包复制到vendor目录中。这包括

    2024年01月25日
    浏览(30)
  • Go-Gin框架

    Gin是一个用Go编写的HTTPweb框架。它是一个类似于martini但拥有更好性能的API框架, 优于httprouter,速度提高了近 40 倍。 点击此处访问Gin官方中文文档。 新建文件main.go,内容如下: 运行后访问: http://localhost:8000/ Gin支持加载HTML模板, 然后根据模板参数进行配置并返回相应的数

    2024年02月20日
    浏览(33)
  • GO学习之 微框架(Gin)

    1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Http) 11、GO学习之 微框架(Gin) 12、GO学习

    2024年02月13日
    浏览(32)
  • Go -【gin】框架搭建基本使用

    Gin是一个快速的Golang web框架,它使用了httprouter来处理路由和速度,而不是使用内置的Go路由。以下是Gin框架的搭建和使用: 这将从Gin GitHub仓库中安装最新版本的Gin框架。 在搭建一个Gin应用程序之前,让我们了解一下Gin的基本架构: Router :它是Gin应用程序的核心部分,它接

    2024年02月16日
    浏览(31)
  • 解决GO安装gin框架(go get -u github.com/gin-gonic/gin)超时问题

    🍊gin框架github地址:https://github.com/gin-gonic/gin         按照官方文档安装gin,但是尝试了好几次,包括使用国内网络或者使用梯子,都超时失败了,爆了如下超时错误 🍊 解决方法如下 1、先查看go相关的配置 如上显示GOPROXY配置是https://proxy.golang.org,这个地址已经被墙了,

    2024年02月11日
    浏览(46)
  • Go学习第十八章——Gin日志与第三方工具Logrus

    1.1 快速入门 在使用Gin框架的过程中,日志是一个重要的组成部分,它可以记录框架和应用程序的运行情况,帮助开发者排查问题和监控应用程序的性能。Gin框架提供了方便的方法来设置和使用日志。 默认日志 Gin框架默认使用的是标准库的log包,将日志输出到控制台。可以通

    2024年02月07日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包