68

I read some articles about how to use log4j. Most of them give below code as a beginning:

 Logger logger = Logger.getLogger("com.foo.Bar");

or

 Logger logger = Logger.getLogger(XXX.class);

This will initialize the logger object.But my question is why need send the class type as a parameter? It seems when I use the logger, I don't care in which class I use it.So the Class type seems no effect to logger. If I declare a logger as static and public, I can call this logger at another class, So what's the intention of the author to design it like this? Will the Class type bind something when I use the logger? Or I can send any Class types to the getLogger function.

shmosel
  • 49,289
  • 6
  • 73
  • 138
roast_soul
  • 3,554
  • 7
  • 36
  • 73

8 Answers8

64
  1. You can always use any string as logger name other than class type. It's definitely ok.

  2. The reason why many people use class type, I guess:

    • Easy to use. You don't need to worry about logger name duplication in a complex Java EE application. If other people also use your logger name, you may have a log file including no only the output of your class;

    • Easy to check the logging class, as the logger name will show in the log file. You can quickly navigate to the specific class;

    • When you distribute you class, people may want to redirect the logging from your class to a specific file or somewhere else. In such case, if you use a special logger name, we may need to check the source code or imposssible to do that if souce is unavailable.

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Jintian DENG
  • 3,152
  • 20
  • 22
  • No, not ANY STRING. I write this in a jsp: Logger.getLogger("fp_check_power.jsp") and log.debug("..."). However, in the log file it only shows:"[2017/07/12 16:13:21, DEBUG] (jsp) : open url = ....". – Scott Chu Jul 12 '17 at 08:16
  • I have the same problem, did you find a solution to it? – Salocin Nov 13 '17 at 13:51
  • including no only --- i don't understand the sentence, could you explain? – Lei Yang Feb 19 '20 at 08:53
  • @LeiYang - I think it's meant to read "you may have a log file including **not** [just] the output of you class". Meaning there could be output from other classes. – Kosi Jan 14 '22 at 17:08
9

From the javadoc: Logger.getLogger(Class) is a shorthand for getLogger(clazz.getName()). A convention used with log4j and other logging frameworks is to define a static logger per class. For example,

public class SomeClass {
    private static final Logger LOG = Logger.getLogger(SomeClass.class);
    ...
}

I have found this convention to work well for organizing logging output. It's certainly not required but is a useful practice.

John McCarthy
  • 5,752
  • 2
  • 29
  • 40
  • Looks like Logger.getLogger(blah) creates one logger per class, rather than one logger per instance of a class. (I checked by getting logger two times for same class. logger1 == logger2 was true). Why doesn't it create a logger per instance ? – MasterJoe Aug 06 '18 at 00:43
  • @testerjoe2 log4j manages the logger instances so that any two logger names (or classes in this case) result in the same instance. The practice of create a static logger instance per class is fairly well established. What are you trying to accomplish with multiple instances? – John McCarthy Aug 13 '18 at 23:15
  • I don't need to use multiple instances of logger for the same class. I only want to understand why we prefer to use one instance. – MasterJoe Aug 15 '18 at 00:29
  • @testerjoe2 understood. I think it's just the way the API the organized. Logger instances are managed by name. – John McCarthy Aug 15 '18 at 14:29
7

1:you can use "class name" or "string name" when you define in log4j.properties before, such as

log4j.logger.anything=INFO,anything

so,you can record your log as

 Logger logger = Logger.getLogger("anything");

2:If you define some log name,you can check it easily,cus they are separate.

Liubey
  • 71
  • 1
  • 1
1

You can trace your log by class type.

example1:

public class Bar {
    Logger logger = Logger.getLogger("com.foo.Bar");
    ...
    logger.debug("debug message");
}

Maybe you can see below a log message.

DEBUG: **com.foo.Bar** debug message

example2:

public class Foo {
    Logger logger = Logger.getLogger("com.foo.Foo");
    ...
    logger.debug("debug message");
}

Maybe you can see below a log message.

DEBUG: **com.foo.Foo** debug message

If you have a lot of java class and logger message, It's too difficult to find where log messages are from.

Oh Jong Am
  • 136
  • 8
1

It can depend on a specific logging library, but usually it's more than a name. It signifies logger's hierarchy. When you configure your logger, you would usually pass both Log Level and Logger name, like this:

<logger name="org.hibernate" level="ALL"/>

This attribute is not just name, it attribute means a hierarchy. And if instead you would write something like:

<logger name="org" level="ALL"/>

not only hibernate, but everything that is in org package will be impacted. On the other hand, if you write something like:

<logger name="org.hibernate.validator" level="ALL"/>

it will only concern hibernate validation package, and not the rest of Hibernate.

By the way, if you don't want to specify a concrete class for every factory, you can use something like(Kotlin):

val logger: Logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass())
yuranos
  • 8,799
  • 9
  • 56
  • 65
0

XXX.class is to Name your Logger i.e to flag subsequent log statements . To give you an idea which class certain log statements belongs to / originated from.

TheWhiteRabbit
  • 15,480
  • 4
  • 33
  • 57
0

Logger with class name is not mandatory, you can use your own message. It is convention to use:

Logger logger = Logger.getLogger(XXX.class) 

and is useful to debug. It will log which line of code is executed.

Popo
  • 2,402
  • 5
  • 33
  • 55
Farhad
  • 1
  • 2
0

Try to use getName() method.

private static final Logger log = LogManager.getLogger(JwtAuthenticationFilter.class.getName());
Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73