【问题标题】:Log4J Custom FieldsLog4J 自定义字段
【发布时间】:2009-11-06 13:02:46
【问题描述】:

简介:

我正在尝试获取其他字段以使用 log4j 进行记录,并且它可以工作,但仅当我在代码中而不是在 log4j.properties 中创建附加程序时

进展:

  1. 将这篇文章 Adding Conversion Characters to PatternLayout 用于 log4j 1.1.3
  2. 发了sample app for log4j 1.2

问题:

使用将运行但不会使用 AppServerPatternLayout 的属性文件,因此不会显示自定义字段。

Download Code

customlog.properties

log4j.rootLogger=FATAL
log4j.logger.some.log=INFO,stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=logging.AppServerPatternLayout
log4j.appender.stdout.layout.ConversionPattern=-----------------using log file------------------------%nTime:      %d%nHost:      %h%nServer:    %s%nComponent: %b%nVersion:   %v%nPriority:  %p%nThread Id: %t%nContext:   %x%nMessage:   %m%n

没有 log4j 属性文件的 Main.java 日志记录

AppServerLoggerFactory factory;
factory = new AppServerLoggerFactory("MyServer", "MyComponent", "1.0");
AppServerLogger.setFactory(factory);
Logger logger = AppServerLogger.getLogger("some.log");
PatternLayout layout = new AppServerPatternLayout( formatString );
logger.addAppender( new ConsoleAppender(layout) );
logger.info("Hello");

使用 log4j 属性文件记录 Main.java

PropertyConfigurator.configure("customlog.properties");
AppServerLoggerFactory factory;
factory = new AppServerLoggerFactory("MyServer", "MyComponent", "1.0");
AppServerLogger.setFactory(factory);
Logger logger = AppServerLogger.getLogger("some.log");
logger.info("Hello");

预期输出

----------------using in code appender----------------------
Time:      2009-11-06 12:55:05,785
Host:      M1330
Server:    MyServer
Component: MyComponent
Version:   1.0
Priority:  INFO
Thread Id: main
Context:   
Message:   logging config from code

实际输出

-----------------using log file------------------------
Time:      2009-11-06 12:56:17,983
Host:      
Server:    
Component: 
Version:   
Priority:  INFO
Thread Id: main
Context:   
Message:   logging config from customlog.properties

解决方案

使用 MDC,您可以添加自定义字段,例如

MDC.put("Version", versionName);
Logger log = LogManager.getLogger("some.log");        
log.info("Hello");

并在 log4j.properties 中使用大写 X 将其拉出

log4j.appender.stdout.layout.ConversionPattern=%X{Version}

【问题讨论】:

标签: java log4j


【解决方案1】:

从您发布的示例中,我只能猜测AppServerPatternLayout 不在包logging 中。其他一切看起来都可以找到。添加

log4j.DEBUG=true

到您的属性文件。 log4j 然后会在读取属性时转储它所做的事情。也许这会让你知道出了什么问题。

如果这没有帮助,请考虑使用Nested Diagnostic Contexts

【讨论】:

【解决方案2】:

当您通过属性加载时,AppServerPatternLayout 在创建AppServerLoggerFactory 之前是否会被实例化?如果您在创建时选择自定义字段的值,而不是在第一次使用时,这可能是一种解释。

【讨论】:

  • AppServerPatternLayour 不依赖于 AppServerLoggerFactory。它所做的就是创建一个 AppServerPatternParser,然后使用它的属性检查它是否获得了一个 AppServerLoggingEvent 实例
  • @Scott,你的记录器有一个静态工厂的默认值,null's 作为值。如果事件是从该工厂创建的,则值将为空。在实例化自定义工厂后,您可以通过移动 .configure() 来证明/反驳。我相信您看到的是创建工厂和事件对象之间的竞争条件。
  • 你可能是对的,当我在属性中切换回 PatternLayout 时,它在日志中显示 %h。所以它一定是在加载。
【解决方案3】:

我不确定您是否会通过属性配置来实现这一点,但我认为您可以使用 XML 来实现这一点,这为您提供了很多自定义选项:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
  xmlns:log4j="http://jakarta.apache.org/log4j/"
  debug="true"
  reset="true"
>
  <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out"/>
    <layout class="your.package.AppServerPatternLayout">
      <param name="ConversionPattern" value="YOUR CONVERSION PATTERN"/>
    </layout>
  </appender>

  <root>
    <level value="info"/>
    <appender-ref ref="stdout" />
  </root>

  <loggerFactory class="your.package.AppServerLoggerFactory">
    <param name="server" value="MyServer"/>
    <param name="component" value="MyComponent"/>
    <param name="version" value="1.0r"/>
  </loggerFactory>

</log4j:configuration>

您需要在AppServerLoggerFactory 上为服务器、组件和版本定义设置器。另外,请阅读 log4j.dtd 了解 xml 配置文件的一般布局。

将此文件另存为 log4j.xml 并在您的启动脚本中定义 -Dlog4j.configuration=/path/to/log4j.xml,或在您的网络应用中将 log4j.properties 替换为 log4j.xml。

我以前从未尝试过自定义 LoggerFactory,但可能是因为它是由配置器安装的,所以您可以使用标准的 getLogger 工厂调用,例如

//Logger logger = AppServerLogger.getLogger("some.log");
Logger logger = Logger.getLogger("some.log");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2015-06-10
    • 2017-08-25
    • 2013-11-25
    相关资源
    最近更新 更多