Go编程快闪之 logrus日志库

战术卧倒

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不支持滚动日志

好马配好鞍 http://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,
		},
	})

抛砖引玉,战术卧倒。


本文来自博客园,作者:{有态度的马甲},转载请注明原文链接:http://www.cnblogs.com/JulianHuang/p/17428673.html

欢迎关注我的原创技术、职场公众号, 加好友谈天说地,一起进化
本文转载于网络 如有侵权请联系删除

相关文章

  • 最大子序列的和_子序列和最大值

    大家好,又见面了,我是你们的朋友全栈君。53.最大子序和https://leetcode-cn.com/problems/maximum-subarray/description/packagecom.test; importjava.util.ArrayList; importjava.util.List; /** *@Authorstono *@Date2018/8/21上午10:56 */ publicclassLesson053{ publicstaticvoidmain(String[]args){ //int[]nums={-2,1,-3,4,-1,2,1,-5,4}; int[]nums={-2,-1}; intmax=maxSubArray(nums); System.out.println(max); } publicstaticintmaxSubArray(int[]nums){ //存放最大序列和 intmax=0; intsum=0; for(inti=0;i<nums.length;i++){ intnum=nums[i]; //如果num出现负值,

  • 聊聊队列(FIFO)的应用

    JZGKCHINA工控技术分享平台尊重原创勿抄袭勿私放其他平台 现场的模拟量信号跳动有点大,我想做个平均滤波程序处理一下,如何实现? 用户需要在PLC内记录一些历史数据,方便在触摸屏或SCADA上展示最近一定次数的操作数据,如何做比较简单? 。。。。。。 本文将从FIFO队列聊起,给出笔者在处理上述问题时的方法。其中涉及的算法未必是最简洁的,欢迎大家在评论里互动讨论。本文约1900字,预计阅读时间10分钟。 1.什么是FIFO队列 FIFO(FirstInputFirstOutput)队列,即先入先出队列。这种数据处理方式就类似于我们去检测点排队做核酸检测:队伍里第一个到达护士小姐姐那里的居民会是第一个从集中检测点走出来的人,小姐姐每检测完一位,整个队伍里所有的居民就向前挪动一个位置。(一般解释这个都用的是超市排队结账模型) 如果我们规定这个队列最多有N个人,并且有很多的居民正在广场上等着进入这个检测队列,每检测完一人则队伍出去一人并进来一人,则FIFO队列有以下特点: (1)队列中始终保持着N个数据元素; (2)队列中的数据元素包含最新的数据以及N-1个较老的数据; 利用以上两个特

  • centos7.0 没有netstat 和 ifconfig命令问题

    yuminstallwget复制运行  yuminstallnet-tools  就OK了默认CentOS已经安装了OpenSSH,即使你是最小化安装也是如此。所以这里就不介绍OpenSSH的安装了。 SSH配置:1、修改vi /etc/ssh/sshd_config,根据模板将要修改的参数注释去掉并修改参数值:Port22指定SSH连接的端口号,安全方面不建议使用默认22端口Protocol2,1允许SSH1和SSH2连接,建议设置成Protocal2其他参数根据自己的需要进行调整。配置方法详见: manssh_config2、修改hosts.deny在最后面添加一行:sshd:All复制3、修改hosts.allow在最后面添加一行:sshd:All复制如果为了安装可以限制访问的IP,设置如下:sshd:192.168.0.101 sshd:192.168.0.102复制上述配置表示只允许101和102的服务器进行SSH连接4、启动SSHsystemctlrestartsshd.service复制至此SSH已经可以连接了

  • VMware虚拟机三种联网方法及原理

    一、Brigde——桥接:默认使用VMnet0  1、原理:  Bridge 桥"就是一个主机,这个机器拥有两块网卡,分别处于两个局域网中,同时在"桥"上,运行着程序,让局域网A中的所有数据包原封不动的流入B,反之亦然。这样,局域网A和B就无缝的在链路层连接起来了,在桥接时,VMWare网卡和物理网卡应该处于同一IP网段 当然要保证两个局域网没有冲突的IP.  VMWare的桥也是同样的道理,只不过,本来作为硬件的一块网卡,现在由VMWare软件虚拟了!当采用桥接时,VMWare会虚拟一块网卡和真正的物理网卡就行桥接,这样,发到物理网卡的所有数据包就到了VMWare虚拟机,而由VMWare发出的数据包也会通过桥从物理网卡的那端发出。  所以,如果物理网卡可以上网,那么桥接的软网卡也没有问题了,这就是桥接上网的原理了。       2、联网方式:  这一种联网方式最简单,在局域网内,你的主机是怎么联网的,你在虚拟机里就怎么连网。把虚拟机看成局域网内的另一台电脑就行了!  提示:主机网卡处在一个可以访问Internet的局域网中,虚拟机才能通过Br

  • kubernetes-2:helm实战-1:生产级别的elasticsearch集群部署

    (1).镜像准备添加需要的Helm仓库: helmrepoaddelastichttps://helm.elastic.co(2).pv准备 因为elasticsearch的data节点很明显是需要持久化保存数据的,很显然是stateful容器类型,但实际上我们会把master,ingest的也做成stateful,因为当master,ingest宕机重启后,我们需要看到连贯日志。 需要准备9个pv声明。 以data0举例: 如下图,注意一定要在NFS上建立对应的path目录,我这里是es-c1-skywalking-data0,否则建立PV不会报错,但是后边初始化容器时会有问题,无法创建POD。 相关配置参见:https://github.com/hepyu/k8s-app-config/tree/master/elasticsearch下的3个pv.yaml:顺次执行创建pv:kubectlapply-f./pv-es-c1-skywalking-master.yaml kubectlapply-f./pv-es-c1-skywalking-ingest.yamlkubectlap

  • 2030年前“钢铁侠”马斯克的宏伟计划:拥有诸多梦想

    北京时间12月7日消息,埃隆·马斯克(ElonMusk)提出了许多宏伟计划,我们可能很难跟踪每一个项目的实现时间。目前,Futurism网站列举了2030年前马斯克所有经营公司将实现的项目清单。埃隆·马斯克:拥有诸多梦想的男人将亿万富翁埃隆·马斯克描述为一位忙碌的企业家,是一种轻描淡写的做法。马斯克虽然年轻,却经营着许多公司,每一家公司都有坚定的未来发展规划。为了使电动汽车(EAVs)和可再生能源解决方案向前推进,他创建了特斯拉公司;为了让人类有机会成为一支多星球物种,他创建了SpaceX公司;为了改变运输以及建造最好的隧道,他创建了“BoringCompany”;为了促进人工智能快速发展,他联合启动了非盈利人工智能项目OpenAI。最后,他为了增强人类大脑能力,创建了“神经墨水(Neuralink)”公司。我们很容易对马斯克大杂烩公司的多样性项目“迷失方向”,因此列举一份项目清单,以下是2030年前马斯克计划实现的目标:2017年:马斯克为自己设定的宏伟目标都在不久的将来实现,最近的时间表是100天内在澳大利亚建造世界上最大的锂离子电池工厂。今年3月份,马斯克宣称他将不久计划100天

  • CSS布局模型

    在网页中,元素有三种布局模型:1、流动模型(Flow)默认的2、浮动模型(Float)3、层模型(Layer)   1、流动模型(Flow)  流动(Flow)模型是默认的网页布局模式。也就是说网页在默认状态下的HTML网页元素都是根据流动模型来分布网页内容的。 流动布局模型具有2个比较典型的特征: 第一点,块状元素都会在所处的包含元素内自上而下按顺序垂直延伸分布,因为在默认状态下,块状元素的宽度都为100%。实际上,块状元素都会以行的形式占据位置。 (每一个便签都显示着自己本来默认的那个宽高) 第二点,在流动模型下,行内元素都会在所处的包含元素内从左到右水平分布显示。(内联元素可不像块状元素这么霸道独占一行)   2、浮动模型(Float) 任何元素在默认情况下是不能浮动的,但可以用 CSS定义为浮动 div{float:left;}  div{float:right;} 可以为不同的div设置不同的浮动方式来布局。   3、层模型(Layer) 层模型有三种形式: 1、相对定位(position:relative)  2、

  • 20150517 Linux文件系统与设备文件系统

    tdp{margin-bottom:0.25cm;direction:ltr;line-height:120%;text-align:left;widows:2;orphans:2} p{margin-bottom:0.25cm;direction:ltr;line-height:120%;text-align:left;widows:2;orphans:2} a:link{} 20150517Linux文件系统与设备文件系统 2015-05-17Lover雪儿 注:本文参考书籍:华清远见-《Linux设备驱动开发详解》第五章,大概内容如下,具体内容还请观看原书. 一.devfs(设备文件系统) devfs(设备文件系统)是由linux2.4内核引入的,具有如下优点: ①可以通过程序在设备初始化时在/dev目录下创建设备文件,卸载时把它删除。 ②设备驱动程序可以指定设备名、所有者和权限位,用户空间中人可以修改。 ③不需要为设备驱动程序分配主设备号以及处理次设备号,在程序中直接可以给register_chrdev()传递0主设备号可以动态获取可用的主设备号,并在devfs_registe

  • javascript中js实现导出CSV文件功能

    js直接在页面中将数组导出到CSV文件之中//数组导出CSV文件 functionexportCSV(jsonData,fileName){ if(!jsonData||jsonData.length==0){ return; } if(!fileName){ fileName="exportCSV.csv"; } letone=jsonData[0]; letcsvText=""; for(letkeyinone){ csvText+=key+"," } csvText=trim(csvText,",")+"\n"; //增加\t为了不让表格显示科学计数法或者其他格式 for(leti=0;i<jsonData.length;i++){ letrow=""; for(letiteminjsonData[i]){ row+=`${jsonData[i][item]+'\t'},`; } csvText+=trim(row,",&qu

  • 快看那个运维妹子在学算法【二分查找】

      数组的查找,分为两种方法,线性查找和二分查找。 一、线性查找 线性查找是一种在数据中查找数据的算法,即便数据没有按顺序存储,也可以使用线性查找。线性查找在数据中从头开始依次往下查找。     Python代码实现: nums=[-1,0,3,5,9,12] target=-2 foriinrange(len(nums)): ifnums[i]==target: result=i else: result=-1 print(result)复制   二、二分查找 二分查找也是一种在数组中查找数据的算法,只能查找已经排好序的数据。二分查找通过比较数组中间的数据与目标数据的大小,可以得知目标数据是在数组的左边还是右边。   图解: 1)查找已经排好序的数组中的目标数字6   2)首先找到中间数字5   3)将5和需要查找的数字作比较5<6   4)因此可得知我们需要查找的数据在5的右边   5)在剩下的数字中查找中间数字为7   6)比较6和7   7)移除不

  • 用光盘充当yum源,配置客户端

    1、VM中,openterminal打开终端,先看看光盘的挂载,同时开启服务systemctlstartautofs;ls/misc/cd可以看见一个repodata的文件,只有含有repodata的路径才可以做yum源路径      2、cd/etc/yum.repo.d/在这个文件夹里存放着配置好的yum源,可以进去看看他们的写法。为了方便,新建文件夹back,将所有的*.repo移动到back里。我们自己重新建一个yum源,起名base.repo          3、vimbase.repo        这里的yum源路径用的是本地路径file:///misc/cd,最基本的格式就配置完成了。然后yumrepolist列出仓库列表 4、再把epl源配了,本地没有,可以用aliyun的,https://mirrors.aliyun.com/epel/7/x86_64/ 配置epl源的文件单独写,还是放在刚才的base.repo都可以,为了方便,继续在bas

  • Linux CentOS完全卸载PHP

    很无语,CentOS居然php版本才5.1.6,很多开源的CMS无法安装。 查看php版本命令: #php-v 下面的命令是删除不干净的 #yumremovephp 因为使用这个命令以后再用 #php-v 还是会看到有版本信息的。。。。。   必须强制删除,使用下面命令查看全部php软件包 #rpm -qa|grep php 提示如下: #php-pdo-5.1.6-27.el5_5.3#php-mysql-5.1.6-27.el5_5.3#php-xml-5.1.6-27.el5_5.3#php-cli-5.1.6-27.el5_5.3#php-common-5.1.6-27.el5_5.3#php-gd-5.1.6-27.el5_5.3 注意卸载要先卸载没有依赖的 pdo是mysql的依赖项;common是gd的依赖项;例如:#rpm-ephp-pdo-5.1.6-27.el5_5.3error:Faileddependencies:       php-pdoi

  • 批处理文件的@echo off是什么意思?

    @echooff 关闭回显 @echoon 打开回显 @echooff并不是DOS程序中的, 而是DOS批处理中的。 当年的DOS,所有操作都用键盘命令来完成, 当你每次都要输入相同的命令时, 可以把这么多命令存为一个批处理, 从此以后,只要运行这个批处理, 就相当于打了几行、几十行命令。 DOS在运行批处理时, 会依次执行批处理中的每条命令, 并且会在显示器上显示, 如果你不想让它们显示, 可以加一个“echooff” 当然,“echooff”也是命令, 它本身也会显示, 如果连这条也不显示, 就在前面加个“@”。 pause 使显示器停下,并显示“请按任意键继续___” 例如: @echooff @echohello! pause 显示如下图hello1 复制     转载https://blog.csdn.net/zl1zl2zl3/article/details/79218448

  • u-boot分析(四)---设置异常向量表|设置SVC模式

    u-boot分析(四) 通过前三篇的分析,我们对u-boot已经有了整体的认识和掌握,但是我们仍然对于其部分硬件是如何初始化的不太清楚,所以接下来几篇博文我将会对我们在http://www.cnblogs.com/wrjvszq/archive/2015/01/10/4215627.html一文中总结出的u-boot的工作流程中的重要环节,结合文档加以分析。 今天我们会用到的文档: 1.       ARMArchitectureReferenceManual:http://download.csdn.net/detail/wrjvszq/8354473   今天我们将会分析以下内容: 1.      设置中断向量表 2.     设置CPU为SVC模式   l 设置异常向量表 我们知道arm上电后u-boot干的第一件事就是设置异常向量表,那么什么是异常?异常又有什么类型呢?等

  • MBR40200PT-ASEMI插件肖特基二极管MBR40200PT

    编辑-Z MBR40200PT在TO-247封装里采用的2个芯片,其尺寸都是130MIL,是一款插件肖特基二极管。MBR40200PT的浪涌电流Ifsm为350A,漏电流(Ir)为0.05mA,其工作时耐温度范围为-65~175摄氏度。MBR40200PT采用金属硅芯片材质,里面有2颗芯片组成。MBR40200PT的电性参数是:正向电流(Io)为40A,反向耐压为200V,正向电压(VF)为0.9V,其中有3条引线。   MBR40200PT参数描述 型号:MBR40200PT 封装:TO-247 特性:插件肖特基二极管 电性参数:40A200V 芯片材质:金属硅芯片 正向电流(Io):40A 芯片个数:2 正向电压(VF):0.9V 芯片尺寸:130MIL 浪涌电流Ifsm:350A 漏电流(Ir):0.05mA 工作温度:-65~+175℃ 引线数量:3     MBR40200PT插件封装系列。它的本体长度为21.3mm,加引脚长度为41.55mm,宽度为16.25mm,高度为5.05mm,脚间距为5.7mm。   以上就是关于MBR402

  • 耳机左右声道_立体声切换

    1.修改文件: mediatek/custom/工程/hal/audioflinger/audio/audio_custom_exp.h   2.修改内容: #define ENABLE_STERIO_SPEAK #undef ENABLE_AUDIO_SW_STERIO_TO_MONO

  • TJOI2014 Alice and Bob

    题目传送门 神仙题 Alice和Bob怎么整天在一起玩一些神仙游戏 原序列为\(x\),输入的序列为\(a\)。 因为题目中是上升子序列和下降子序列,所以原序列中相同的元素没有贡献,因此不妨设\(x\)为\(1\)~\(n\)的一个排列 \(a_i\)是以\(x_i\)为结尾的最长上升子序列的长度,所以对于所有的\(a_k=a_i-1\),一定存在至少一个\(k\)使\(x_k<x_i\) 如果要使Bob得分尽量高,可以贪心的使\(a_i\)较大的\(x_i\)尽量小,\(a_i\)相同的使\(i\)较大的\(x_i\)(即相对靠后的元素)尽量小 考虑如何构造出符合上述条件的\(x\) 对于\(i\),我们可以向离它最近的满足\(a_k=a_i-1\)的\(k\)连一条边,这样可以构造出一棵树(以\(0\)为根) 我们直接对这棵树求出它的dfs序数组\(dfn\),则\(dfn\)就是一个满足上述条件的序列 因为前向星有一个特殊的性质:晚连上的边会被先遍历到。同时因为dfs先序遍历的特性(节点的dfs序小于它的子树中任意点的dfs序),求出来的\(dfn\)一定是满足上述所有条

  • git和github的用法汇总

    1、git的安装:(我是windows) 查看git版本号(未安装则不会出现版本号,去官网下载对应版本的git即可) git--version 在桌面空白处右键,会出现gitguihere和gitbashhere   2、github上头像不显示的问题及解决: 修改hosts文件:C:\Windows\System32\drivers\etc\hosts (20210119有效/包括MAC系统,20210123更新) #GitHubStart 140.82.113.3github.com 140.82.114.20gist.github.com 151.101.184.133assets-cdn.github.com 151.101.184.133raw.githubusercontent.com 199.232.28.133raw.githubusercontent.com 151.101.184.133gist.githubusercontent.com 151.101.184.133cloud.githubusercontent.com 151.101.184.133

  • IAR使用notice

    1、IAR中无法程序跳转问题   在工程的C编译器选项里的预编译添加$TOOLKIT_DIR$\inc解决,需要clean一下工程再make即可。($TOOLKIT_DIR$:这个语法表示包含文件的路径在IAR安装路径的8051文件夹下,也就是说IAR安装在C盘中,它就表示包含文件指向C:\ProgramFiles(x86)\IARSystems\EmbeddedWorkbench8.0\8051\inc)   2、IAR不支持位定义怎么实现位访问    IARfor51中位定义如下,与keil对比如下,e.g.PSW_bit.P=1;IAR位访问格式。  在IAR位定义 在keil中位定义   3、IAR与keil中断函数区别   中断函数是如下形式   在keil中:   voidTimer0_isr(void)interrupt1  {         //code  }  而在IAR中:   #pragmavector=timer0  __interruptvoid

  • chrome 去除https自动跳转

    原因解决思路具体步骤最近使用nginx配置本地代理,进行本地测试的时候,发现http网站总会跳转到https,很是苦恼,网上找了很多办法发下下面这种办法还是有效的。 原因chrome升级最新版后,为了安全考虑,如果站点支持https,会强制跳转到https。并且chrome会记录dns,下次访问会直接重定向到https站点。 解决思路知道原因之后,下面就是解决办法,删除chrome的dns记录就行了。 具体步骤chrome://net-internals/页面右端红条上有个黑色的下三角 如图clearcacheflushsockets清除两项即可

  • 高斯模糊的Java实现

    1、http://jhlabs.com/ip/index.html publicstaticbyte[]blur(byte[]data)throwsIOException{ ByteArrayInputStreambais=newByteArrayInputStream(data); BufferedImageimg=ImageIO.read(bais); GaussianFiltergaussianFilter=newGaussianFilter(); gaussianFilter.filter(img,img); ByteArrayOutputStreambaos=newByteArrayOutputStream(); ImageIO.write(img,"jpg",baos); returnbaos.toByteArray(); } 复制 Maven地址:http://mvnrepository.com/artifact/com.jhlabs/filters 除了高斯模糊,这人还写了好多图片处理的filter,参见:http://jhlabs.com/ip/filt

相关推荐

推荐阅读