Changes to Log4j categories/loggers effect eachother
I have a logging problem with log4j. I am using the configureAndWatch to make log4j poll the following config occasionnaly and update what logging is done:
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Write logs to a file -->
<appender name="DEBUGGING" class="org.apache.log4j.RollingFileAppender">
...
</appender>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
...
</appender>
...
<category name="com.ourinternalpackage" additivity="false">
<priority value="DEBUG"/>
<appender-ref ref="CONSOLE"/>
</category>
<root>
<level value="DEBUG"/>
<appender-ref ref="CONSOLE"/>
</root>
</log4j:configuration>
This works well. Everything I expect ends up getting logged to console. Now I add (before the root element):
<category name="com.ourinternalpackage.somesubpackage.SomeClass" additivity="true">
<priority value="DEBUG"/>
<appender-ref ref="DEBUGGING"/>
</category>
Now, as expected, the log messages from SomeClass ends up in both the DEBUGGING log file and is logged to console. Great! However, when I change the priority of the category named "com.ourinternalpackage.somesubpackage.SomeClass" to OFF the logging to CONSOLE is also disabled. This is unexpected since the category named "com.ourinternalpackage" still has it's priority set to DEBUG and is logging to console. Other debug level messages, from classes in the com.ourinternalpackage, do end up in the console log. Additionally, if I remove the cate开发者_开发技巧gory with the appender-ref to DEBUGGING from the config file it keeps appending debug messages to the log.
Any ideas how to be able to toggle the logging on AND off for a specific category/logger without having to restart the application? In most cases the priority level for the category with name "com.ourinternalpackage" would be set to INFO. In which case I could set the priority of the category named "com.ourinternalpackage.somesubpackage.SomeClass" to INFO to reduce the ammount of logging done, but I would still be logging to both files. Which is something I'd like to avoid if possible.
Any ideas how to be able to toggle the logging on AND off for a specific category/logger without having to restart the application?
In the paragraph right before that, you said that you already did that by setting the priority to "OFF".
If I understand you correctly, then everything you described is expected log4j behavior. You should spend some time in the log4j manual to understand how loggers and appenders work. You seem to incorrectly expect that the same logger can be configured to have two different priorities/levels. That's not how it works. If you have specific questions other than that one that I quoted, ask them explicitly.
Update: Based on your update, you still need to read the log4j manual. (It's really short and easy to read.) You have a Logger named "com.ourinternalpackage.somesubpackage.SomeClass". There's only one of them, and whether you list it explicitly in the config file or not, it exists because somewhere your code calls or causes to be called Logger.getLogger(SomeClass.class)
.
Your one Logger can only have one priority. When you define <category name="com.ourinternalpackage.somesubpackage.SomeClass" ...
, its priority comes from there because it's an exact match to the Logger. If you don't define the exact match, then your Logger inherits its priority from its nearest ancestor, which is <category name="com.ourinternalpackage" ...
. Thus when you add the exact match and set it to "OFF", the expected (and exhibited) behavior is for all output of that Logger to be turned off.
So, still, the answer to your question is, "You're already doing it." That is, you're already toggling logging on and off for a specific Logger. It's just that you have an incorrect concept of what a Logger is. You think you have two Loggers when you only have one. One possible solution to your problem would be to actually create two Loggers. Then you can control them individually the way you're trying to. If you create one named "com.ourinternalpackage.somesubpackage.SomeClass" and one named "debug.com.ourinternalpackage.somesubpackage.SomeClass", then you've established a precedent for prefixing debug Loggers with "debug", and you can control your entire set of debug Loggers with one config entry: <category name="debug" ...
.
精彩评论