How to get other than root logger from SLF4J using Log4J

21,143

Solution 1

I have seen that this is getting root logger by default

No it is not.

Assume FQN of Name is foo.bar.Name), when you call private final Logger logger = LoggerFactory.getLogger(Name.class); , you are getting a logger with name foo.bar.Name, for which inherits from foo.bar, for which inherits from foo, for which inherits from root.

You can get the root logger in SLF4J by LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)

Loggers are hierarchical. Child level logger inherits configurations from its parent (including appenders, level etc). I believe you were confused about "getting a child logger which inherited config from ROOT logger" and "getting the ROOT logger"

2.How can i get other loggers which are defined in log4j.xml file?

For example, if you want to get logger com.example.foo, it is simply by private final Logger logger = LoggerFactory.getLogger("com.example.foo");

As mentioned above, loggers are hierarchical. If you get the logger "com.example.foo.Bar", given there are no specific setting for "com.example.foo.Bar", its behaviour should be the same as using "com.example.foo" (except the logger name being show in log of course).

As it is a common practice to use the class name itself as the logger name, SLF4J also provide a method to get logger by providing a class (as what you do in your question), by Logger logger = LoggerFactory.getLogger(Bar.class);. This make it more refactoring-friendly. In this case, the logger name got will be the same as the FQN of the class provided ("com.example.foo.Bar")

Solution 2

1.How this is getting root logger

Loggers build a hierarchy, as you can see from the tables here: http://logging.apache.org/log4j/2.x/manual/architecture.html

2.How can i get other loggers which are defined in log4j.xml file?

If you want strictly what's defined there, than you have to parse and read that config file. If you need all the active loggers and their configuration at runtime, than there's API for it. E.g. an article how to do it: http://nelz.net/2008/04/08/log4j-runtime-configuration/

Also,I havent found any good tutorial on slf4J.If you have some good links

slf4j has quite a few docs: http://www.slf4j.org/docs.html but since it's just a wrapper, log4j does the "work" so here's a book about it: http://www.qos.ch/shop/products/log4jManual

Share:
21,143
beinghuman
Author by

beinghuman

Updated on January 22, 2021

Comments

  • beinghuman
    beinghuman over 3 years

    I am learning Slf4j and log4j in Spring.I have seen that eyerywhere we are using one line

    private final Logger logger = LoggerFactory.getLogger(name.class);
    

    I have seen that this is getting root logger by default.

    1. How this is getting root logger?Am I wrong?

    2. How can i get other loggers which are defined in log4j.xml file?

    This is my configuration:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE log4j:configuration PUBLIC
      "-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
        debug="false">
    
        <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="[%d{dd/MM/yy hh:mm:ss:sss z}] %5p %c{2}: %m%n" />
            </layout>
        </appender>
    
        <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="FILE" />
        </appender>
    
        <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
    
            <param name="File" value="C:/log/spring-hib.log" />
            <param name="MaxBackupIndex" value="100" />
    
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="[%d{dd/MM/yy hh:mm:ss:sss z}] %5p %c{2}: %m%n" />
            </layout>
    
    
        </appender>
    
      <logger name="com.example.foo">
      <level value="DEBUG"/>
      <appender-ref ref="FooLogFile"/>
     </logger>
    
    
    
        <category name="org.hibernate">
            <priority value="DEBUG" />
        </category>
    
        <category name="java.sql">
            <priority value="debug" />
        </category>
    
        <root>
            <priority value="INFO" />
            <appender-ref ref="ASYNC" />
        </root>
    
    </log4j:configuration>
    
  • beinghuman
    beinghuman over 10 years
    "which make it more refactoring-friendly. In this case, the logger name got will be the same as the FQN of the provided class ("com.example.foo.Bar" in this case)" .I didn't get last line..
  • Adrian Shum
    Adrian Shum over 10 years
    What I mean is,if FQN of Foo is com.example.foo.Bar, then when you get logger by ...getLogger(Bar.class) (Oh typo in my original answer, will fix that), the name of the returned logger will be "com.example.foo.Bar". For the statement of "refactoring-friendly": One difference of passing in the FQN as string vs as Class object to get the logger is, if class or package is renamed, you will still get the correct logger in latter case.
  • WillBD
    WillBD over 10 years
    This helped me a bunch, thanks so much for this detailed answer. +1