java agent开发 日志打印

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

简介

目前java 打印日志用的比较多的就是slf4j配合log4j/logback进行日志打印,但是呢agent是独立的jar包,
使用slf4j就需要将包引入agent中,这样就可能和业务自身的slf4j log4j日志产生冲突

而且在agent包使用slf4j-api包后,需要保证agent的classLoader和业务的classLoader保持一致,否则找不到

需求

  • agent的日志打印可以不依赖于业务日志,如果用户有日志包依赖,也可以使用业务日志
  • agent的日志设置,用户可以在环境变量设置

问题

  • 有时候出现包冲突,导致日志打印不出来
  • spring boot项目的classLoder和agent的classLoader不一致,sf4j相关包找不到。因为spring boot打包出来后是一个独立的jar包,jar包内部的依赖包由spring 自己的类加载器处理
  • 在ide调试的时候没有问题,在linux环境运行就有问题。因为在ide调试的时候所有包都在一个classLoader下,可以找到相关的类

解决方案

  • spring boot的问题可以通过字节码增强的方式,把agent相关的包路径加到spring boot的classLoader(JarLauncher) 搜索路径中

  • agent日志打印方式使用Java.util.logging (jdk原生的打印),jul-to-slf4j包可以把 原生的log和sf4结合起来。这时候不管有没有slf4j相关包都可以打印日志。有就走slf4j,没有就是jdk自己的打印

  • ide调试的问题没有好的解决方案,只能说在本地shell进行一次独立运行测试

相关代码封装实例

public class AgentLogger {
    static Logger logger = Logger.getLogger("AgentLogger");

    static String defaultLogName = "";

    public static Logger getLogger(){
        return logger;
    }

    public static void log(Level level, String msg, Object...param){

        if(param != null && param.length >0){
            String message = String.format(msg,param);
            logger.log(level,message);
        }else {
            logger.log(level,msg);
        }

    }

    public static void info( String msg, Object...param){
        log(Level.INFO,msg,param);
    }

    public static void init(){
//        Logger tlogger = Logger.getLogger("plough");
//        Logger clogger = Logger.getLogger("governance-client");
//
//        tlogger.setLevel(Level.SEVERE);
//        clogger.setLevel(Level.SEVERE);

        setLevel();

        String agentLogNames = EnvUtil.getEnv("agent_console_log_name",defaultLogName);

        List<String> agentLogNameList = StringUtil.StringToList(agentLogNames);
		// 给某个logger 手动添加日志打印, 防止某种情况打印不出日志
        for (String agentLogName : agentLogNameList){
            Logger logger = Logger.getLogger(agentLogName);

            Handler[] handlers = logger.getHandlers();
            if (handlers != null && handlers.length == 0){
                ConsoleHandler consoleHandler = new ConsoleHandler();
                consoleHandler.setLevel(Level.ALL);
                logger.addHandler(consoleHandler);
            }
        }
    }
	
	//可以通过环境变量设置日志级别
    public static void setLevel(){
        Map<String,String> envMap = System.getenv();

        Properties properties = System.getProperties();
        properties.putAll(envMap);
        Set<Object> keySet = properties.keySet();

        for (Object envKey : keySet){
            String envKeyStr = envKey.toString();

            if (envKeyStr.startsWith("agent_log_level_")){
                envKeyStr = envKeyStr.replace("agent_log_level_","");
                Logger logger = Logger.getLogger(envKeyStr);

                String level = properties.getProperty(envKey.toString());
                if ("error".equals(level)) {
                    logger.setLevel(Level.SEVERE);
                }else if ("info".equals(level)){
                    logger.setLevel(Level.INFO);
                }else if ("debug".equals(level)){
                    logger.setLevel(Level.ALL);
                }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值