Java Log4J 自定义字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1687473/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Log4J Custom Fields
提问by Scott Cowan
Introduction:
介绍:
I'm trying to get additional fields to log with log4j, and its working but only when I create an appender in code and not in the log4j.properties
我正在尝试获取其他字段以使用 log4j 进行记录,并且仅当我在代码中而不是在 log4j.properties 中创建附加程序时才可以正常工作
Progress:
进步:
- Used this article Adding Conversion Characters to PatternLayoutfor log4j 1.1.3
- Made a sample app for log4j 1.2
- 使用这篇文章为 log4j 1.1.3添加转换字符到 PatternLayout
- 为 log4j 1.2制作了一个示例应用程序
Problem:
问题:
using the properties file it will run but won't use AppServerPatternLayout so the custom fields aren't displayed.
使用它会运行的属性文件,但不会使用 AppServerPatternLayout,因此不会显示自定义字段。
Download Code
下载代码
customlog.properties
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
Main.java logging without a log4j properties file
没有 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");
Main.java logging with a log4j properties file
带有 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");
Expected output
预期输出
----------------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
Actual output
实际产量
-----------------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
Solution
解决方案
Using MDC you can add custom fields like
使用 MDC,您可以添加自定义字段,例如
MDC.put("Version", versionName);
Logger log = LogManager.getLogger("some.log");
log.info("Hello");
and pull it out in the log4j.properties with a UPPER case X
并在 log4j.properties 中使用大写 X 将其拉出
log4j.appender.stdout.layout.ConversionPattern=%X{Version}
采纳答案by Aaron Digulla
From the example you posted, I can only guess that AppServerPatternLayout
is not in the package logging
. Everything else looks find. Add
从您发布的示例中,我只能猜测它AppServerPatternLayout
不在包中logging
。其他一切看起来都找到了。添加
log4j.DEBUG=true
to your properties file. log4j will then dump what it does while reading the properties. Maybe that gives you an idea what's wrong.
到您的属性文件。log4j 然后将在读取属性时转储它所做的事情。也许这让你知道出了什么问题。
If that doesn't help, consider to use Nested Diagnostic Contexts.
如果这没有帮助,请考虑使用Nested Diagnostic Contexts。
回答by rsp
Can it be that when you load via properties the AppServerPatternLayout
is instantiated before the AppServerLoggerFactory
is created? If you pick up the values of your custom fields at creation as opposed to at first use that could be an explanation.
是不是当您通过属性加载时AppServerPatternLayout
,AppServerLoggerFactory
会在创建之前实例化?如果您在创建时获取自定义字段的值而不是第一次使用,这可能是一种解释。
回答by Alexander Pogrebnyak
I'm not sure that you will achieve this with properties configuration, but I think you can do this with XML, which gives you a lot of customization options:
我不确定您是否会通过属性配置来实现这一点,但我认为您可以使用 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>
You will need to define setters on AppServerLoggerFactory
for server, component and version. Also, read log4j.dtd
on general layout of xml configuration file.
您需要AppServerLoggerFactory
为服务器、组件和版本定义设置器。另外,请阅读log4j.dtd
xml 配置文件的总体布局。
Save this file as log4j.xml and define -Dlog4j.configuration=/path/to/log4j.xml in your startup script, or replace log4j.properties with log4j.xml in your web-app.
将此文件另存为 log4j.xml 并在您的启动脚本中定义 -Dlog4j.configuration=/path/to/log4j.xml,或在您的 Web 应用程序中将 log4j.properties 替换为 log4j.xml。
I've never tried a custom LoggerFactory before, but it may be that because it is installed by the configurator you can use standard getLogger
factory calls, e.g.
我以前从未尝试过自定义 LoggerFactory,但可能是因为它是由配置器安装的,因此您可以使用标准的getLogger
工厂调用,例如
//Logger logger = AppServerLogger.getLogger("some.log");
Logger logger = Logger.getLogger("some.log");