Slf4j + logback 打印日志的最佳实践

2 篇文章 0 订阅
2 篇文章 0 订阅

 

我们抛开业务逻辑,仅仅从日志的角度来考虑日志问题。集合最近对项目的日志优化,总结以下几点最佳实践。

 

Slf4j + logback 打印日志的最佳实践
1,日志级别使用不当
2,谨慎使用e.printStackTrace()
3,使用占位符,而不是字符串拼接
4,尽量打印更少的日志
5,尽量不要在for循环中log日志

 

下面结合代码,来具体讲解。

 

1,日志级别使用不当

 

Slf4j有四个级别的log level可供选择,级别从上到下由低到高,优先级高的将被打印出来。

Debug:简单来说,对程序调试有利的信息都可以debug输出。

info:对用户有用的信息,比如最常见的打印接口入参和返参。

warn:可能会导致错误的信息,比如某个对象可能为null的场景判断。

error:顾名思义,发生错误的地方,最常见的catch代码块中的日志。

 

这里以error日志为例,举一个例子,在合适的场合打印合适的日志,是我们日志界的规范。

        // ---------------- 1,日志级别使用不当 ----------------
        try{
            String str = null;
            str.length();
        } catch(Exception e) {
            // 这里不推荐打印info日志
            logger.info("注意,这里不要打印info日志,", e);
            // 正确的做法
            logger.error("注意,这里不要打印error日志,", e);
        }

 

 

2,谨慎使用e.printStackTrace()

 

e.printStackTrace()打印的是异常堆栈信息,会占用内存空间。正确的姿势是把日志打印到文件中。

        // ---------------- 2,谨慎使用e.printStackTrace() ----------------
        try{
            String str = null;
            str.length();
        } catch(Exception e) {
            // 谨慎使用e.printStackTrace()
            e.printStackTrace();
        }

 

3,使用占位符,而不是字符串拼接

 

Slf4j打印日志使用了占位符,避免了字符串拼接操作。字符串拼接最大的弊端,就是需要new新的字符串对象,增加了内存的开销。

        // ---------------- 3,使用占位符,而不是字符串拼接 ----------------
        String str = null;
        String str2 = "五千年文明史";
        try{
            str.length();
        } catch(Exception e) {
            // 不推荐的做法,尤其是拼接的 字符串较多时,对性能有影响
            logger.error("str:" + str + ", str2:" + str2, e);
            // 正确的做法
            logger.error("str:{}, str2:{}", str, str2, e);
        }

 

4,尽量打印更少的日志

 

日志打印,要坚持一个原则:尽量打印更少的日志。

因为磁盘空间也是有限的,如果磁盘空间不足,会直接导致应用程序的崩溃。

 

好的做法是:不要打印无用的日志,不要重复打印日志,尽量不要在for循环中打印日志。

        // ---------------- 4,尽量打印更少的日志 ----------------
        String str1 = null;
        String str2 = null;
        String str3 = null;
        try{
            // 错误的做法
            logger.info("str1:{}", str1);
            logger.info("str1:{}", str1);
            logger.info("str1:{}", str1);
            
            // 正确的做法
            logger.info("str1:{}, str2:{}, str3:{}", str1, str2, str3);
            str.length();
        } catch(Exception e) {
            logger.error("str:{}", str, e);
        }

 

5,尽量不要在for循环中log日志

 

一般来说,for循环中的log日志,都可以提到for循环外面来打印。因为for循环的对象

是集合,而集合都可以转化成对应的json字符串。

特殊情况,必须要在for循环中打印的,需要评估是否有必要,已经这个日志的量级,看

是否太耗内存。

 

        // ---------------- 5,尽量不要在for循环中log日志 ----------------
        try{

            List<String> list = new ArrayList<>();
            list.add("唐朝");
            list.add("宋朝");
            list.add("董仲舒");

            // 不推荐的做法
            for (String str : list) {
                logger.info("str:{}", str);
                // 业务逻辑代码
            }

            // 推荐的做法
            logger.info("list to json:{}", JSON.toJSON(list).toString());
            for (String str : list) {

                // 业务逻辑代码
            }

        } catch(Exception e) {
            logger.error("{} error", this.getClass().getSimpleName(), e);
        }

 

如果是其他集合,同理,也可以转化成json字符串,这里不再赘述。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值