后端日志最佳实践

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了后端日志最佳实践相关的知识,希望对你有一定的参考价值。

参考技术A

title: 后端日志最佳实践
Date: 2021/07/27 09:18

日志是用来 记录用户操作 系统运行状态 等,是一个系统的重要组成部分。

对于一些简单的应用,可能并不需要在如何记录日志的问题上花费太多精力。

但是对于作为基础平台为很多产品提供服务的后端程序,就必须要考虑如何 依靠良好的日志来保证系统可靠的运行了

1) 请求出错时不能通过日志直接来定位问题 ,而 需要开发人员再临时增加日志并要求请求的发送者重新发送同样的请求 才能定位问题;

2)无法确定服务中的 后台任务是否按照期望执行

3)无法确定 服务的内存数据结构的状态

4)无法确定 服务的异常处理逻辑(如重试)是否正确执行

5)无法确定服务 启动时配置是否正确加载

其他的还有:

---- ERROR

模型连接超时

调用模型时传入的参数格式不正确

---- WARN

调用模型时传入的参数值有误

---- INFO

XX 用户启动机器审查

重试

---- DEBUG

调用模型的请求参数

模型响应的结果

请求的用户信息

打印日志时要 考虑日志的使用者 ,我们的日志的使用者主要是开发和运维人员,所以打印的日志最好是两者都能看懂的(有的时候能让运维人员解决,就别让他们找我们):

这种日志,开发 可能 会看懂,但是运维人员看到可能就会一头雾水,只能在去找开发。所以至少应该是:

这样运维人员一眼就能清楚问题的原因(可能是模型挂了),而不用在找开发来确定问题。

1)能够放在一条日志里的东西,放在多条日志中输出;

2)预期会发生且 能够被正常处理 的异常,打印出一堆无用的堆栈;

3)开发人员在开发过程中为了调试方便而加入的“临时”日志

DEBUG日志和INFO日志的一个重要的区别是, INFO 日志用于记录常规的系统运行状态 (业务状态变化信息、用户业务流程中的核心处理记录等),对于定位一般的问题已经足够了。而 DEBUG 日志则详细的记录了一个请求的处理过程,甚至是每一个函数的输入和输出结果 ,遇到一些隐藏比较深的问题时,必须要依赖DEBUG日志。

然而,由于 DEBUG 级别的日志数量比INFO级别的数量多很多(通常差一个数量级),如果长期在线上服务器开启 DEBUG 级别的日志输出,日志量太大。再比如,有时候仅仅是由于某一个用户的访问模式比较特殊导致了问题,如果将整个服务(特别是一个服务部署了很多台节点时)都临时调整为 DEBUG 级别日志输出,也非常不方便。

所以可以采用这种方案: 当接收到的HTTP请求的QueryString中包含 DEBUG=true 参数时,就将所有的DEBUG级别的日志也输出

服务在接收到一个请求的时候,记录请求的接收时间(T1),在请求处理完成待发送的时候,会记录请求发送时间(T2),通常一个请求的日志都记为INFO级别,然而 当出现请求处理时间(T2-T1)超过一定时间(如10s)时,可以将该日志提升为WARN级别 。通过该方法,可以预先发现系统可能存在的一些问题。

同样的慢操作日志 还可以用来记录系统一些外部依赖的处理时间 ,如一个服务可能依赖外部认证服务器来进行认证授权。通过记录每次认证请求的时间并将超出预期时间的请求日志采用WARN级别输出,可以尽早发现认证服务器是不是需要扩容等问题。

慢日志的 时间阈值应该是可以动态调整 的,这样在进行系统优化时,可以将该报警时间阈值逐渐调小,不断地对系统进行优化。

上面在讲日志级别的时候说过 ERROR 级别代表着系统某个地方出现了问题需要运维人员来处理,那么一般我们都会采用邮件通知的方式进行报警,Logback 也为我们提供了这样的一个 Appender —— SMTPAppender。

具体使用参见下面两篇文章:

ERROR & WARN 日志都代表着系统出现了问题,需要解决;但有时仅仅凭借着一行日志并不能很快的定位到问题,所以可以考虑将打印 ERROR、WARN 日志的包名和行号打印出来。

logback 并没有提供这种功能,不过我们可以通过自定义 Layout 来实现。

开发环境是用于开发本地调试时使用,一般都只需要看控制台就可以,所以没必要在本地输出日志文件,那么我们可以利用 logback 的“条件表达式”来实现:

在性能测试时遇到的另一个问题是,当并发量很大时,可能会有一些请求处理失败(如0.5%),为了对这些错误进行分析,需要去查这些错误请求的日志。而由于这种情况下日志量巨大,使得对错误日志的分析变得困难。

这种情况下可以 将所有的错误日志(ERROR)同时输出到一个单独的文件之中

日志文件不宜过大, 过大的日志文件对于日志监控,问题定位等都会带来不便 。因此需要进行日志文件的切分,日志文件应该按天来分割,还是按照小时来分割,应该 根据日志量来决定 ,原则就是方便开发或运维人员能快速查找日志。

logback 日志工具可以在 日志文件滚动后将前一文件进行压缩,以减少磁盘空间占用 ,若使用 logback 对于日志量庞大的应用建议开启该功能。

为了防止日志文件将整个磁盘空间占满,需要 定期对日志文件进行删除 。例如,在收到磁盘报警时,可以将两个月以前的日志文件删除。

生产环境中的文件输出,可以 考虑使用异步文件输出 ,该种方式日志并不会马上刷新到文件中去, 会产生日志延时 在停止应用时可能会导致一些还在内存中的日志未能及时刷新到文件中去而产生丢失 ,如果对于应用的要求并不是非常高的话,可考虑异步日志

Zipkin 是一款开源的 分布式实时数据追踪系统 ,主要功能是 聚集来自各个异构系统的实时监控数据 ,和 微服务架构下的接口直接的调用链路 系统延时问题

总结一下链路追踪工具主要提供了以下功能:

所以其实没有必要所有的请求的链路都上传到 zipkin,zipkin 为我们提供了一个采样率的概念:

Zipkin分布式任务追踪

指定接口采样率

最重要的还是 不断优化日志

有一点可以肯定,好的日志就像好的文章一样,绝不是一遍就可以写好的,而 需要在实际的运维过程中,结合线上问题的定位,不断地进行优化

此处有以下几个比较好的实践:

Java日志记录最佳实践

最佳日志实践(v2.0)

其他 TODO

1)链路追踪

2)访问日志

3)Swagger 页面动态切换用户 或者使用 chrome 插件实现(不推荐,因为还要安装,java 浏览器版就是这样没火起来的)

或者插件。可以记住的。点击切换用户(cookie),时间要比一般的长

4)其他

logback 的原理

root 和 logger 的继承

5)规范

不能用父类的logger 对象

使用 Firestore 后端进行版本控制的最佳实践 [关闭]

【中文标题】使用 Firestore 后端进行版本控制的最佳实践 [关闭]【英文标题】:Best practices of versioning with Firestore backend [closed] 【发布时间】:2020-03-13 16:00:25 【问题描述】:

对于经典的 REST api,最好将版本添加到 api url。这个版本可以是fi。嵌入在路径中 (api.myservice.com/v1/dataset) 或作为参数 (api.myservice.com/dataset?v=1)。当部署新版本的 api 时,只要需要,它就可以与旧版本并存。旧版本的 API 可以标记为已弃用,最终可以删除。

这为前端提供了适应新版本 API 的宽限期,因此在后端更新、前端开发人员对此进行调整和前端用户进行更新之间没有停机时间。

当我们使用 Firestore 或任何类似的实时数据库时,前端可以直接访问数据库。数据库的结构可以更改,列或表可以重命名、移动或删除。没有 API 可以为前端抽象出这种底层结构。那么,使用实时数据库向前端-后端通信添加某种版本控制的最佳方式是什么?

可能的解决方案:

无论如何都要使用 REST api 作为包含版本的额外层。缺点:使用这种方法会失去实时数据库的优势,例如实时更新和用户管理。

将抽象层移至前端并公开所需的最低版本。如果前端不满足此版本,则强制更新前端。缺点:相信前端会做正确的事,而不是强制执行。

将版本添加到项目名称或表名称中。这将导致大量额外的冗余,其中数据必须不断保持同步。这可能会导致额外费用并且容易出错。

还有其他的吗?

这些选项对我来说似乎都不是好主意。如果前端可以直接访问数据,最好的解决方案是什么?我知道这个问题很快就会被标记为“太宽泛”。如果是,请告诉我如何集中我的问题。

【问题讨论】:

这是一个非常开放的问题,可能会产生一堆固执己见的答案。没有一种正确的方法来对数据进行版本控制。因此,它并不适合 Stack Overflow。我建议您将这个问题带到 Reddit 等讨论板,以便进行一些一般性的对话。 reddit.com/r/Firebase 我按照建议将主题移至reddit.com/r/Firebase/comments/dyhzlv/…。 我认为这对 SO 来说是一个可靠的问题,这个问题和弗兰克的回答都对我有帮助。 【参考方案1】:

我采取的典型方法是将数据模型的版本号放入数据库中。每当需要对数据库进行架构更改时,我都会检查它是否可以保持向后兼容。如果不是,请增加版本号。

无论哪种方式,架构都编码在我的数据库的安全规则中。这意味着客户端无法写入无效数据,因为它将被安全规则拒绝。

客户端读取版本号,并在版本号高于构建时显示请升级

【讨论】:

没有想到禁止错误写入的安全规则,虽然很明显。谢谢粉扑!

以上是关于后端日志最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

MS Access 前端与 SQL Server 后端查询存储最佳实践 [关闭]

Laravel 后端、Vue 前端、api 最佳实践?

Elasticsearch 最佳实践:直接从前端或后端使用

ElasticsearchElasticsearch日志场景最佳实践

日志采集最佳实践

使用 Firestore 后端进行版本控制的最佳实践 [关闭]