I'd like to override the logging level for a specific package.
It works when the level is more restrictive, but it does not work when the level is less restrictive.
Here is an example:
public class Main {
private static final java.util.logging.Logger JDK_LOGGER = java.util.logging.Logger.getLogger(Main.class.getName());
public static void main(String[] args) {
JDK_LOGGER.fine("Hello fine (jdk)...");
JDK_LOGGER.info("Hello info (jdk)...");
JDK_LOGGER.severe("Hello severe (jdk)...");
If the specified package has a more restrictive level, it works:
handlers = java.util.logging.ConsoleHandler
.level = FINE
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
com.ice.level = SEVERE
It prints:
août 19, 2019 10:44:25 PM com.ice.foo.Main main
GRAVE: Hello severe (jdk)...
But if the specified package has a less restrictive level, it does not work as what I was expecting:
handlers = java.util.logging.ConsoleHandler
.level = INFO
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
com.ice.level = FINE
It prints:
août 19, 2019 10:55:50 PM com.ice.foo.Main main
INFOS: Hello info (jdk)...
août 19, 2019 10:55:50 PM com.ice.foo.Main main
GRAVE: Hello severe (jdk)...
But, because FINE > INFO > SEVERE, I was expecting to see the 3 logs (fine, info and severe).
Where is my mistake?
Thx.
Your mistake is in not realizing that the package filter and the handler filter are applied independently, i.e. as-if they were AND'd.
The purpose of the ConsoleHandler.level filter is to reduce the console output, while allowing e.g. a file handler to log everything. It is mainly used when you are logging to both console and file at the same time.
As such, the handler level cannot be overridden.
The reason console output is usually filtered more than file output, is that console output is relatively expensive, performance-wise. You don't want large volume of output to the console, so finer-grained log messages are usually filtered out.
Related
I'm getting the exception when I try to connect to the orient db using Java. Below is the exception I'm getting.
Jun 07, 2016 12:43:40 PM com.orientechnologies.common.log.OLogManager log
INFO: OrientDB auto-config DISKCACHE=891MB (heap=891MB direct=891MB os=4,006MB), assuming maximum direct memory size equals to maximum JVM heap size
Jun 07, 2016 12:43:40 PM com.orientechnologies.common.log.OLogManager log
WARNING: MaxDirectMemorySize JVM option is not set or has invalid value, that may cause out of memory errors. Please set the -XX:MaxDirectMemorySize=4006m option when you start the JVM.
Jun 07, 2016 12:43:40 PM com.orientechnologies.common.log.OLogManager log
WARNING: MaxDirectMemorySize JVM option is not set or has invalid value, that may cause out of memory errors. Please set the -XX:MaxDirectMemorySize=4006m option when you start the JVM.
Exception in thread "main" com.orientechnologies.orient.core.exception.OFileLockedByAnotherProcessException: File 'F:\Program Files\orientdb-community-2.2.0\databases\mydbo\database.ocf' is locked by another process, maybe the database is in use by another process. Use the remote mode with a OrientDB server to allow multiple access to the same database at com.orientechnologies.orient.core.storage.fs.OFileClassic.lock(OFileClassic.java:756)
at com.orientechnologies.orient.core.storage.fs.OFileClassic.openChannel(OFileClassic.java:813)
at com.orientechnologies.orient.core.storage.fs.OFileClassic.open(OFileClassic.java:603)
at com.orientechnologies.orient.core.storage.impl.local.OSingleFileSegment.open(OSingleFileSegment.java:51)
at com.orientechnologies.orient.core.storage.impl.local.OStorageConfigurationSegment.load(OStorageConfigurationSegment.java:80)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.open(OAbstractPaginatedStorage.java:186)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.open(ODatabaseDocumentTx.java:231)
at orient.insert.Insert.main(Insert.java:12)
this is the code that i tried.
ODatabaseDocumentTx db = new ODatabaseDocumentTx("plocal:F:/Program Files/orientdb-community-2.2.0/databases/mydbo").open("admin", "admin");
ODocument doc = new ODocument("Person");
doc.field( "name", "Luke" );
doc.field( "surname", "Skywalker" );
doc.field( "city", new ODocument("City").field("name","Rome").field("country", "Italy") );
doc.save();
db.close();
I can't figure out the error I'm having.
You have a server running and you try to open the database from another process in plocal.
Could you please verify that you have no active OrientDB instances while accessing it in plocal (console or external processes) and that you open one plocal connection at a time?
I am using Payara 4.1 and Netbeans 8.1.
When I run my application, these four lines are among the first to be logged:
#!## LogManagerService.postConstruct : rootFolder=/opt/payara41/glassfish
#!## LogManagerService.postConstruct : templateDir=/opt/payara41/glassfish/lib/templates
#!## LogManagerService.postConstruct : src=/opt/payara41/glassfish/lib/templates/logging.properties
#!## LogManagerService.postConstruct : dest=/opt/payara41/glassfish/domains/domain1/config/logging.properties
I added the line org.springframework=WARNING at the end of the last logging.properties file given above, and restarted my server. That didn't seem to have an effect. When I open the asadmin shell /opt/payara41/bin/asadmin and run list-log-attributes, here is what I get:
asadmin> list-log-attributes
com.sun.enterprise.server.logging.GFFileHandler.excludeFields <>
com.sun.enterprise.server.logging.GFFileHandler.file <${com.sun.aas.instanceRoot}/logs/server.log>
com.sun.enterprise.server.logging.GFFileHandler.flushFrequency <1>
com.sun.enterprise.server.logging.GFFileHandler.formatter <com.sun.enterprise.server.logging.ODLLogFormatter>
com.sun.enterprise.server.logging.GFFileHandler.logtoConsole <false>
com.sun.enterprise.server.logging.GFFileHandler.maxHistoryFiles <0>
com.sun.enterprise.server.logging.GFFileHandler.multiLineMode <true>
com.sun.enterprise.server.logging.GFFileHandler.retainErrorsStasticsForHours <0>
com.sun.enterprise.server.logging.GFFileHandler.rotationLimitInBytes <2000000>
com.sun.enterprise.server.logging.GFFileHandler.rotationOnDateChange <false>
com.sun.enterprise.server.logging.GFFileHandler.rotationTimelimitInMinutes <0>
com.sun.enterprise.server.logging.SyslogHandler.useSystemLogging <false>
handlerServices <com.sun.enterprise.server.logging.GFFileHandler,com.sun.enterprise.server.logging.SyslogHandler>
handlers <java.util.logging.ConsoleHandler>
java.util.logging.ConsoleHandler.formatter <com.sun.enterprise.server.logging.UniformLogFormatter>
java.util.logging.FileHandler.count <1>
java.util.logging.FileHandler.formatter <java.util.logging.XMLFormatter>
java.util.logging.FileHandler.limit <50000>
java.util.logging.FileHandler.pattern <%h/java%u.log>
log4j.logger.org.hibernate.validator.util.Version <warn>
org.springframework <WARNING>
Command list-log-attributes executed successfully.
I have tried the suggestions given in this SO question but that didn't work. I'm stumped. :( I really do not want to see all those INFO logging lines printed by the spring framework.
=== EDIT ===
Here is what is in my log4j.properties (copied from SO):
# Define the root logger with appender file
log4j.rootLogger = DEBUG, stdout
# Define the file appender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Set the name of the logs destination
log4j.appender.stdout.target=System.out
# Set the immediate flush to true (default)
log4j.appender.stdout.ImmediateFlush=true
# Set the threshold to debug mode
log4j.appender.stdout.Threshold=debug
# Set the append to false, overwrite
log4j.appender.stdout.Append=false
# Define the layout for appender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.conversionPattern=%d{yyyy-MM-dd}:%m%n
log4j.logger.org.springframework=WARNING
Here are all the places I have copied that file to:
$PROJECT_DIR/src/log4j.properties
$PROJECT_DIR/src/main/resources/META-INF/log4j.properties
$PROJECT_DIR/src/main/webapp/WEB-INF/log4j.properties
$PROJECT_DIR/src/main/webapp/WEB-INF/classes/log4j.properties
$PROJECT_DIR/target/$PROJECT-1.0/WEB-INF/log4j.properties
$PROJECT_DIR/target/$PROJECT-1.0/WEB-INF/classes/log4j.properties
$PROJECT_DIR/target/$PROJECT-1.0/WEB-INF/classes/META-INF/log4j.properties
$PROJECT_DIR/target/classes/META-INF/log4j.properties
/opt/payara41/glassfish/domains/domain1/config/log4j.properties
In addition, I have added log4j.logger.org.springframework=WARNING and org.springframework=WARNING to Configurations > server-config > Logger Settings > Module Log Levels in the Payara UI. Nothing is working. Payara's server log still has INFO lines for the spring framework.
I tried everything that has been suggested so far, to no avail. So I ended up doing something pretty hacky. I wrote my own log handler and installed it to domain1/lib/ext:
package org.springsuppressor;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
public class MyHandler extends ConsoleHandler {
public MyHandler() {
super();
setLevel(Level.WARNING);
}
}
The handler above sets the log level for all loggers to WARNING. I could suppress messages for just the spring framework, but I don't yet need to do that.
I have used java util logging for my application. I noticed that certain properties such as the month name and even certain log levels are getting printed in German.
Dez 10, 2015 8:50:26 AM com.kube.common.HidCommunication readFromHidDevice
SCHWERWIEGEND: Time - Barcode Message read from the Device: 2015/12/10 08:50:26:992
Though I have specified the level as Level.SEVERE, why is it printing it as "SCHWERWIEGEND" in German? Please advice.
The first piece of code is doing almost exactly the same thing as the second one. But the hierarchal propagation of Log record is different. Can someone please explain why its happening. Thanks
Logger log1 = Logger.getLogger("Test1");
Logger log2 = Logger.getLogger("Test1.Test2");
Logger log3 = Logger.getLogger("Test1.Test2.Test3");
log2.setLevel(Level.WARNING);
log3.setLevel(Level.INFO);
log2.addHandler(new ConsoleHandler());
log3.addHandler(new ConsoleHandler());
log1.log(Level.INFO, "Message By: {0}",log1.getName());
log2.log(Level.INFO, "Message By: {0}",log2.getName());
log3.log(Level.INFO, "Message By: {0}",log3.getName());
OUTPUT: Nov 27, 2014 8:32:51 PM Test main
INFO: Message By: Test1
Nov 27, 2014 8:32:51 PM Test main
INFO: Message By: Test1.Test2.Test3
Nov 27, 2014 8:32:51 PM Test main
INFO: Message By: Test1.Test2.Test3
Nov 27, 2014 8:32:51 PM Test main
INFO: Message By: Test1.Test2.Test3
Logger logger = Logger.getLogger("d");
Logger logger1 = Logger.getLogger("d.1");
Logger logger1_2 = Logger.getLogger("d.1.2");
logger1 .setLevel(Level.WARNING);
logger1_2.setLevel(Level.INFO);
logger .info("msg:");
logger1 .info("msg: 1");
logger1_2 .info("msg: 1.2");
OUTPUT:
Nov 27, 2014 8:33:34 PM Test main
INFO: msg:
Nov 27, 2014 8:33:34 PM Test main
INFO: msg: 1.2
The lowest logger INFO message should not have propagated to the top as the middle one is set to Warning
That assumption is the source of your confusion. Record propergation is decsribed in the java.util.logging.Logger class documentation. Per the documentation:
By default, loggers also publish to their parent's Handlers, recursively up the tree.
The child logger is directly logging to the parent handler not the parent logger. So the level of the parent handler is what comes in to play not the level of the parent logger in this case.
I'm developing a Java application that uses java.util.logging for its logging needs. This application uses a multitude of external libraries (JDBC, JMS clients, JSR-160 implementation, etc), some of which also use java.util.logging.
I want to set the log level for my Loggers to ALL when I specify a flag on the command line, but so far I have only found ways to set the level for all loggers, not just mine.
My loggers are all called "com.mycompany.myapp.SomeClass" and when I set the level for "com.mycompany.myapp" to ALL, no extra information is logged. When I set the level for the root logger to ALL, all information for all loggers is logged to the console, which is way too much information!
How can I set my own loggers to ALL without having all those other loggers flood my logfiles?
Actually, I'm not sure why your having the problems you've described. I've created a simple JUnit test (below) and setting the log levels works exactly as I expect (which also seems inline with the way you expected them to work).
Are you trying to log messages with levels set below INFO in your custom logger? As you can see from the tests I've included, the default logging handler is set to INFO by default. You need to change that Handler's level to see FINE messages (also shown).
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Test;
public class SimpleLoggerTest {
private void logMessages(Logger logger) {
logger.warning(getLoggerName(logger) + ": warning message");
logger.info(getLoggerName(logger) + ": info message");
logger.fine(getLoggerName(logger) + ": fine message");
}
private String getLoggerName(Logger logger) {
String loggerName = logger.getName();
if (loggerName.isEmpty()) {
return "[root logger]";
}
return loggerName;
}
private void listHandlerLevels(Logger logger) {
for (Handler handler : logger.getHandlers()) {
logger.info(getLoggerName(logger) + ": handler level = " + handler.getLevel());
}
Logger parentLogger = logger.getParent();
if (null != parentLogger) {
for (Handler handler : parentLogger.getHandlers()) {
logger.info("parent logger handler (" + getLoggerName(parentLogger) + "): handler level = " + handler.getLevel());
}
}
}
private void setHandlerLevels(Logger logger, Level level) {
for (Handler handler : logger.getHandlers()) {
handler.setLevel(level);
}
Logger parentLogger = logger.getParent();
if (null != parentLogger) {
for (Handler handler : parentLogger.getHandlers()) {
handler.setLevel(level);
}
}
}
#Test
public void testLoggingLevel() {
Logger myLogger = Logger.getLogger(SimpleLoggerTest.class.getName());
Logger rootLogger = myLogger.getParent();
// list the default handler levels
listHandlerLevels(myLogger);
listHandlerLevels(rootLogger);
// log some messages
logMessages(myLogger);
logMessages(rootLogger);
// change the logger levels
myLogger.setLevel(Level.ALL);
rootLogger.setLevel(Level.WARNING);
// list the handler levels again
listHandlerLevels(myLogger);
listHandlerLevels(rootLogger);
// log some messages (again)
logMessages(myLogger);
logMessages(rootLogger);
// change Handler levels to FINE
setHandlerLevels(myLogger, Level.FINE);
// list the handler levels (last time)
listHandlerLevels(myLogger);
listHandlerLevels(rootLogger);
// log some messages (last time)
logMessages(myLogger);
logMessages(rootLogger);
}
}
Produces this output...
May 13, 2009 10:46:53 AM SimpleLoggerTest listHandlerLevels
INFO: parent logger handler ([root logger]): handler level = INFO
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
INFO: [root logger]: handler level = INFO
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
WARNING: SimpleLoggerTest: warning message
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
INFO: SimpleLoggerTest: info message
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
WARNING: [root logger]: warning message
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
INFO: [root logger]: info message
May 13, 2009 10:46:53 AM SimpleLoggerTest listHandlerLevels
INFO: parent logger handler ([root logger]): handler level = INFO
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
WARNING: SimpleLoggerTest: warning message
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
INFO: SimpleLoggerTest: info message
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
WARNING: [root logger]: warning message
May 13, 2009 10:46:53 AM SimpleLoggerTest listHandlerLevels
INFO: parent logger handler ([root logger]): handler level = FINE
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
WARNING: SimpleLoggerTest: warning message
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
INFO: SimpleLoggerTest: info message
May 13, 2009 10:46:53 AM SimpleLoggerTest logMessages
FINE: SimpleLoggerTest: fine message
May 13, 2009 10:46:53 AM java.util.logging.LogManager$RootLogger log
WARNING: [root logger]: warning message
This is what I was trying to convey in my other response.
Yeah, the JDK’s own logging framework can be a real bitch sometimes. As you correctly noticed the log levels of the root logger’s handlers are the problem. The solution you are proposing in your question is almost a good one:
Logger logger = Logger.getLogger("com.mycompany.myapp");
Handler handler = new ConsoleHandler(); /* or whatever you like. */
handler.setLevel(Level.ALL);
logger.addHandler(handler);
logger.setLevel(Level.ALL);
logger.setUseParentHandlers(false); /* <- important. */
When you create logger “below” that logger, i.e. with names like “com.mycompany.myapp.foo.Foo", they will log only to the logger you created. The parent logger of that logger (the root logger) will not get any log messages from your application but will receive messages from other parts of the JDK such as Swing or AWT.
Each Logger has a Handler with it's own log Level.
Is it possible that the Handler for your logger is not also set to ALL and is ignoring the messages? (This is messy, I know).
Here's a 2002 article on Java logging from O'Reilly.
Setting the property
com.mycompany.myapp.level = ALL
should do what you want.
But all the loggers will need to be named correcly with the relevant class names! E.g.
package com.mycompany.myapp;
public class MyClass{
private static Logger theLogger =
Logger.getLogger(MyClass.class.getName());
...
}
Another possible explanation is that your configurations aren't being passed correctly to the logging framework. Try feeding
LogManager.getLogManager().readConfiguration(InputStream);
your logging configuration right at startup. That is what I do and this works for me.