zoukankan      html  css  js  c++  java
  • 日志到底该如何打印?

    最近在做新项目,一直在加班,期间遇到很多问题,我把一部分归类为设计原则的问题,当然,这里的设计原则不是特指那个SOLID五大原则,这里是指更广义的设计原则,不喜勿喷。

    今天,我们来看第一个问题: 日志到底该如何打印?

    咋一看,这个问题很简单,其实不然,我随手写几个,您看看。

    log.error("xxxxx");

    log.error(e.getMessage());

    log.error("xxxxx", e.getMessage());

    log.error("xxxxx {}", e.message());

    log.error("xxxxx {}", e);

    好了,就随便写这么多,地铁上打字不太方便,您认为上面那些日志打印方式哪些是正确的?

    实话说,没有正确的,全是错的。怎么样,是不是踩坑了,是不是给别人埋过这样的坑。

    那么,怎么打印日志才是正确的呢?

    如果您使用的是slf4j,那么,只有下面这一种是正确的:

    log.error("xxxxx, userId={}, xxParam={}", userId, xxParam, e);

    首先,打印日志必须带上上下文信息,比如,用户ID,关键参数,同时,如果是捕获异常里面打印的日志,必须把原来的e打印出来,否则,排查日志想死的心都有了。

    比如,我最近就遇到一个同学,他把远程调用用一个try catch包着,并在catch中捕获了异常,打印了日志"远程调用错误xxx",呵呵,有一次请求失败,非要说远程调用失败,对方出错了,对方说我没收到请求呀,两人撕逼,最后找到我,我一看这代码,说了一句,把e打印出来再重新调用,结果可想而知,他自己空指针了,呵呵了。

    再说回上面的打印方式,有的同学可能会质疑,前面引号里明明是两个大括号,后面却出现3个变量,确定这个e能打印出来?

    你是在怀疑我吗?自己看源码去。源码中已经明确写了如果最后一个参数是Exception类型,就不会参与字符串格式化,会单独拿出来打印,同时,可以打印出堆栈信息。看源码去吧,我在地铁上,就不截图了。

    你以为本篇文章就结束了吗?那你就错了。

    有没有更优雅的日志打印方式呢?

    我认为,最好的日志是以解决问题的方式打印日志。

    怎么理解呢?

    我们以服务注册为例,当注册中心地址不通的时候,我们能不能这样打印呢?

    "从 112.112.112.112 到注册中心 113.113.113.113的网络不通,请检查注册中心是否启动,网络防火墙是否畅通,balabala"。

    这样的方式就比较好,给使用者提供解决方案,你只要按着给出的方案排查一下,大概率就能解决了你的问题,这才是最优雅的打印姿势。

    好了,今天的内容就到这里,嗐,差点坐过站。

  • 相关阅读:
    扫面线模板
    (动态规划、栈)leetcode 84. Largest Rectangle in Histogram, 85. Maximal Rectangle
    tmux 常见命令汇总
    leetcode 221
    leetcode 319 29
    (贪心)leetcode 392. Is Subsequence, 771. Jewels and Stones, 463. Island Perimeter
    leetcode 982 668
    Python import 同文件夹下的py文件的函数,pycharm报错
    Windows里Anaconda-Navigator无法打开的解决方案
    Windows下 gpu版 Tensorflow 安装
  • 原文地址:https://www.cnblogs.com/tong-yuan/p/14311382.html
Copyright © 2011-2022 走看看