日志几点思考

    在系统中经常会加很多必要的日志来帮忙我们定位分析解决问题,虽然这个日志挺简单,但是真的很重要,下面从几个方面来总结下

   1.日志框架的来源

    java有很多现成的日志框架,我们可以借鉴学习源码和设计思想,可参考之前转载的文章https://blog.csdn.net/jiangzhexi/article/details/80771163

   2.日志打印规范

    2.1日志分级:像log4j2有8个日志级别,按照从低到高为:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF。我们常用的就是日志级别分为info ,warn,error, info和debug一般主要用在方法调用开始,参数校验,方法结束等场景,error使用场景:参数校验出错还有业务异常,rpc接口异常等场景  warn使用场景:校验参数以及警告等业务场景

   2.2生产环境约束:生产环境严禁使用ConsoleAppender(具体参考该篇博文);强烈推荐AsyncLogger,也不能出现System.out.println()语句

 2.3 日志输出格式建议统一 

 控制台:%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%t] %c:%L - %m%n
 error:%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [%t] %l - %m%n
 info:%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] %C.%M - %m%n

  2.4规范日志格式: 可以搞一个日志打印工具类,如下代码示例

public class TradeLog {

    private String methodName;
    private String methodValue;
    private Map<String,Object> paramInfo;

    public TradeLog(String methodName, String methodValue, Map<String,Object> paramInfo) {
        this.methodName = methodName;
        this.methodValue = methodValue;
        this.paramInfo=paramInfo;
    }

    @Override
    public String toString() {
        return "TradeLog{" +
                "methodName='" + methodName + '\'' +
                ", methodValue='" + methodValue + '\'' +
                ", paramInfo=" + paramInfo +
                '}';
    }

    public static TradeLog.TradeLogBuilder builder(String logKey, String logValue) {
        return new TradeLog.TradeLogBuilder(logKey,logValue);
    }


    public static class TradeLogBuilder {
        private String methodName;
        private String methodValue;
        private Map<String,Object> paramInfo;

        public TradeLogBuilder(String methodName, String methodValue) {
            this.methodName = methodName;
            this.methodValue = methodValue;
        }


        public TradeLog.TradeLogBuilder appendParam(String paramName, Object paramValue){
            if(paramInfo ==null){
                paramInfo= Maps.newHashMap();
            }
            paramInfo.put(paramName,paramValue);
            return this;
        }
        public TradeLog build() {
            return new TradeLog(this.methodName, this.methodValue,this.paramInfo);
        }
    }


    public static void main(String[] args) {
        TradeLog tradeLog = TradeLog.builder("getOrderById", "获取用户订单信息").appendParam("name",222).appendParam("orderId",333333).build();
        System.out.println(tradeLog);
    }

   3.集成log4j2

 3.1 maven包依赖

#jar包依赖
<!-- log4j2 -->
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-core</artifactId>
	<version>2.3</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-jcl</artifactId>
	<version>2.3</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-slf4j-impl</artifactId>
	<version>2.3</version>
</dependency>
<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-1.2-api</artifactId>
	<version>2.3</version>
</dependency>
<dependency>
	<groupId>com.lmax</groupId>
	<artifactId>disruptor</artifactId>
	<version>3.0.0</version>
</dependency>
<!-- log4j2 -->

<exclusion>
	<groupId>log4j</groupId>
	<artifactId>*</artifactId>
</exclusion>
<exclusion>
	<groupId>org.slf4j</groupId>
	<artifactId>*</artifactId>
</exclusion>

 3.2 升级后压测结果分析(1台docker【8核/16G内存/50G磁盘】)

  • log4j版本为1.2.16时,TPS为3636.7笔/秒,CPU为66.54%;
  • log4j版本为1.2.17时,TPS为3769.92笔/秒,CPU为66.87%;
  • log4j版本为2.3时,TPS为5817.41笔/秒,CPU为91.24%;
  • log4j版本为2.3混合异步打日志时,TPS为6903.75笔/秒,CPU为96.3%;
  • log4j版本为2.3纯异步打日志时,TPS为6913.06笔/秒,CPU为95.6%;

从上面压测结果来看纯异步肯定性能要好,但是升级log4j2还是建议使用混合异步方式,这样能灵活控制error级别log同步输出防止丢失,一些有必要输出的info级别log异步输出提高性能,也就是info级别日志用AsyncLogger异步打,error级别log比较重要还是用Logger同步打。当然还有一种全局方式使用异步的,log4j2的配置文件Loggers中都使用Logger标签即可,在classpath中添加文件“log4j2.component.properties”,文件增加以下内容:“Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector”,这种方式就是所有日志都是异步打印了。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值