专栏/[转]Slf4j + logback 打印日志的最佳实践

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

2022年02月25日 07:23--浏览 · --喜欢 · --评论
粉丝:88文章:5

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


 


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字符串,这里不再赘述。

————————————————

版权声明:本文为CSDN博主「春秋战国程序猿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/reggergdsg/article/details/105298012


投诉或建议