战术卧倒

golang中常见的日志包是logrus, 根据logrus的胚子和我们的生产要求,给出一个生产可用的logrus实践姿势。

主谓宾定状补

logrus是一个结构化的、可插拔的、兼容golang标准log api的日志库。

快速过一下能力

  • 支持对output=TTY增加关键字颜色
  • 内置JSONFormatter和TextFormatter(默认)两种Formatter
  • 支持输出logger所在的函数行位置 log.SetReportCaller(true)
  • 可以兼容golang内置的标准log库, 建议无脑替换
  • 鼓励输出可解析的日志字段,而不是大段的无法结构化的文本日志
log.WithFields(log.Fields{
"event": event,
"topic": topic,
"key": key,
}).Fatal("Failed to send event")

基于现状,凑了6个钱包上生产,下面给出一些自己的生产实践。

添砖加瓦

1. logrus不支持滚动日志

好马配好鞍 https://github.com/lestrrat-go/file-rotatelogs 让你下雨天不再哭泣。

它会根据配置自动按照时间切分日志,并滚动清理日志(不用配磁盘报警,不用担心磁盘满故障)。

	logf, err := rotatelogs.New(
cfg.Log.LogDir+logName+".%Y%m%d%H%M",
rotatelogs.WithLinkName(cfg.Log.LogDir+logName),
rotatelogs.WithMaxAge(24*time.Hour),
rotatelogs.WithRotationTime(time.Hour),
)
if err != nil {
stdLog.Printf("failed to create rotatelogs: %s", err)
return
}

2. 日志格式化

java生态默认日志输出格式:

11:44:44.827 WARN [93ef3E0120160803114444] [main] [ClassPathXmlApplicationContext] Exception encountered during context initialization - cancelling refresh attempt

在公司中javaer占据主流,故java的默认格式就成了公司集中式日志的"标准"格式。

很明显,logrus默认的两种Formatter都不匹配。

github.com/antonfisher/nested-logrus-formatter 让你柳暗花明。

log.SetFormatter(&nested.Formatter{ // 嵌套日志兼容skynet日志格式
HideKeys: true,
FieldsOrder: []string{"region", "node", "topic"},
TimestampFormat: "2006-01-02 15:04:05.000", // 显示ms
})

3. 自定义Hook用法:输出默认字段

写本文的时候,发现logrus官方本身支持输出默认日志字段。

requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
requestLogger.Warn("something not great happened")

Hook: 通常 钩子函数用于在触发某种事件时附带一些动作。

logrus的Hook定义:logEntry满足指定的logLevel日志时, 你想要做的动作(你甚至可以不设置output直接在hook输出日志, 这就是内置write hook的实现)。

type Hook interface {
Levels() []Level
Fire(*Entry) error
}

示例代码为logLevel>=info的logEntry,固定了2个日志字段。

type FixedFieldHook struct {
LogLevels []logrus.Level
FixedField map[string]string
} // Fire will be called when some logging function is called with current hook
// It will format log entry to string and write it to appropriate writer
func (hook *FixedFieldHook) Fire(entry *logrus.Entry) error {
for k, v := range hook.FixedField {
entry.Data[k] = v
}
return nil
} log.AddHook(&FixedFieldHook{ // Set fixed field
FixedField: map[string]string{"region": cfg.LocalRegion, "node": ip},
LogLevels: []logrus.Level{
logrus.InfoLevel,
logrus.ErrorLevel,
logrus.WarnLevel,
logrus.FatalLevel,
},
})

抛砖引玉,战术卧倒。

Go编程快闪之 logrus日志库的更多相关文章

  1. Go第三方日志库logrus

    日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...

  2. 第三方日志库logrus使用

    日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...

  3. Go之第三方日志库logrus使用

    文章引用自 第三方日志库logrus使用 日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库 ...

  4. 日志服务Python消费组实战(三):实时跨域监测多日志库数据

    解决问题 使用日志服务进行数据处理与传递的过程中,你是否遇到如下监测场景不能很好的解决: 特定数据上传到日志服务中需要检查数据内的异常情况,而没有现成监控工具? 需要检索数据里面的关键字,但数据没有建 ...

  5. Go语言项目中使用zap日志库(翻译)

    本文先介绍了Go语言原生的日志库的使用,然后详细介绍了非常流行的Uber开源的zap日志库,同时介绍了如何搭配Lumberjack实现日志的切割和归档. 在Go语言项目中使用Uber-go的Zap L ...

  6. golang-Zap和Go Logger日志库

    目录 在Go语言项目中使用Zap日志库 介绍 默认的Go Logger日志库 实现Go Logger 设置Logger 使用Logger Logger的运行 Go Logger的优势和劣势 优势 劣势 ...

  7. Go之Zap日志库集成Gin

    简介 在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能: 1 . 能够将事件记录到文件中,而不是应用程序控制台; 2 . 日志切割-能够根据文件大小.时间或间隔等来切割日志文件; ...

  8. 在Go语言项目中使用Zap日志库

    在Go语言项目中使用Zap日志库 本文先介绍了Go语言原生的日志库的使用,然后详细介绍了非常流行的Uber开源的zap日志库,同时介绍了如何搭配Lumberjack实现日志的切割和归档. 在Go语言项 ...

  9. Go语言系列之日志库zap

    在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能: 能够将事件记录到文件中,而不是应用程序控制台. 日志切割-能够根据文件大小.时间或间隔等来切割日志文件. 支持不同的日志级别.例 ...

  10. golang常用库包:log日志记录-uber的Go日志库zap使用详解

    Go 日志记录库:uber-go 的日志操作库 zap 使用 一.简介 zap 是 uber 开源的一个高性能,结构化,分级记录的日志记录包. go1.20.2 zap v1.24.0 zap的特性 ...

随机推荐

  1. jsp页面中的正则表达式--主要用于js判断文本格式

    一.方括号[] 举例: 二.^ 三.元字符 举例的话,就可以这么说,要实现要表示整数的话: []就表示输入的文本框里面的数字的第一位,可以这么写--->[1-9] 然后已知\d表示的与[0-9] ...

  2. 【打怪升级】【rocketMq】rocket的持久化

    rocket持久化保证的思想有两点:1是刷盘保证大部分数据不丢失:2是持久化文件的处理,零拷贝技术和内存页,NIO模型保证处理能力 文件持久化目录 ├──abort:rocket broker启动检查 ...

  3. 65.C++的输入流和输出流

    1.流的概念和流类库的结构   程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件.   C++输入输出包含以下三个方面的内容:   对系统指定的标准设备的输入和输 ...

  4. golang中关于死锁的思考与学习

    1.Golang中死锁的触发条件 1.1 书上关于死锁的四个必要条件的讲解 发生死锁时,线程永远不能完成,系统资源被阻碍使用,以致于阻止了其他作业开始执行.在讨论处理死锁问题的各种方法之前,我们首先深 ...

  5. Mybatisplus----DML编程控制

    乐观锁 (1)业务并发现象带来的问题:秒杀 执行: 1.在类对象中添加version属性,在数据库表中添加version字段(默认值为1) package com.itheima.domain; im ...

  6. 机器学习基础04DAY

    scikit-learn数据集 我们将介绍sklearn中的数据集类,模块包括用于加载数据集的实用程序,包括加载和获取流行参考数据集的方法.它还具有一些人工数据生成器. sklearn.dataset ...

  7. 重打包APK绕过签名校验

    这里先提一种针对性校强但简单好理解的办法,纯Java实现,代码大概也就50行不到吧. 还有更强的并且能过各种保护(反调试反HOOK反内存修改等等)的万能方法,不过较复杂,长篇大论的,等有空整理出来再提 ...

  8. 计网学习笔记六 Network Layer Overview

    这节课开始进入了网络层的学习,讲述了网络层提供的功能,还有路由器内部是什么样子的,以及virtual circuit网络和datagram网络的一点比较. 网络层有什么作用呢?用一句话来说,就是需要负 ...

  9. [Spring MVC]@RequestMapping 与 @RequestMapping+@RequestResponse的区别

    假定:返回格式均为JSON,JSON实体对象myJson的属性有:data.message.code.status. 二者的区别在于: @RequestMapping:会在最外层包裹 data属性,将 ...

  10. 23.04.06_为博客设置https

    title: 为博客设置https协议 categories: - 博客优化 date: 2023-04-06 url_dir: Blog_optimization url_name: setting ...