Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于使用static final修饰Logger变量的相关框架或组件日志无法在各业务模块正常隔离打印的问题 #828

Closed
suntaiming opened this issue Jan 11, 2024 · 11 comments
Labels

Comments

@suntaiming
Copy link

共用的框架或组件依赖会下沉到基座(模块瘦身),很多框架或组件都是使用static final修饰的Logger变量
这样就会导致这些框架或组件日志无法在各业务模块正常隔离打印,请问有解决方案吗?

@lvjing2
Copy link
Collaborator

lvjing2 commented Jan 11, 2024

https://github.com/sofastack/sofa-serverless/tree/master/samples/springboot-samples/logging
已经有解决方案,这是你想要的,可以看下这里

@suntaiming
Copy link
Author

这种复写Log4J2LoggingSystem.getLoggerContext() 方法应该只能解决初始化配置问题,后续动态获取的log日志可以正常打印,但是针对static final 修饰Logger 因为只在第一次类加载时获取log对象(使用的是基座配置),所以导致业务模块调用时的日志都打印到了基座目录,这种这么处理呢?

@lvjing2
Copy link
Collaborator

lvjing2 commented Jan 12, 2024

通过我们的适配逻辑,第一次加载的时候已经拿到的是模块的配置了,也就是能打印到模块目录里的

@suntaiming
Copy link
Author

但是这些公共组件的依赖是下沉到基座的,所有业务模块都会使用,比如第一加载使用的是A模块的配置,后续B模块使用时日志就会也打印到A模块的目录中(因为static final修饰的logger只会加载一次,用的是A模块的配置)

@lvjing2
Copy link
Collaborator

lvjing2 commented Jan 16, 2024

是的,这部分的日志是作为基座的日志打印的,没有区分模块。不过如果是流量相关的日志,可以通过流量里带上模块信息,在打印trace的时候把模块信息打印出来。

@suntaiming
Copy link
Author

suntaiming commented Jan 19, 2024

目前想到一种方案:
log4j2适配器上再加上对static final修饰的logger适配,复写org.apache.logging.slf4j.Log4jLogger,该类是个包装类,底层实际时调用ExtendedLogger具体打印日志的,所以我们针对此类有一定操作空间,添加Map<ClassLoader,ExtendedLogger>做一个缓存,key是每个模块的类加载器,value是具体模块的ExtendedLogger ,每次调用打印方法都根据当前线程上下文类加载器获取对应模块的ExtendedLogger,如果缓存没有使用当前线程上下文类加载器对应的LoggerContext.getLogger()重新获取并缓存。

代码如下:

public class Log4JLogger implements LocationAwareLogger, Serializable {
    private transient final Map<ClassLoader, ExtendedLogger> loggerMap = new ConcurrentHashMap<>();
    private static final Map<ClassLoader, LoggerContext> LOGGER_CONTEXT_MAP = new ConcurrentHashMap<>();

    pubblic void info(final String format, final Object o) {
        //每次调用都获取对应的ExtendedLogger
        getLogger().logIfEnabled(FQCN, Level.INFO, null, format, o);
    }
   
   /**
     * 根据当前线程上下文类加载器获取logger
     *
     * @return ExtendedLogger
     */
    private ExtendedLogger getLogger() {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        LoggerContext loggerContext = LOGGER_CONTEXT_MAP.get(classLoader);
        if (loggerContext == null) {
            loggerContext = LogManager.getContext(Thread.currentThread().getContextClassLoader(), false);
            LOGGER_CONTEXT_MAP.put(classLoader, loggerContext);
        }
        ExtendedLogger extendedLogger = loggerMap.get(classLoader);
        if (extendedLogger == null) {
            extendedLogger = loggerContext.getLogger(this.name);
            loggerMap.put(classLoader, extendedLogger);
        }
        return extendedLogger;
    }
   } 

@lvjing2
Copy link
Collaborator

lvjing2 commented Jan 20, 2024

赞,挺不错的想法。可以通过把复写代码放在下面这个包里,然后实际验证下吗?然后提交个 PR 吗?

我们现在 log4j2 也是复写了部分类来支持多应用的。
https://github.com/sofastack/sofa-serverless/tree/master/sofa-serverless-runtime/sofa-serverless-adapter-ext/sofa-serverless-adapter-log4j2

@lvjing2
Copy link
Collaborator

lvjing2 commented Jan 22, 2024

方便加下开发者协作群细聊吗?或者我个人微信 zzl_ing
“Serverless 社区交流与协作群”群的钉钉群号: 24970018417

@suntaiming
Copy link
Author

好的,已提pr:sofastack/sofa-serverless#478

Copy link

This issue has been automatically marked as stale because it has not had recent activity in the last 30 days. It will be closed in the next 7 days unless it is tagged (pinned, good first issue or help wanted) or other activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale label Feb 22, 2024
@lvjing2
Copy link
Collaborator

lvjing2 commented Feb 25, 2024

已完成

@lvjing2 lvjing2 closed this as completed Feb 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants