提高日志质量的 5 大技巧

最近涌现出各种各样能帮助你理解日志的新工具,有类似 Scribe、Logstash 这样的开源项目,也有类似 Splunk 的预付费工具,还有托管服务如 SumoLogic 和 PaperTrail。这些工具的共同点是对日志数据进行清洗,在大量日志中提取一些更有价值的文件。

但有一件事这些工具却爱莫能助,因为它们完全依赖你实际投入的日志数据,而如何保证数据的质量和数量则需要用户自行完成。因此,在关键时刻,如果你需要基于部分或者遗漏日志做代码调试时,事情可能会变得非常棘手。

为了减少这种情况发生,在这里分享五个建议,在你记录日志时最好能铭记于心:

1. 你好,我的(线程)名字是

正如 Ringo,线程名称这个属性是 Java 中最被低估的方法之一。其原因是线程名称大部分是描述性的。然而问题同样出现在这里,类似人们自己,起名时通常会被赋予一定的意义。而在多线程日志中,线程名同样挥着关键作用。通常情况下,大多数日志框架会记录当前所调用的线程名称。可悲的是,我们通常会看到 http-nio-8080-exec-3 这种名字,简单地由线程池或容器进行分配。

出于某种原因,我们曾不止一次地听过这种误解——线程名称是不可变的。与之相反,在日志中,线程名称占据基本主要地位,你应该确保能正确使用。比如将它与具体情境结合起来,例如 Servlet 的名字、任务相关,或者一些动态语境如用户或消息 ID。

这样的话,代码接口应该是这样:

Thread.currentThread().setName(ProcessTask.class.getName() + “: “+ message.getID);

更先进的版本将被加载到当前线程的线程局部变量,配置 log appender,并自动将其添加到日志条目。

当多个线程写入服务器日志,但你需要集中在单一线程上时,这将会非常有用。如果你在一个分布式 /SOA 环境下运行,更能看到它得天独厚的优势。

2. 分布式的标识符

在 SOA 或消息驱动的架构,任务执行很可能跨多台机器。当处理这种环境下的故障时,连接相关机器和它们的状态将是了解具体情况的关键。大多数日志分析器会将这些日志信息分组,假设你为它们提供了唯一标识,它们便可以作为实际日志消息的一部分。

从设计的角度出发,这意味着,从进入系统到操作完成,每一个入站操作应该有其唯一的 ID 对应。请注意,一个持久的标识符,如用户 ID 可能不是一个好容器。在记录日志文件的过程中,用户可能有多个操作,这将使得隔离特定流更加困难。UUIDs 可能是个不错的选择。它的值可以被加载到实际线程名称或者作为 TLS-thread 的局部储存器。

3. 不要使用文本+驱动器,不要日志+循环

很多时候,你会看到一段代码在紧密的循环中运行,并执行相应的日志操作。基本假设是,该代码运行的次数是有限的。

很可能运行情况非常良好。但是当代码得到意外输入时,循环可能并不会中断。在这种情况下,你不只是处理一个无限循环「虽然这样已经很糟糕了」,你正在处理的代码正将无限量的数据写到磁盘或网络。

在单机场景中它可能会造成一台服务器崩溃,而在分布式场景中,被影响的则是整个集群。因此如果可能,不要在紧密循环中记录日志。捕获错误时,这一点尤其如此。

下面这个例子,记录了一个 while 循环中的异常:

    void read() {
while (hasNext()) {
try {
readData();
} catch {Exception e) {
// this isn’t recommend
logger.error(“error reading data“, e);
}
}
}

如果 readData 抛出异常,而 hasNext 返回值为 true,这里将会写入无限量的日志数据。要解决这个问题的方法是确保不会记录这一切:

void read() {
int exceptionsThrown = 0;
while (hasNext()) {
try {
readData();
} catch {Exception e) {
if (exceptionsThrown < THRESHOLD) {
logger.error(“error reading data", e);
exceptionsThrown++;
} else {
// Now the error won’t choke the system.
}
}
}
}

另一种方法是从循环中移除日志记录,并保存第一/最后一个异常对象并在其它地方记录。

4. 未捕获的处理程序

Westeros 有最后一道防御墙,而你有 Thread.uncaughtExceptionHandler。因此,尽量使用它们。如果没有安装这些处理程序,在异常抛出时,你只能获得很少有价值的上下文,同时你也无法控制在结束之前你已经将其记录,并确定记录的位置。

请注意,即使在未捕获的异常处理程序,看起来你没有任何办法访问线程中(已终止)的任何变量,你仍然可以获得实际线程对象的引用。如果你坚持# 1步,你仍然会得到一个有意义的thread.getName()值可记录。

5. 捕获外部调用

每当调用一个外部的 API, JVM 异常的几率将大大增加。这包括 Web 服务、 HTTP、 DB、 文件系统、操作系统和任何其他 JNI 调用。认真对待每个调用,因为它随时会爆炸 「它很有可能发生在同样的点」。

大多数情况下,外部 API 故障的原因是意外输入,日志中对其记录是修复代码的关键。

在这一点上,你可以选择不记录错误,只是抛出异常也可以。在这种情况下,只要收集到调用的相关参数,并将其解析为异常错误信息。

只要确保异常被捕获并记录在更高级别的堆栈调用即可。

try {
return s3client.generatePresignedUrl(request);
} catch (Exception e) {
String err = String.format(“Error generating request: %s bucket: %s key: %s. method: %s", request, bucket, path, method);
log.error(err, e); //you can also throw a nested exception here with err instead.
}

原文链接:5 Techniques to Improve Your Server Logging

本文系 OneAPM 工程师编译整理。OneAPM 是中国基础软件领域的新兴领军企业,能帮助企业用户和开发者轻松实现:缓慢的程序代码和 SQL 语句的实时抓取。想阅读更多技术文章,请访问 OneAPM 官方博客

时间: 2024-08-03 04:19:11

提高日志质量的 5 大技巧的相关文章

提高网页性能的九大技巧

第一条,DOM 的多个读操作(或多个写操作),应该放在一起.不要两个读操作之间,加入一个写操作. 第二条,如果某个样式是通过重排得到的,那么最好缓存结果.避免下一次用到的时候,浏览器又要重排. 第三条,不要一条条地改变样式,而要通过改变 class,或者 csstext 属性,一次性地改变样式. // bad var left = 10; var top = 10; el.style.left = left + "px"; el.style.top = top + "px&q

提高文章阅读性的7大技巧

用户体验优化 用户在阅读网站的文章时,往往文章的阅读性是一个对用户友好的体现,同时文章的阅读性高往往能留住更多的老用户和吸引更多的新用户,提高网站的浏览量和知名度.下面就让我介绍提高文章阅读性的7大技巧. ①文章列表 一个网站会有大量的文章,用户要在这样大量的文章上快速寻找到自己所需要阅读的文章,是一件很困难的事.为了解决这一个对用户不好友的问题,我们可以使用文章列表这一个技巧.在我个人认为基本上在网站必须有文章列表,一方面方便了用户寻找资讯,另外一方面对于网站站长会是一个很好的统计数据.从文章

7大技巧助你找准微信营销方向

企业做微信营销,一定要找准方向,不然再怎么用功也都是无用功. 1.适应客户的不同需求 不同的企业和行业的客户需求存在很大差异,新老客户也对信息获取有不同的渴望.比如,餐饮.快销.数码.酒店.汽车等服务型企业的客户往往更多的 关注企业提供的促销信息或优惠活动,这些活动不会天天有新意,服务号一般更合适.媒体.通信.交通等行业提供的信息一般比较丰富,更适合订阅号. 同时,企业微信也应该针对新老客户有信息发送上的区分,初次关注的客户与长期订阅的客户信息有差异,对公司业务的用户与普通关注的社会客户有差异

十大技巧快速提升Android应用开发性能

一个应用程序要想开发成功,质量至关重要.用户要求它们决定安装到自己设备上的Android应用程序反应迅即.性能合理.如果应用程序未能提供好用的功能和稳定的用户体验,那么很快就会被卸载掉.本文我们将介绍十大技巧快速提升Android应用开发性能. 1:首先要有良好的编程习惯 要成为一名优秀的资源管理员;既要运用常识,还要使用公认的算法和标准的设计模式.在资源使用方面,如果你打开了资源,要记得关闭资源.要尽量晚地获取,尽量早地释放.这些由来已久的编程准则同样适用于你的Android应用程序,如果它们

如何提高代码质量

一.代码质量 软件是交付给用户,并由用户体验的产品:代码则是对软件正确且详细的描述,所以代码质量关系到软件产品的质量.虽然软件质量不等于代码质量,但是代码上的缺陷会严重的影响到软件产品的质量.因此,为提高代码质量的投入是值得的. 二.软件产品质量通常可以从以下六个方面去衡量 功能性,即软件是否满足了客户业务要求: 可用性,即衡量用户使用软件需要付出多大的努力: 可靠性,即软件是否能够一直处在一个稳定的状态上满足可用性: 高效性,即衡量软件正常运行需要耗费多少物理资源: 可维护性,即衡量对已经完成

记录:掌握单页网站设计的5大技巧

在设计师们的不懈探究之下,单页设计已经摘掉了混乱单调的帽子,构建起了一套相对比较完善的设计体系,保持简洁而漂亮的设计,重视内容,强调清晰明了的表达.从用户体验的角度上来看,单页设计确实有其优势也有缺陷,但是值得注意的是,用户的确是喜欢单页网站的浏览方式,这也是单页设计流行开来的基石. ·单页网站导航方式简单,用户不易迷路,只需上下滚动. ·单页网站内容更专注,信息传递更清晰,更有针对性. ·单页网站几乎可以在全平台设备上流畅浏览,滚动和滑动浏览替代了点击 而设计单页网站最大的挑战在于让用户保持滚

程序员提高工作效率的15个技巧【Facebook】

程序员提高工作效率的15个技巧[Facebook] 作者: habadog 日期: 2015 年 02 月 13 日发表评论 (0)查看评论 1,Days always fill up. Only plan for 4-5 hours of real work per day.其实每天只有4-5个小时能专心编码,充分利用这些时间. 2,Work more when you’re in the zone. Relax when you’re not.在状态的时候多干一些,不在状态时可以就去做个大保

【转】提高PHP性能的53个技巧

PHP技巧汇总:提高PHP性能的53个技巧用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的函数译注:PHP手册中说echo是语言结构,不是真正的函数,故把函数加上了双引号).1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍.2.$row[*id]*的速度是$row[id]的7倍.3.echo 比 print 快,并且使用echo的多重参

提高代码质量:如何编写函数

阅读目录 命名 函数参数 编写函数体 总结 函数是实现程序功能的最基本单位,每一个程序都是由一个个最基本的函数构成的.写好一个函数是提高程序代码质量最关键的一步.本文就函数的编写,从函数命名,代码分布,技巧等方面入手,谈谈如何写好一个可读性高.易维护,易测试的函数. 回到顶部 命名 首先从命名说起,命名是提高可读性的第一步.如何为变量和函数命名一直是开发者心中的痛点之一,对于母语非英语的我们来说,更是难上加难.下面我来说说如何为函数命名的一些想法和感受: 采用统一的命名规则 在谈及如何为函数取一