阅读更多

2顶
0踩

编程语言

转载新闻 Java日志记录的5条规则

2016-01-12 11:11 by 副主编 mengyidan1988 评论(3) 有7721人浏览
本文由 ImportNew - Jyy 翻译自 javacodegeeks
日志记录是在软件开发过程中常常需要考虑的关键因素。

当产品运行出错时,日志文件通常是我们进行错误分析的首要选择。

而且,在很多情况下,它们是我们手上唯一可以用来查明发生状况和问题根本原因的信息。

可见,正确记录需要的信息是极其重要的。

以下5条日志规则,让我们可以检查和改进在代码中操作日志记录的方式。

同时也请注意,我们既不会讨论怎么配置一个日志引擎,也不会相互比较。

规则1、日志是面向读者的

日志消息不仅要对书写(日志)代码的人有意义,也应该对日志文件的读者有意义。

这似乎是一条很明显但却经常违背的规则。
ERROR: Save failure - SQLException .....

举个例子吧,我们来看看下面这条日志信息:
ERROR: Save failure - SQLException .....

保存什么呢?这条消息在开发者看来是能说明一些问题的,但是对于正在苦苦查看产品问题的可怜家伙来说,却毫无用处。
RROR: Save failure- Entity=Person, Data=[id=123 surname="Mario"] - SQLException....

更合适的信息是这样的:
RROR: Save failure- Entity=Person, Data=[id=123 surname="Mario"] - SQLException....

这就解释了你想要存储的东西(这里是一个 Person,是一个 JPA 实体)以及这个 Person 实例相关的内容。

请注意相关这个单词,并不是指泛泛的全体:我们不应该让无价值的信息使日志文件变得乱糟糟,比如说完整打印所有的实体字段。

通常,实体名字和其逻辑关键字足以识别在表格中的一条记录了。

规则2、匹配日志等级和执行环境

在 Java 系统中提供的所有日志管理工具和引擎都有日志等级(ERROR、INFO……)的概念,这将有可能过滤掉等级过低的消息。

例如,Java util logging 使用如下的等级:SEVERE、WARN、INFO、FINE、FINER、FINEST(+ CONFIG 和 OFF)。相反,两个最受欢迎的日志管理工具, Apache Commons Logging 和 SLFJ 更倾向于如下的等级:FATAL、ERROR、WARN、INFO、DEBUG、TRACE。

日志过滤等级则需要取决于代码的开发阶段:成品与仍处在测试、集成环境下的代码日志等级就不能相同。

更具体的来说,日志等级也应该参考代码的归属情况。

一般而言,我们自己的应用程序代码应该比使用的任何第三方开发库拥有更详细的日志记录。

比如说,Apache 的通用调试消息出现在我们的日志文件中,就没有多大意义。

我通常像这样配置日志记录:
  • 成品阶段: 我的代码是 INFO 等级,第三方库是 WARN。
  • 测试、集成阶段:我的代码是 DEBUG 等级,第三方库是 WARN(或者如果需要的话是 INFO)。
  • 开发阶段:任何有意义的信息。

注意:个人而言,我不建议使用 TRACE/FINEST 等级(我并不是唯一持这种观点的人,可以参考 这里 的例子)。

我并没有发现 DEBUG 和 TRACE 有多大的区别,而年轻团队的成员常常苦恼于到底是使用 DEBUG 还是 TRACE 。

根据KISS原则,我建议只使用RROR、WARN、INFO和DEBUG等级。

规则3、提交前去除编码帮助日志
编码时,我们常常会使用 logger 或是 System.out 在代码中添加日志消息,来更好地掌握应用程序在执行、调试期间发生的状况。
void aMethod(String aParam) {
  LOGGER.debug(“Enter in aMethod”);
  if (“no”.equals(aParam)) {
  LOGGER.debug(“User says no”);
  ….

比如这样的代码:
void aMethod(String aParam) {
  LOGGER.debug(“Enter in aMethod”);
  if (“no”.equals(aParam)) {
  LOGGER.debug(“User says no”);
  ….

这些消息显示被调用的方法并且备份内部变量及方法参数值,主要是为了追踪应用程序的行为。这在非测试驱动开发中相当受欢迎。

但糟糕的是,一旦代码发布(测试之后成为成品)这些消息通常就无用武之地了。

所以,这条规则简单来说就是:一旦你已经完成开发工作,在将代码提交到使用中的 SCM 系统(git、svn……)之前,要去除所有临时的和不必要的日志消息。

这条规则并不是要求去除所有的 DEBUG 消息,只是针对那些在应用程序完成和发布后就没有意义的消息,或者是说当我们有理由相信应用程序能正确运行时就失去意义的那些消息。

规则4、log DEBUG消息之前检查日志等级


根据第2条规则,在产品日志中,我们只会显示ERROR、WARN、INFO 等级的消息,但是在代码中我们也可以使用一些不会影响产品运行的DEBUG消息。
if ( LOGGER.isDebugEnabled((){
 LOGGER.debug (…….)
 }

每次你想要 log 一个 DEBUG 消息时(在使用了规则3后的留下的所有消息),需要在前面添加一个检查来明确是否启用了 DEBUG 日志:
if ( LOGGER.isDebugEnabled((){
 LOGGER.debug (…….)
 }

这种做法可以阻止代码去创建日志消息和调用 logger,提高产品运行程序的效率。

规则5、了解你的 logger

我们使用 logger 方法的方式可能会带来巨大的开销:
  • 创建消息字符串
  • 组织包含在消息字符串中的数据

我们应该查阅所选择的日志管理工具、引擎的 javadoc 文档,了解使用它们 logger 的最有效的方法。
LOGGER.info(“Person name is “ + person.getName());

例如,我们可以创建一条这样的消息:
LOGGER.info(“Person name is “ + person.getName());

这就创建了不必要的字符串实例。
LOGGER.info(“Person name is {}“, person.getName());

使用SLF4J,正确的用法应该是:
LOGGER.info(“Person name is {}“, person.getName());

这里的格式化字符串是常量,不可变消息只有在允许 logging 的情况下才会被创建。

这里可以获得更多细节内容。
来自: ImportNew
2
0
评论 共 3 条 请登录后发表评论
3 楼 卡维囊格美 2016-01-21 09:45
很实用,赞一个
2 楼 hesier110 2016-01-14 09:27
1 楼 tugn 2016-01-13 08:31
[align=left][/align]

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • C# Excel导入导出到DataGridView

    C# Excel导入导出到DataGridView 在DataGridView中直接编辑保存Excel C#导入。导出。还有类库。。。

  • DataGrid 点击单元格弹出面板

    var listData:AdvancedDataGrid...

  • winform datagridview 通过弹出小窗口来隐藏列 和冻结窗口

    1.小窗口如图所示   相应的后台代码:View Code  1  public partial class HideColumn : Form 2     { 3         public DataGridView dgv { set; get; } 4  5         public HideColumn() 6         { 7             InitializeC...

  • C#——表格开发之DataGridView控件

    DataGridView控件支持标准的Windows窗体数据绑定模型,因此它可以绑定到各种数据源。通常,您绑定到管理与数据源交互的BindingSource。BindingSource可以是任何Windows窗体数据源,这在选择或修改数据位置时为您提供了极大的灵活性。将数据绑定到DataGridView控件是直接和直观的,在许多情况下,它就像设置DataSource属性一样简单。当绑定到包含多个列表或表的数据源时,请将DataMember属性设置为指定要绑定到的列表或表的字符串。

  • datagrid之修改

    1.dialog控件 ①.添加操作列(book.js文件) ②.usermanage写入dialog窗体然后添加form表单 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/ht

  • 带分页的datagrid弹窗实现

      本文不介绍基本的引入框架操作   页面准备,页面需要代码如下:   <div id="resourceWindow"> <div id="resultMessage"> </div> <div id="resourcePanel">           <table id="couponRule

  • easyui datagrid 弹出窗口

    我的主页面,代码如下: Javascript代码   //添加数据弹出窗口   $(function(){                  addDataWin = $('#addData-window').window({                             href:'${basePath}/page/marketPlat2/addData/

  • Jquery easyui 实现datagrid的单元格点击跳出弹出框

    最开始,页面布局如图,我们需要选中一行后再点击查看详情才可以,若点中两行,则跳出的弹出框。 然后呢,客户为了方便,要求直接在每一行操作后即可查看详情。所以,我就开始了吭哧吭哧改页面之路。 刚开始,我是想做成点击后直接下拉框内有详情的样子,如 这个样子的。可是呢,好像和我们想展示的周报详情有点不太符合,毕竟周报内容比较多,同时为了方便删除,我保留了选择框。 最后决定做成每一行添加按钮,可以直

  • Easyui--datagrid 的使用 (弹出框的使用)

    1 Home控制器 using DbService; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Script.Serialization; namespace MvcAppEF.Contr

  • easyui弹窗公共方法,弹窗选择数据

    /** * 弹窗公共方法 * @param url 弹窗页面地址 * @param title 弹窗标题 * @param width 弹窗宽度 * @param height 弹窗高度 * @param saveButton 弹窗页面保存按钮对象 */ function popup(url, title, width, height, saveButton,callBackFun...

  • C# Wince设置DataGridCell的格式、颜色

    C# Wince中设置DataGrid的Cell的格式、颜色 可以根据条件任意设置Cell的颜色边框等,甚至可以重画, 并且也有DataGrid动态绑定的功能,值得拥有。

  • C#里的DataGrid的使用

    using System;using System.Collections;using System.ComponentModel;using System.Data;using System.Data.SqlClient;using System.Drawing;using System.Web;using System.Web.SessionState;using System.Web.UI;

  • Toad 修改起始窗口

      Toad默认窗口时Editor, 如果想要修改为Schema Browser可以通过以下步骤进行修改(以Toad9.6为例):      1,点击菜单栏上的View下拉菜单   2,选择Toad Options...菜单   3,在打开窗口的左边功能列表中找到并点击Windows(在最下方)   4,在右边的Behavior显示区域中找到Editor一栏,去除第三个Auto Open...

  • 关于获取弹出的子窗口中datagrid选中的值

    对于常见的一个普通窗口,可以用以下的方式进行弹出窗口和获取选中的datagrid中的row function chooseXxx() { var dia = top.sy.iframeDialog({ id:'u_frame', title : '示例标题', height: $(top).height()...

  • Wpf 弹出窗口

    #region 新增 private void Add_Click(object sender,RoutedEventArgs e) { if(UserAdd.ShowModuleDialog().Equals(System.Windows.Forms.DialogResult.OK)) { DataBind(); } } #endregion弹框页面后台代码:private System.W

  • WPF——MVVM点击弹出窗口

    ViewModel里面建的委托 false隐藏界面true显示

Global site tag (gtag.js) - Google Analytics