如何在log4j.xml文件中将主机名添加到日志文件?

13

我想将主机名和日期附加到日志文件名中。因此,日志文件名应该像app_hostname.date.log这样。 注意:这应该在Linux和Windows上均可运行。

<appender name="applog" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="${path}/app.log" />
        <param name="MaxFileSize" value="1MB" />
        <param name="DatePattern" value=".dd-MM-yyyy" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{dd-MM-yyyy HH:mm:ss}] [%-5p] %m%n"/>
        </layout>
</appender>

如何基于日志模式添加过滤器,而不是像 StringMatchFilter 那样。我想要匹配模式。

感谢您的提前帮助。

考虑使用 logbacklog4j2。从 logbackSiftingAppender 开始。 - Nati
@Nati,请更具体一些。如果可能的话,附上代码片段。 - Prasanna Kumar H A
8个回答

10

根据log4j2的文档,您可以进行环境变量查找,在类Unix系统中应该可以这样做:

<Property name="MYHOST">${env:HOSTNAME}</Property>
<Appenders>
  <File name="File1" fileName="${MYHOST}_file.log">
  ...
  </File>
</Appenders>

请注意,$HOSTNAME并非总是默认可用的,您可能需要在shell中显式地导出它,参见此文章


为了更新这个答案,最好使用{hostName},因为它默认情况下始终可用,而不像建议的答案那样。来自帖子https://dev59.com/PK_2oIgBc1ULPQZF66rV - Potion

6

6

首先在您的Java代码中执行以下操作,然后将log4j配置到应用程序中。

注意:在执行以下代码时需要处理或捕获必需的异常。

// step-1 : set hostName into System's property, which will use by log4j
System.setProperty("hostName", InetAddress.getLocalHost().getHostName()); 
//step - 2 : set currentDate into System's property, which will use by log4j
System.setProperty("currentDate", new SimpleDateFormat("dd-MMM-yyyy").format(new Date()));
//step - 3 : now configure/load log4j into Application , if it's not still loaded earlier then.
org.apache.log4j.Logger LOG = Logger.getLogger(YourJavaClassName.class); // ALERT : before this step above 2-step must needs to be execute, otherwise file-name won't appear as you required.

//LOG.debug("anything whatever programmer what to log");

更新:

如果您的应用程序是Web应用程序,则需要配置属性,即在tomcat-server启动之后以及任何application运行之前所需的属性。

为此,请创建一个类ApplicationConfiguration,其中实现了ServletContextListener接口,该接口可以在任何应用程序运行之前首先运行。

做同样的事情,

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ApplicationConfiguration implements ServletContextListener{

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {

        try {
            // step-1 : set hostName into System's property, which will use by log4j
            System.setProperty("hostName", InetAddress.getLocalHost().getHostName());
            //step - 2 : set currentDate into System's property, which will use by log4j
            System.setProperty("currentDate", new SimpleDateFormat("dd-MMM-yyyy").format(new Date()));
        } catch (UnknownHostException e) {
            System.out.println("Error Message : " + e.getMessage());
            //e.printStackTrace();
        } 


    }


}

请将您的log4j.xml文件设置为相同的方式,
<appender name="applog" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="${path}/app_${hostName}.${currentDate}.log" />
        <param name="MaxFileSize" value="1MB" />
        <param name="DatePattern" value=".dd-MM-yyyy" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{dd-MM-yyyy HH:mm:ss}] [%-5p] %m%n"/>
        </layout>
</appender>

请相应更新web.xml文件。
<web-app ...>
   <listener>
    <listener-class>
             com.pck1.ApplicationConfiguration
        </listener-class>
   </listener>
</web-app>

这个配置需要应用到web.xml中,因为应用程序在启动时,通过这个配置将像Context-listener一样跟随它。


更新2:

<logger name="packageName.AAA" additivity="false" >
    <level value="INFO" />
    <appender-ref ref="applog"/>
 </logger>

是的,它是一个Web应用程序...Tomcat是应用服务器。 - Prasanna Kumar H A
@Sam,请参考我的“已更新”部分。 - Vishal Gajera
@Sam,我建议创建一个名为ApplicationConfiguration的类,这样就不需要执行上述提到的设置主机名和当前日期的2个步骤,因为ApplicationConfiguration类本身已经处理了这些内容。 - Vishal Gajera
@Sam 不不不,这在我的电脑上是可以运行的,肯定是哪里出了问题,请按照我的建议检查并跟进。 - Vishal Gajera
@Sam,请查看我的更新答案,其中包括对web.xml文件的更新。 - Vishal Gajera
显示剩余21条评论

1
Cf.这个响应与类似问题,即使根据这个邮件列表线程,这是一个长期存在的请求,要满足这个请求也不是很明显。
使用最新版本的log4j,文档部分的结尾似乎已经可以使用属性来实现此功能。
无论如何,您总是可以使用专用模式布局(例如此处)自己解决它。

谢谢您的回答,但对我来说主要问题是我有两个关于同一程序包的日志,但如果它来自我的自定义类,则应写入一个日志,如果它来自其他类,则应写入另一个日志。 - Prasanna Kumar H A

1
以下配置可以解决问题。
<appender name="file" class="org.apache.log4j.RollingFileAppender">
        <param name="append" value="false" />
        <param name="maxFileSize" value="10MB" />
        <param name="maxBackupIndex" value="10" />
        <param name="file" value="C:\\Users\\kavurira\\Desktop\\log4j-${HostName}.log" />
        <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" 
            value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m${HostName}%n" />
        </layout>
    </appender>

Just set "HostName" as system property, before initialization of Log4j.

System.setProperty("HostName", InetAddress.getLocalHost().getHostName());

在哪里设置主机名(hostname)属性?我没有任何servlet(启动时加载)...? - Prasanna Kumar H A
不需要在启动时加载,必须有登录或项目的某些开始,对吧?您必须在执行以下行之前在项目中设置属性 Logger logger = Logger.getLogger("classname") - Rajesh Kumar
我尝试过……但在我的情况下,当应用程序启动时生成日志文件……因此它无法获取名称。 - Prasanna Kumar H A
请告诉我您正在使用哪个应用服务器? - Rajesh Kumar

1
你可以定义一个系统属性hostname并更改配置:
<param name="File" value="${path}/app_${hostname}.log" />

在log4j初始化之前,请确保设置系统属性。

如需添加过滤器,请参考按匹配模式过滤日志- log4j的答案。

更新: 编写不同日志的简单解决方案:

<logger name="com"><!-- for Class Package is com.???... -->
    <level value="INFO" />
    <appender-ref ref="applog" />
</logger>
<logger name="loggerForCustomClass">
    <level value="INFO" />
    <appender-ref ref="customlog" />
</logger>

修改程序中的代码:

//message will write to "customlog" appender
Logger.getLogger("loggerForCustomClass").info("log from custom class");

//message will write to "applog" appender
Logger.getLogger(getClass()).info("log from other class");

谢谢你的答案,但对我来说主要问题是我有两个针对同一软件包的日志,但如果它来自我的自定义类,则应写入一个日志,如果它来自其他类,则应写入另一个日志。 - Prasanna Kumar H A

0

log4j会在应用程序启动时加载,因此如何通过system.setProperty进行定义。 - Prasanna Kumar H A
你如何调用log4j,你有一个基类吗?如果有的话,你可以在那里设置属性。 - Sam
Log4j正在初始化,之后是Spring Boot。INFO:正在初始化Spring根Web应用程序上下文。log4j:WARN - Prasanna Kumar H A

0
尝试这个:"${env:HOST}-${date:yyyy-MM-dd}" 主机名 + 日期。在yaml中:
Properties:
    Property:
      - name: log-path
        value:  "logs"
      - name: filePattern
        value:  "${env:HOST}-${date:yyyy-MM-dd}"

  Appenders:

    Console:
      name: Console_Appender
      target: SYSTEM_OUT
      PatternLayout:
        pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"

    File:
      name: File_Appender
      fileName: "${log-path}/filelog-${filePattern}.log"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接