Java log4j 日志文件名?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/83918/
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 log file names?
提问by DIA Tom
We have several jobs that run concurrently that have to use the same config info for log4j. They are all dumping the logs into one file using the same appender. Is there a way to have each job dynamically name its log file so they stay seperate?
我们有几个同时运行的作业,它们必须对 log4j 使用相同的配置信息。他们都使用同一个 appender 将日志转储到一个文件中。有没有办法让每个作业动态命名其日志文件,以便它们保持独立?
Thanks
Tom
谢谢
汤姆
采纳答案by shadit
Can you pass a Java system property for each job? If so, you can parameterize like this:
您可以为每个作业传递一个 Java 系统属性吗?如果是这样,您可以像这样参数化:
java -Dmy_var=somevalue my.job.Classname
And then in your log4j.properties:
然后在你的 log4j.properties 中:
log4j.appender.A.File=${my_var}/A.log
You could populate the Java system property with a value from the host's environment (for example) that would uniquely identify the instance of the job.
您可以使用来自主机环境(例如)的值填充 Java 系统属性,该值将唯一标识作业的实例。
回答by DIA Tom
You could programmatically configure log4j when you initialize the job.
您可以在初始化作业时以编程方式配置 log4j。
You can also set the log4j.properties file at runtime via a system property. From the manual:
您还可以在运行时通过系统属性设置 log4j.properties 文件。从手册:
Set the resource string variable to the value of the log4j.configurationsystem property. The preferred way to specify the default initialization file is through the log4j.configuration system property. In case the system property log4j.configuration is not defined, then set the string variable resource to its default value "log4j.properties".
将资源字符串变量设置为log4j.configuration系统属性的值。指定默认初始化文件的首选方法是通过 log4j.configuration 系统属性。如果未定义系统属性 log4j.configuration,则将字符串变量资源设置为其默认值“log4j.properties”。
Assuming you're running the jobs from different java commands, this will enable them to use different log4j.properties files and different filenames for each one.
假设您从不同的 java 命令运行作业,这将使它们能够使用不同的 log4j.properties 文件和不同的文件名。
Without specific knowledge of how your jobs are run it's difficult to say!
如果不了解您的工作是如何运行的,就很难说!
回答by Alexandre Victoor
Tom you coud specify and appenders for each job. Let's that you have 2 jobs corresponding to two different java packages com.tom.firstbatch and com.tom.secondbatch, you would have something like this in log4j.xml :
汤姆,您可以为每个作业指定和附加程序。假设您有 2 个作业对应于两个不同的 java 包 com.tom.firstbatch 和 com.tom.secondbatch,您将在 log4j.xml 中有这样的内容:
<category name="com.tom.firstbatch">
<appender-ref ref="FIRST_APPENDER"/>
</category>
<category name="com.tom.secondtbatch">
<appender-ref ref="SECOND_APPENDER"/>
</category>
回答by Asgeir S. Nilsen
If the job names are known ahead of time, you could include the job name when you do the getLogger() call. You then can bind different appenders to different loggers, with separate file names (or other destinations).
如果提前知道作业名称,则可以在执行 getLogger() 调用时包含作业名称。然后,您可以使用单独的文件名(或其他目的地)将不同的 appender 绑定到不同的记录器。
If you cannot know the job name ahead of time, you could configure the logger at runtime instead of using a configuration file:
如果您不能提前知道作业名称,您可以在运行时配置记录器而不是使用配置文件:
FileAppender appender = new FileAppender();
appender.setFileName(...);
appender.setLayout(...);
Logger logger = Logger.getLogger("com.company.job."+jobName);
logger.addAppender(appender);
回答by erickson
You could write your own appender that makes up its own filename, perhaps using the [File.createTempFile](http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String))method. If the FileAppender
class was written correctly, you should be able to extend it—or RollingFileAppender
—and override the getFile
method to return one that you choose based on whatever new properties you would like to add.
您可以编写自己的附加程序来组成自己的文件名,也许使用 [File.createTempFile]( http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html# createTempFile(java.lang.String,%20java.lang.String))方法。如果FileAppender
类编写正确,您应该能够扩展它——或者RollingFileAppender
——并覆盖该getFile
方法以返回您根据要添加的任何新属性选择的方法。
回答by James A. N. Stauffer
You can have each job set NDC or MDC and then write an appender that varies the name based on the NDC or MDC value. Creating a new appender isn't too hard. There may also be a appender that will fit the bill in the log4j sandbox. Start looking in http://svn.apache.org/viewvc/logging/log4j/trunk/contribs/
您可以让每个作业设置 NDC 或 MDC,然后编写一个根据 NDC 或 MDC 值改变名称的 appender。创建一个新的 appender 并不太难。在 log4j 沙箱中可能还有一个 appender 可以满足要求。开始查看http://svn.apache.org/viewvc/logging/log4j/trunk/contribs/
回答by pgras
you may implement following:
您可以执行以下操作:
- A ThreadLocal holder for the identity of your job.
- Extend FileAppender, your FileAppender has to keep a Map holding a QuietWriter for every job identity. In method subAppend, you get the identity of your job from the ThreadLocal, you look up (or create) the QuietWriter and write to it...
- 用于标识您的工作的 ThreadLocal 持有者。
- 扩展 FileAppender,您的 FileAppender 必须为每个工作标识保留一个包含 QuietWriter 的 Map。在方法 subAppend 中,您从 ThreadLocal 获取工作的标识,查找(或创建) QuietWriter 并写入它...
I may send you some code by mail if you wish...
如果您愿意,我可以通过邮件向您发送一些代码...
回答by 18Rabbit
We have something similar implemented in our system. We store the specific loggers in a HashMap and initialize appenders for each of them as needed.
我们在我们的系统中实现了类似的东西。我们将特定的记录器存储在 HashMap 中,并根据需要为每个记录器初始化附加器。
Here's an example:
下面是一个例子:
public class JobLogger {
private static Hashtable<String, Logger> m_loggers = new Hashtable<String, Logger>();
private static String m_filename = "..."; // Root log directory
public static synchronized void logMessage(String jobName, String message)
{
Logger l = getJobLogger(jobName);
l.info(message);
}
public static synchronized void logException(String jobName, Exception e)
{
Logger l = getJobLogger(partner);
l.info(e.getMessage(), e);
}
private static synchronized Logger getJobLogger(String jobName)
{
Logger logger = m_loggers.get(jobName);
if (logger == null) {
Layout layout = new PatternLayout("...");
logger = Logger.getLogger(jobName);
m_loggers.put(jobName, logger);
logger.setLevel(Level.INFO);
try {
File file = new File(m_filename);
file.mkdirs();
file = new File(m_filename + jobName + ".log");
FileAppender appender = new FileAppender(layout, file.getAbsolutePath(), false);
logger.removeAllAppenders();
logger.addAppender(appender);
}
catch (Exception e)
{ ... }
}
return logger;
}
}
Then to use this in your job you just have to use a one line entry like this:
然后要在您的工作中使用它,您只需要使用这样的一行条目:
JobLogger.logMessage(jobName, logMessage);
This will create one log file for each job name and drop it in its own file with that job name in whichever directory you specify.
这将为每个作业名称创建一个日志文件,并将其放入自己的文件中,并在您指定的任何目录中使用该作业名称。
You can fiddle with other types of appenders and such, as written it will continue appending until the JVM is restarted which may not work if you run the same job on a server that is always up, but this gives the general idea of how it can work.
您可以摆弄其他类型的附加程序等,如所写的那样,它将继续附加,直到 JVM 重新启动,如果您在始终启动的服务器上运行相同的作业,这可能无法正常工作,但这给出了它如何可以的总体思路工作。
回答by Vishal Zanzrukia
log4j.logger.com.foo.admin=,AdminFileAppender log4j.logger.com.foo.report=,ReportFileAppender
log4j.logger.com.foo.admin=,AdminFileAppender log4j.logger.com.foo.report=,ReportFileAppender
It's another way to do this task.. here com.foo.admin is the full package name
这是执行此任务的另一种方法.. 这里 com.foo.admin 是完整的包名称
回答by runaros
Building on shadit's answer. If each job can be identified by which class' main method was started you can use the system property sun.java.command
that contais the full name of the class started. For instance like this:
基于shadit的回答。如果可以通过启动哪个类的 main 方法来识别每个作业,则可以使用包含sun.java.command
启动类的全名的系统属性。例如像这样:
log4j.appender.LOGFILE.File=${sun.java.command}.log
I use it together with a TimestampFileAppenderlike this:
我将它与TimestampFileAppender一起使用,如下所示:
log4j.appender.LOGFILE=TimestampFileAppender
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log
This way when I'm developing in Eclipse I get a new log file for each new process that I run, identified by the classname of the class with the main method and the time it was started.
这样,当我在 Eclipse 中进行开发时,我会为我运行的每个新进程获得一个新的日志文件,由该类的类名和 main 方法及其启动时间标识。