你应该打好你的日志,起码避免被甩锅

大家好,我是蓝胖子,相信大家或多或少都有这样的经历,当你负责的功能出现线上问题时,领导第一时间便是找到你询问原因,然而有时问题的根因或许不在你这儿,只是这个功能或许依赖了第三方或者内部其他部门,这个时候快速排查问题根因就是关键,给领导留个快速解决问题的印象,绩效也找不到理由给你打低了。

而日志作为最简单最直接的排查问题手段,就起到了至关重要的作用, 关于如何打日志,我谈谈我的一些感悟。

日志应该由什么组成

首先,我们来思考下日志应该具有哪些维度的信息,日志无非就是要记录,什么时间,什么地点,发生了什么事情。

针对于应用程序来说,就是哪台主机,哪个应用服务,哪种业务,在某个时间点,出现了什么问题

这里要特别注意的是🔊🔊🔊,日志应该包含业务的上下文信息,例如,要记录某个用户做了支付行为,你应该要记录用户的id,订单号,甚至可以更详细点,把订单的价格,购买的商品信息都记录下来,以便后续排查问题时能直接通过日志找到用户的支付记录。

当然,业务的上下文信息需要根据业务情况决定,不同业务需要考虑下需要打印的业务信息。

打印的日志格式,我还是建议json,毕竟json 更容易被分析,特别是如果是当用上ELK这类的日志收集框架后,能很容易对日志提取字段进行分析。比如将日志中的应用服务名称字段提取出来,在ELK中做聚合分析,我们能分析出某段时间内,究竟是哪个应用在疯狂的打日志。

甚至也可以从日志中提取业务场景字段,对其进行聚合分析,得出某段时间内,那种业务在疯狂打印日志,评估其日志打印是否合理,如下图所示,是在kibana上对过去15小时的日志按业务场景对日志量进行的分析。

image.png

我总结下,日志的基本组成如下

{"host"="主机名",log_time="打印日志格式",app="应用服务名称",action="业务场景",msg="描述信息", err="如果有错误打印错误信息",  业务上下文信息....} 

日志的作用

日志除了按上面提到的进行聚合统计分析系统日志量情况外,还可以按业务维度的字段进行聚合分析,比如将业务场景字段设置为登录,利用它统计每天,每小时登录的人数。利用日志做一些业务维度的监控

当然,日志除了去进行分析统计外,更是为了解决问题,对出错进行恢复,让系统留下运行的痕迹而打印的。打印日志前,一定要想清楚,我们需要解决的问题。

举一个场景,蓝胖子之前在服务中做过邮寄服务,由于邮寄需要依靠第三方的接口,并且整个邮寄的逻辑比较复杂,会有许多邮寄过滤条件,并且后续的产品功能持续有对这部分过滤逻辑进行修改,如何在对第三方接口进行容错,如何后续的迭代过程中对 过滤代码进行容错,保证出错后能有办法恢复出错用户的邮寄就成了要思考的问题。

其实要解决这类问题,最简单的办法就是将程序的运行轨迹能用日志表示出来,有了日志,日志被ELK此类日志收集组件收集后,后续就能通过ELK对日志进行搜索下载,进而恢复数据。所以,蓝胖子在开始邮寄之前,把人员名单记录了下来,把后续邮寄过程中出错的人员,无论是第三方接口调用出错,还是程序内部对数据库或者缓存的访问出错,把它们的错误原因和出错时影响到的用户名单都记录了下来,并且将那些由于邮寄过滤条件过滤掉的用户和过滤原因也记录了下来,最后,把邮寄成功的用户记录下来。

可以看到,最终我只要通过日志,就能找出最终邮寄成功的用户,以及邮寄失败的用户,整个邮寄过程就变透明了,如果有邮寄失败的用户,我也可以通过日志进行恢复。

那你可能会想,那我干脆将程序所有接口,每步操作都打上日志,不就好了吗,其实也是不对的🚫🚫🚫。

1,会让代码变得很臃肿😮‍💨。

2, 打印的日志量也是很大,影响磁盘容量以及日志分析组件收集,因为多了很多无效日志。

所以,下面我给出几条打印日志的建议,

打日志最佳实践

☝🏻第一条,在请求第三方接口或者内部部门接口的时候,你应该要对接口参数以及返回结果进行打印。比较重要的场景甚至还需要对错误情况进行告警🚨。这样起码在接口出错时,在第三方部门需要你提供参数时能及时捞出日志。

第二条在程序对数据进行修改时,记录下改动日志,这也是为了让程序留下运行的痕迹,有助于我们知道对数据做了哪些改动,以便后续出错时,能通过日志对数据进行回滚修复。甚至为了让这个原则更加容易落地,我们可以修改数据库的客户端库,通常这类库会提供许多埋点钩子函数,我们可以实现它们让其在进行delete,update,insert操作时,对sql进行记录,记录下对数据的改动。

第三条,程序出现报错时记录日志,这条基本是准则,不过就像前面提到的那样,在记录时除了记录错误信息,还需要记录下错误的上下文,比如是哪个用户,涉及到了哪些业务数据。

第四条,可以利用日志做一些关键业务信息的监控,特别是一些复杂的业务逻辑,通过日志记录来让业务流程透明化。就像蓝胖子之前提到的对接邮件服务那样,让邮寄过程透明化,也有利于对我们程序的出错恢复。

最后,

自荐一波✅:

欢迎朋友们关注我的公众号📢📢:【蓝胖子的编程梦】!

学习容器知识🐳,性能监控🚀,Golang🐋 相关编程知识

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 自动装配的原理!!!

SpringBootApplication SpringBootConfiguration:标识启动类是一个IOC容器的配置类 EnableAutoConfiguration: AutoConfigurationPackage:扫描启动类所在包及子包中所有的组件,生…

Mint_21.3 drawing-area和goocanvas的FB笔记(七)

FreeBASIC gfx 基本 graphics 绘图 8、ScreenControl与屏幕窗口位置设置 FreeBASIC通过自建屏幕窗口摆脱了原来的屏幕模式限制,既然是窗口,在屏幕坐标中就有它的位置。ScreenControl GET_WINDOW_POS x, y 获取窗口左上角的x, y位置;ScreenC…

小程序网页view多行文本超出隐藏或显示省略号

实现效果: 限制两行,超出即显示省略号 实现:话不多说,展示代码 关键代码 .box{ width:100rpx; overflow:hidden; text-overflow: ellipsis;//超出省略号 display:-webkit-box; -webkit-line-clamp: 2;//显…

【数学】【组合数学】1830. 使字符串有序的最少操作次数

作者推荐 视频算法专题 本博文涉及知识点 数学 组合数学 LeetCode1830. 使字符串有序的最少操作次数 给你一个字符串 s &#xff08;下标从 0 开始&#xff09;。你需要对 s 执行以下操作直到它变为一个有序字符串&#xff1a; 找到 最大下标 i &#xff0c;使得 1 < i…

Android UI自动化测试框架—SoloPi简介

1、UI自动化测试简介 软件测试简介 ​软件测试是伴随着软件开发一同诞生的&#xff0c;随着软件规模大型化&#xff0c;结构复杂化&#xff0c;软件测试也从最初的简单“调试”&#xff0c;发展到当今的自动化测试。 ​ 自动化测试是什么呢&#xff1f;自动化测试是把以人为…

用C语言执行SQLite3的gcc编译细节

错误信息&#xff1a; /tmp/cc3joSwp.o: In function main: execSqlite.c:(.text0x100): undefined reference to sqlite3_open execSqlite.c:(.text0x16c): undefined reference to sqlite3_exec execSqlite.c:(.text0x174): undefined reference to sqlite3_close execSqlit…

从零开始:神经网络(1)——神经元和梯度下降

声明&#xff1a;本文章是根据网上资料&#xff0c;加上自己整理和理解而成&#xff0c;仅为记录自己学习的点点滴滴。可能有错误&#xff0c;欢迎大家指正。 一. 神经网络 1. 神经网络的发展 先了解一下神经网络发展的历程。从单层神经网络&#xff08;感知器&#xff09;开…

349. 两个数组的交集

349. 两个数组的交集 力扣题目链接(opens new window) 题意&#xff1a;给定两个数组&#xff0c;编写一个函数来计算它们的交集。 说明&#xff1a; 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。 对于看某个元素是否出现在一个集合中的 &#xff0c;…

STM32利用标准库的方式输出PWM(proteus仿真)

首先打开proteus仿真软件&#xff0c;绘制电路图&#xff1a; 其中示波器的添加很简单的&#xff0c;看图&#xff1a; 再来看看咱们最后程序的效果&#xff1a; 下面就是程序代码了&#xff0c;新建两个文件PWM.c和PWM.h文件&#xff0c;所属关系如图&#xff1a; 整个的编程思…

Redis 内存的优化

目录 前言 Redis 的内存碎片问题 判断Redis 内存碎片 如何清理内存碎片&#xff1f; 前言 我想讲一下怎么提高Redis 内存的利用率&#xff0c;redis 的数据是保存在内存中。对内存的利用率低&#xff0c;意味着存的数据很少&#xff0c;并不意味着就没有内存了&#xff0c…

如何在Mapbox GL中处理大的GEOJSON文件

Mapbox GL可以将 GeoJSON 数据由客户端(Web 浏览器或移动设备)即时转换为 Mapbox 矢量切片进行显示和处理。本文的目的是教大家如何有效加载和渲染大型 GeoJSON 源,并优化渲染显示速度,增强用户体验,减少客户端卡顿问题。本文以Mapbox 为例,至于其它框架原理大致相同,可…

中国联通云联网在多元行业应用中的核心地位与价值体现

在全球化浪潮与数字化转型的时代背景下&#xff0c;中国联通积极响应市场需求&#xff0c;推出以云联网为核心的全球化智能组网解决方案&#xff0c;突破地理限制&#xff0c;为各行业提供高效、安全、灵活的网络服务。该方案不仅涵盖传统的通信连接&#xff0c;更是深入到能源…

复盘-excel

excel-选列没有用&#xff0c;选小标题才可以 将簇状柱形图放置在一个新表上##### excel: 添加数据模型时&#xff0c;要通过套用表格格式与外部断开连接 透视分析2010年人数未解决(第四套&#xff09; 通过日期显示星期几 判断星期几 因为前面已经通过星期六&#xff0c…

【AcWing】蓝桥杯集训每日一题Day1|二分|差分|503.借教室(C++)

503. 借教室 503. 借教室 - AcWing题库难度&#xff1a;简单时/空限制&#xff1a;1s / 128MB总通过数&#xff1a;8052总尝试数&#xff1a;26311来源&#xff1a;NOIP2012提高组算法标签二分差分 题目内容 在大学期间&#xff0c;经常需要租借教室。 大到院系举办活动&…

Linux上安装torch-geometric(pyg)1.7.2踩坑记录

重点&#xff1a;1.一定要在创建虚拟环境的时候设置好python版本。2.一定要先确定使用1.X还是2.X的pyg库&#xff0c;二者不兼容。3.一定要将cuda、torch、pyg之间的版本对应好。所以&#xff0c;先确定pyg版本&#xff0c;再确定torch和cuda的版本。 结论&#xff1a;如果在u…

【解读】OWASP大语言模型应用程序十大风险

OWASP大型语言模型应用程序前十名项目旨在教育开发人员、设计师、架构师、经理和组织在部署和管理大型语言模型&#xff08;LLM&#xff09;时的潜在安全风险。该项目提供了LLM应用程序中常见的十大最关键漏洞的列表&#xff0c;强调了它们的潜在影响、易利用性和在现实应用程序…

基本计算器II

文章目录 题目解析算法解析算法模拟第一步 第二步第三步第四步第五步第六步最后一步 代码 题目解析 题目链接 我们先来看一下题目这个题目的意思很明确就是给你一个算数式让你计算结果并返回并且给了很多辅助条件来帮助你。 算法解析 那么我们来看看这个题目有哪些做法&…

Qt 定时器事件

文章目录 1 定时器事件1.1 界面布局1.2 关联信号槽1.3 重写timerEvent1.4 实现槽函数 启动定时器 2 定时器类 项目完整的源代码 QT中使用定时器&#xff0c;有两种方式&#xff1a; 定时器类&#xff1a;QTimer定时器事件&#xff1a;QEvent::Timer&#xff0c;对应的子类是QTi…

SQL中常见的DDL操作及示例,数据库操作及表操作

目录 一、数据库操作 1、创建数据库 2、查看所有数据库 3、使用数据库 4、删除数据库 二、表操作&#xff1a; 1、创建表 2、查看表结构 3、修改表结构 3.1 添加列 3.2 修改列数据类型 3.3 修改列名 3.4 删除列 3.5 修改表名 3.6 删除表 注意&#xff1a; 在数…

云计算项目十一:构建完整的日志分析平台

检查k8s集群环境&#xff0c;master主机操作&#xff0c;确定是ready 启动harbor [rootharbor ~]# cd /usr/local/harbor [rootharbor harbor]# /usr/local/bin/docker-compose up -d 检查head插件是否启动&#xff0c;如果没有&#xff0c;需要启动 [rootes-0001 ~]# system…