How to append hostname to log file in log4j.xml
Asked Answered
M

8

13

I want to append hostname and date to log file name.So log file Name should be like app_hostname.date.log. Note: This should run in both linux and 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>

And how to add filter based on the log pattern, not as StringMatchFilter.I want pattern to be matched. Thanks in advance

Multicellular answered 23/3, 2016 at 6:10 Comment(2)
consider using logback or log4j2. start wtih logback's SiftingAppenderPriapus
@Nati,Please be more specific..If possible with code snippetMulticellular
A
6

Do this first from your java code then configure log4j into application,

NOTE : handle or catch required Exception while below code execute.

// 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");

UPDATED :

If your application is web-application, then need to configure property which we want here aftertomcat-server start and before any application run,

for that create one class ApplicationConfiguration which has ServletContextListener interface implemented which helps here to run first before any application runs.

do likewise,

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();
        } 


    }


}

......

Set your log4j.xml file likewise,

<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>

please, update web.xml file accordingly,

<web-app ...>
   <listener>
    <listener-class>
             com.pck1.ApplicationConfiguration
        </listener-class>
   </listener>
</web-app>

This configuration need to apply into web.xml because application when start, by this configuration it will follow it like Context-listener.


UPDATE 2 :

<logger name="packageName.AAA" additivity="false" >
    <level value="INFO" />
    <appender-ref ref="applog"/>
 </logger>
Avowal answered 28/3, 2016 at 9:28 Comment(26)
actually log4j getting called when the application starts.Multicellular
@Sam your application is web-application ?Avowal
Yes it is a web app...tomcat is app serverMulticellular
@Sam refer my 'UPDATED' sectionAvowal
@Sam once class ApplicationConfiguration(what i suggest) created then no need to put above mentioned 2-steps for set hostname and currentDate because it's handled by ApplicationConfiguration - class itself.Avowal
@Sam my suggested answer, works or not ? do i need to provide more information to make you success. let me knowAvowal
@Vishal..Thank you for your efforts..but its not worked..Do i need to add this in web.xml or something?Multicellular
@Sam no no it's works on my machine, something went wrong please check and follow as i suggest..Avowal
"LogName_." this is what am getting...Actually i placed a breakpoint in that class and started tomcat but it's not at all came to that place.Multicellular
"LogName_" log file name ?Avowal
I Mean values are not replacing...Empty value for hostname because control is not going to that classMulticellular
Let us continue this discussion in chat.Avowal
@Sam please see my update answer which include update into web.xml fileAvowal
Wow! done...answer for one more..get bounty...I am logging two logs from same package..but particularly from one class I want to write for seperate log..how to have filter for that oneMulticellular
@Sam please post another question.Avowal
Actually i have asked that in this one onlyMulticellular
@Sam okay, let me check. because this thing wasn't in my mindAvowal
@Sam what is name for second class's log-file ?Avowal
1st one package..second one AAAMulticellular
@Sam can you please check my UPDATE 2 section .Avowal
<logger name="a.b.c(package)"> <priority value="ALL" /> <appender-ref ref="file1" /> </logger> <logger name="class(a.b.c.class)"> <level value="info" /> <appender-ref ref="file2" /> </logger>Multicellular
Both should be independentMulticellular
No..if i try to write for a.b.c.class its writing to file1 also...that should not happenMulticellular
How can I Differ that??Multicellular
by putting 2-logger for 2-appender with proper 'ref' pass.Avowal
filter has not solved..but still m giving bounty for your efforts..thank you...if you come to know please update the answerMulticellular
P
10

Following the log4j2 documentation you can do environment variable lookups, so in Unix-like systems this should work:

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

Beware that $HOSTNAME is not always available by default and you might need to export it explicitly in the shell, see this post.

Pacemaker answered 14/9, 2016 at 0:39 Comment(1)
To update this answer, it is better to use {hostName} as it is always available by default unlike the suggested answer. From post #70531172Duralumin
A
6

Do this first from your java code then configure log4j into application,

NOTE : handle or catch required Exception while below code execute.

// 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");

UPDATED :

If your application is web-application, then need to configure property which we want here aftertomcat-server start and before any application run,

for that create one class ApplicationConfiguration which has ServletContextListener interface implemented which helps here to run first before any application runs.

do likewise,

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();
        } 


    }


}

......

Set your log4j.xml file likewise,

<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>

please, update web.xml file accordingly,

<web-app ...>
   <listener>
    <listener-class>
             com.pck1.ApplicationConfiguration
        </listener-class>
   </listener>
</web-app>

This configuration need to apply into web.xml because application when start, by this configuration it will follow it like Context-listener.


UPDATE 2 :

<logger name="packageName.AAA" additivity="false" >
    <level value="INFO" />
    <appender-ref ref="applog"/>
 </logger>
Avowal answered 28/3, 2016 at 9:28 Comment(26)
actually log4j getting called when the application starts.Multicellular
@Sam your application is web-application ?Avowal
Yes it is a web app...tomcat is app serverMulticellular
@Sam refer my 'UPDATED' sectionAvowal
@Sam once class ApplicationConfiguration(what i suggest) created then no need to put above mentioned 2-steps for set hostname and currentDate because it's handled by ApplicationConfiguration - class itself.Avowal
@Sam my suggested answer, works or not ? do i need to provide more information to make you success. let me knowAvowal
@Vishal..Thank you for your efforts..but its not worked..Do i need to add this in web.xml or something?Multicellular
@Sam no no it's works on my machine, something went wrong please check and follow as i suggest..Avowal
"LogName_." this is what am getting...Actually i placed a breakpoint in that class and started tomcat but it's not at all came to that place.Multicellular
"LogName_" log file name ?Avowal
I Mean values are not replacing...Empty value for hostname because control is not going to that classMulticellular
Let us continue this discussion in chat.Avowal
@Sam please see my update answer which include update into web.xml fileAvowal
Wow! done...answer for one more..get bounty...I am logging two logs from same package..but particularly from one class I want to write for seperate log..how to have filter for that oneMulticellular
@Sam please post another question.Avowal
Actually i have asked that in this one onlyMulticellular
@Sam okay, let me check. because this thing wasn't in my mindAvowal
@Sam what is name for second class's log-file ?Avowal
1st one package..second one AAAMulticellular
@Sam can you please check my UPDATE 2 section .Avowal
<logger name="a.b.c(package)"> <priority value="ALL" /> <appender-ref ref="file1" /> </logger> <logger name="class(a.b.c.class)"> <level value="info" /> <appender-ref ref="file2" /> </logger>Multicellular
Both should be independentMulticellular
No..if i try to write for a.b.c.class its writing to file1 also...that should not happenMulticellular
How can I Differ that??Multicellular
by putting 2-logger for 2-appender with proper 'ref' pass.Avowal
filter has not solved..but still m giving bounty for your efforts..thank you...if you come to know please update the answerMulticellular
C
6

I found that just ${hostName} by default would work for latest log4j

Something like this:

    <File name="file" fileName="${baseDir}/${hostName}-file.log" append="true">

This is documented under here: https://logging.apache.org/log4j/2.x/manual/configuration.html#AutomaticConfiguration

In the Default Properites Section:

The default map is pre-populated with a value for "hostName" that is the current system's host name or IP address

Congdon answered 17/6, 2021 at 9:18 Comment(0)
H
1

Cf. this response to a similar question, the request wouldn't be obvious to satisfy, even if according to this mailing-list thread, this is a long-standing request.

Using a recent version of log4j, the end of this documentation section seems you already have the feature available using properties.

Anyway, you always have the solution to do it yourself with a specialized pattern layout, like here.

Hae answered 25/3, 2016 at 13:44 Comment(1)
thanks for the answer, but for me main problem is I have two logs for the same package,but if it comes from my custom class it should write to one log, if it comes from other than that class it should write to another.Multicellular
E
1

You can defined a system property hostname and change the configuration:

<param name="File" value="${path}/app_${hostname}.log" />

Make sure the system property is set before log4j initialization.

For adding filter, please refer the answer of Filter log by matching pattern - log4j

UPDATED: A simple solution for writing different log:

<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>

Change code in your program:

//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");
Estebanesteem answered 25/3, 2016 at 14:0 Comment(1)
thanks for the answer, but for me main problem is I have two logs for the same package,but if it comes from my custom class it should write to one log, if it comes from other than that class it should write to another.Multicellular
M
1

Following configuration will do the trick

<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());
Mutz answered 25/3, 2016 at 15:29 Comment(4)
where to set the hostname property, i dont have any servlet(load on start up)...?Multicellular
No need of load on start up, there must be login or some starting of your project right? You have to set the property in your project, before executing the following line in your project Logger logger = Logger.getLogger("classname")Mutz
I tried...but in my case log files are generating when the application starts..so its not taking the nameMulticellular
Let me know which application server are you using ?Mutz
A
0

Write you own custom appender extending the basic appenderws. This will help you to manipulate the properties in java.

See This answer https://mcmap.net/q/298605/-configure-log4j-to-log-to-custom-file-at-runtime

Or Simply set the command line arguments & system property like this answer

https://mcmap.net/q/298605/-configure-log4j-to-log-to-custom-file-at-runtime

Autogamy answered 28/3, 2016 at 7:47 Comment(3)
log4j will load on application start up,so how to define by system.setPropertyMulticellular
How do you call log4j , do you have a base class ? If so you can set the property thereAutogamy
Log4j is initializing on after spring boot.INFO: Initializing Spring root WebApplicationContext log4j:WARNMulticellular
H
0

try this : "${env:HOST}-${date:yyyy-MM-dd}" Hostname + Date . In 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"
Horror answered 7/5, 2020 at 23:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.