175

I use log4j and would like to route the output of certain Loggers to specific files.

I already have multiple appenders in place. Now, to make debugging easier, I want to tell log4j that the output generated by a specific class (e.g. foo.bar.Baz) should be written to a specific log file.

Can this be done?

gubrutz
  • 1,753
  • 2
  • 11
  • 4

3 Answers3

214

An example:

log4j.rootLogger=ERROR, logfile

log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.datePattern='-'dd'.log'
log4j.appender.logfile.File=log/radius-prod.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%-6r %d{ISO8601} %-5p %40.40c %x - %m\n

log4j.logger.foo.bar.Baz=DEBUG, myappender
log4j.additivity.foo.bar.Baz=false

log4j.appender.myappender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.myappender.datePattern='-'dd'.log'
log4j.appender.myappender.File=log/access-ext-dmz-prod.log
log4j.appender.myappender.layout=org.apache.log4j.PatternLayout
log4j.appender.myappender.layout.ConversionPattern=%-6r %d{ISO8601} %-5p %40.40c %x - %m\n
Maurice Perry
  • 32,610
  • 9
  • 70
  • 97
  • 22
    ahh - that simple! Thanks! Does the log4j.additivity.foo.bar.Baz=false setting enforce that the output of Baz will not show up in the rootLogger's appender? – gubrutz May 04 '10 at 08:25
  • 3
    what version of log4J is this for? I'm trying to find the xml configuration to do the same thing for log4j version 1.2.17 – A.C May 30 '14 at 15:37
  • 1
    @RodrigoGurgel yes, nothing unusual there – Maurice Perry Apr 01 '15 at 07:16
  • Can you explain what the `additivity` is for? – dwjohnston May 25 '15 at 03:35
  • 5
    @dwjohnston setting additivity to false will prevent the logger from logging to the appenders of it's ancestors (it's true by default), In this case, had the additivity been left to true, logging to the Baz appender would have written to both files. – Maurice Perry May 25 '15 at 16:36
  • Is there another way to achive this? Can defining a custom appender to filter classes or packages? – Leo Lee Dec 25 '15 at 08:27
  • @LeoLee What are you trying to do? defining a custom appender is not enough; you would still need to provide à log4j configuration in one way or another. – Maurice Perry Dec 25 '15 at 21:00
  • 1
    any thoughts on the xml config? – Igor Donin Jan 13 '16 at 17:04
  • 2
    See my answer below for the XML config, I was looking for this today... – mikeb Jun 26 '16 at 15:29
  • Does this logic work if I want to redirect logs for all objects in a namespace, not just a class? For instance, all classes under `foo.bar` should log to `myAppender` – AbhinavChoudhury Apr 15 '20 at 17:25
  • @A.C I could get this to work with 1.2.17 – somshivam Feb 25 '21 at 08:55
22

Here's an answer regarding the XML configuration, note that if you don't give the file appender a ConversionPattern it will create 0 byte file and not write anything:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
        </layout>
    </appender>

    <appender name="bdfile" class="org.apache.log4j.RollingFileAppender">
        <param name="append" value="false"/>
        <param name="maxFileSize" value="1GB"/>
        <param name="maxBackupIndex" value="2"/>
        <param name="file" value="/tmp/bd.log"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
        </layout>
    </appender>

    <logger name="com.example.mypackage" additivity="false">
        <level value="debug"/>
        <appender-ref ref="bdfile"/>
    </logger>

    <root>
        <priority value="info"/>
        <appender-ref ref="bdfile"/>
        <appender-ref ref="console"/>
    </root>

</log4j:configuration>
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
mikeb
  • 10,578
  • 7
  • 62
  • 120
  • 4
    it is critical to remove `` from `` - otherwise you will see your whole log copied to this file as well. – sab Dec 24 '16 at 16:57
  • how to configure this for default pacakge or for specific class without package? – Prasad Jadhav Mar 10 '17 at 05:18
  • It's the `...` element. Specify the class or package as the name and the appender as the file appender. – mikeb Mar 10 '17 at 13:38
1

Here is an example for logging details into separate files, rollout file for every month and delete logs older than 180 days:

#property settings
property.LOG_DIR = /opt/logs/app_name/

#Console appenders
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yy/MM/dd HH:mm:ss.SSS} %p %c{1}: %m%n

#root loggers
rootLogger.level = INFO
rootLogger.appenderRef.stdout.ref = STDOUT
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.files.ref = Rolling

# Rolling file appender
appender.rolling.type = RollingFile
appender.rolling.name = Rolling
appender.rolling.fileName= ${LOG_DIR}/application.log
appender.rolling.filePattern= ${logFile}.%i
appender.rolling.layout.type=PatternLayout
appender.rolling.layout.pattern=%d{yy/MM/dd HH:mm:ss.SSS} %p %c{1}: %m%n
appender.rolling.policies.type=Policies
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.policies.size.size=50MB
appender.rolling.strategy.max=20

#custom logging for audit-viewer
logger.aduit.name = auditlogger
logger.aduit.level = info
logger.aduit.appenderRefs = auditRef
logger.aduit.appenderRef.auditRef.ref = AuditAppender
logger.aduit.additivity = false

# Logging audit details to dedicated file
appender.aduitfile.type = RollingFile
appender.aduitfile.fileName = ${AUDIT_FILE}
appender.aduitfile.filePattern= ${LOG_DIR}/audit.%d{yyyy-MM}.log
appender.aduitfile.name = AuditAppender
appender.aduitfile.layout.type = PatternLayout
appender.aduitfile.layout.pattern = %d{yy/MM/dd HH:mm:ss.SSS} %p %c{1}: %m%n
appender.aduitfile.policies.type = Policies
appender.aduitfile.policies.time.type =TimeBasedTriggeringPolicy
appender.aduitfile.strategy.type = DefaultRolloverStrategy
#Rollout files based on month
appender.aduitfile.policies.time.interval=1
appender.aduitfile.policies.time.modulate= true
appender.aduitfile.ImmediateFlush=true
appender.aduitfile.append=true
appender.aduitfile.strategy.action.type = Delete
appender.aduitfile.strategy.action.basepath = ${LOG_DIR}
appender.aduitfile.strategy.action.maxdepth = 1
appender.aduitfile.strategy.action.PathConditions.type = IfFileName
#This below field uses relative path from basepath
appender.aduitfile.strategy.action.PathConditions.glob = audit.*.log
appender.aduitfile.strategy.action.condition.type = IfLastModified
appender.aduitfile.strategy.action.condition.age = P180D


# Settings to quiet third party or custom logs that are too verbose
loggers = mongodb, aduit

logger.mongodb.name=org.mongodb.driver.cluster
logger.mongodb.level=ERROR

Here if you wish to have logs from some class into separate file, like auditlogger then use it inside a class as follows:

  private val logger = LogManager.getLogger("auditlogger") //dont change this appender ref
  logger.info("Find me inside 'audit.log' file")
Puneeth Reddy V
  • 1,538
  • 13
  • 28