How can I disable logging for a certain library? [duplicate] - java

I am using Apache Commons Logging ™. For now I wanted to use SimpleLog implementation, but when I changed the level, loggers from the libraries came out. I want it to turn them off.
Is there a easy way to change log level for whole package (can Log4j do that)?
I have tried to set
org.apache.commons.logging.simplelog.log.foo=fatal
in the property files to disable (setting to fatal is OK) foo logger, but it doesn't work (foo is a name of logger that appears in output : [INFO] foo - Message).

In Log4j you can specify a logging level for specified package, class or logger identified by string. You just simply write this in log4j.properties file:
log4j.logger.<your package> = DEBUG|INFO|OFF|WARN...

You should use:
log4j.logger.foo = OFF
Please note that "foo" does not need to be a package, or a class, but is an arbitrary String. We e.g. have a logger named "SQL" that is called from many classes.

If you use Spring Boot, you may set to OFF in application.properties file, by using logging.level.<package-or-class-name>=OFF Example:
logging.level.org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer=OFF
Reference:
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging.log-levels

Use of SimpleLog from Commons Logging requires two configuration files unless you are using some system properties. The files are: commons-logging.properties and simplelog.properties.
The log level properties you have indicated should be placed in simplelog.properties like:
org.apache.commons.logging.simplelog.log.foo=warn
where "foo" is the logger name. Generally, this is the package or package and class name. In the following example, everything under the com.stackoverflow.utils package is set to info whereas com.stackoverflow.servlet.Dispatcher is specifically set to warn:
org.apache.commons.logging.simplelog.log.com.stackoverflow.utils=info
org.apache.commons.logging.simplelog.log.com.stackoverflow.servlet.Dispatcher=warn
The commons-logging.properties file should contain:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
Documentation here and here.

Related

How to set different log levels in Eclipse Scout framework?

I'm having some trouble configuring proper logging in Eclipse Scout framework. My claims aren't that high as I only want to be able to set different log levels for different parts of my program in a configuration/properties/XML file.
The logging configuration in the config.ini of my Scout server plugin currently looks like this:
eclipse.consoleLog=true
org.eclipse.scout.log=eclipse
org.eclipse.scout.log.level=INFO
So as you can see this is the default logging configuration using Eclipse logging. It works fine for logging at a global level. The only thing I would like to do is to write something like this to set the different log levels:
packagename.ClassName=LOGLEVEL
As this is a very basic logging use case I think there must be some easy way to do this in Scout. Otherwise I would appreciate some help how to configure log4j, JUL or others for the use with Scout. The Eclipse Scout Wiki hasn't helped me so far. I created the example logger fragment to the host plugin 'org.eclipse.scout.commons' and removed the logging configuration lines from my config.ini but nothing happens. I'm also not sure where to put the log4j.poperties or how this is done otherwise.
I'm a bit ashamed for being unable to figure out such a basic problem, but would be very happy about some quick help.
I can tell you how to configure the logging if you choose the java logger (config.ini: org.eclipse.scout.log=java).
For the eclipse logger, I barely found any information at all.
Now, to configure the java (JUL) logging: You can do this in a file called logging.properties.
You can configure the logging by specifying the configuration file in your product:
Create your configuration file - say logging.properties inside the folder where your product file (for server or client respectively) is located. Typically this is in a folder named 'products'.
Open your product file and go to the "Launching" tab and specify your logging configuration file in the "VM Arguments" tab. Use the "java.util.logging.config.file" system property to do so:
-Djava.util.logging.config.file="${resource_loc:/com.yourapp.server/products/logging.properties}"
Now, you should be able to specify the log levels in your new logging.properties file:
### Root level of your application, all below are ignored
.level=INFO
### Handlers
handlers=java.util.logging.ConsoleHandler
### Handler properties
java.util.logging.ConsoleHandler.level=FINEST
### Override the logging level for certain classes
com.yourapp.server.SomeService.level=FINE
Alternatively, you can also use a class to initialize the logging with the java.util.logging.config.class option. See this wiki page for a detailed example.
Also, when building a WAR file, you might be interested in this answer.

How to use multiple configuration files for Log4j2?

I am writing Java code that tests a Java library. The library includes its own Log4j2 configuration as part of the distribution.
I would like to use Log4j2 in my test code without modifying the library's configuration.
Is there a way to have a separate Log4j2 configuration for my test code?
This is all running as command-line Java, no servers or web involvement at all.
EDIT
What I want is to be able to configure loggers, appenders, etc for the test code to use, and at the same time have the library code use its own separate configuration file for its logging.
The idea is to use Log4j2 in my test code, but without having to change the library's configuration file. Since the library configuration file is part of the library's distribution, I don't want to change it for testing.
This may be helpful:
Log4j2 will first look for log4j2-test.xml in the classpath
if that file is not found, it will look for log4j2.xml in the classpath
So one option is to copy the library's configuration (log4j2.xml) to log4j2-test.xml and add your own configuration to log4j2-test.xml.
Furthermore, Log4j2 supports XInclude in XML configuration, so you could use that feature to avoid duplicating the library's configuration in your log4j2-test.xml.
Log4j2 supports "Composite Configuration" which exactly matches your requirement. All you need to do is provide path to multiple files in log4j.configurationFile property. This can be passed from command line or added to log4j2.component.properties file in your application.
References
https://logging.apache.org/log4j/2.x/manual/configuration.html#CompositeConfiguration
https://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties
There are two step you can try to solve for your issue
Create your own configuration file with your custom name(eg: xyz.properties/.xml)
You must add the following line to your java runtime command
cmd> java -Dlog4j.configuration=location/xyz.properties
If you use diffent name for configuration rather log4j.properties/.xml file you need to configure that file at runtime by above command for more info have a look here..
Correct format for using an alternate XML file to log4j2.xml:
java -Dlog4j.configurationFile=./location/log4j2-custom.xml
Assuming ./location/log4j2-custom.xml exists and is the new XML to replace log4j2.xml in this run
See:
https://github.com/kamalcph/Log4j2Examples/blob/master/src/main/java/in/co/nmsworks/log4j2/examples/CompositeConfigurationExample.java
Referencing https://logging.apache.org/log4j/2.x/manual/configuration.html states that you can add multiple comma separated files under log4j2.configurationFile property.
To use multiple configuration files, depending on the environment you must set the.
for example:
if (env.equals("DEV")) {
setConfigFile("log4j2-dev.xml");
}
public static void setConfigFile(String logConfigFile) {
File file = new File(logConfigFile);
LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
context.setConfigLocation(file.toURI());
}
first configure application.yaml file
spring:
profiles:
active: dev
---
spring:
message: running in the dev profile //just to output the message in the log
profiles: dev
logging.config: classpath:log4j2-dev.xml
---
spring:
profiles: prod
logging.config: classpath:log4j2-prod.xml
and create these similar files in your classpath
* log4j2-dev.xml
* log4j2-prod.xml

How can I determine what log configuration source Logback actually used?

log4j has a property, log4j.debug, which will helpfully provide the user with an indication of which configuration file was actually used to configure the logging system.
I haven't been able to find anything equivalent with the (otherwise superior) Logback logging framework. Is there any way to print (for diagnostic purposes) at runtime, which configuration file Logback used to bootstrap itself?
[edit]
To clarify, I'd ideally like a solution that doesn't require me to modify the configuration file itself (since a badly assembled third-party JAR, for example, may be picked up incorrectly, and prior to my logback configuration XML).
You can set a Java system property to output Logback debugging info:
java -Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener
This is further explained by the Logback documentation for automatic status printing (very bottom mentions forcing status output) and the logback.statusListenerClass property:
In the absence of status messages, tracking down a rogue logback.xml configuration file can be difficult, especially in production where the application source cannot be easily modified. To help identify the location of a rogue configuration file, you can set a StatusListener via the "logback.statusListenerClass" system property (defined below) to force output of status messages. The "logback.statusListenerClass" system property can also be used to silence output automatically generated in case of errors.
If you want to go deep into Logback, you can do the following
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) throws Exception {
LoggerContext loggerContext = ((ch.qos.logback.classic.Logger)logger).getLoggerContext();
URL mainURL = ConfigurationWatchListUtil.getMainWatchURL(loggerContext);
System.out.println(mainURL);
// or even
logger.info("Logback used '{}' as the configuration file.", mainURL);
}
}
It will print the URL of the loaded configuration file.
you can set debug="true" in a logback.xml file that you control like this:
<configuration debug="true">
(...)
</configuration
and tho make sure that file is going to be used by logback add following VM argument when you start your program:
-Dlogback.configurationFile=/path/to/yourlogback.xml
This does not really answer to your question but gives you a work around solution.
Not very scientific, but it works if you just want a quick confirmation.
I simply changed the log entry pattern and observed whether or not it changed in my console/log file.

Set log4j log level

I'm currently working on a project that uses log4j.
I'm running a testcase (junit) and would like to set the log level to trace so that I can see if all the values are correct. Classes that use logging in the project contain a line like the following:
private static final Log LOG = LogFactory.getLog(MatchTaskTest.class);
and use a like like this to do the actual debugging
LOG.trace("value");
I have never used log4j before, does anybody know how I can change the log level just for the testcase, preferably simply by defining a parameter in eclipse's run configuration dialog.
Using another configuration file
Perhaps you could point to another configuration file.
java -Dlog4j.configuration=config file yourApp
Where:
config, you file of configuration, e.g. log4j.properties or log4j.xml.
file, the log file, e.g. myApp.log
yourApp, you app, e.g. MyAppGUI
Or you can use a class
java -Dlog4j.configurationClass=config class yourApp
Where:
config, you file of configuration, e.g. log4j.properties or log4j.xml.
class, any customized initialization class, like LogManager, should implement
the org.apache.log4j.spi.Configurator
yourApp, you app, e.g. MyAppGUI
You can see more in Apache log4j 1.2 - Short introduction to log4j on Default Initialization Procedure section.
Modifying the level programmatically
Moreover, you can also use the methods that offers the Logger class, like public void setLevel(Level level), e.g.:
Logger.getRootLogger().setLevel(Level.TRACE);
Since you want only for testing purposes, you could use them. But it is recommended not to use in client code because they overwrite the default configuration parameters in hard coded. The best way is to use an external configuration file.
In your junit class put:
Logger.getRootLogger().setLevel(Level.TRACE);
somewhere before the execution of the tested method. It will set the threshold level of the root logger to TRACE.
If you're using Maven, you can have two log4j configuration files:
one in src/main/resources, containing your production logging config
one in src/test/resources, containing your test-time logging config
Maven will automatically use the latter at test time, and bundle the former into your artifact (JAR, WAR, etc) so that it's used in production. You don't have to mess around with command line switches or anything.
I don't think this is possible.
The config file is going to let you configure what log messages actually surface in the log, not what level each message is going be logged at. This makes sense - the config should not affect the level of the message.
The javadoc has a method for each log level and a generic log method, which takes in a priority, so I'm not sure there's even a default to be set.
You can set a config file explictly on the command line via -Dlog4j.configuration=<FILE_PATH>, so you could set up a specific config for that test case.
I have no idea why some of the above didn't work for me. (I don't want to write config file). following works for me
Logger log1 = Deencapsulation.getField(Some.class,"logger");
log1.setLevel(Level.DEBUG);
NB that the log4j2.properties file may include the line
filter.threshold.level = debug
You can waste an entire afternoon trying to figure out why your LOG.trace() statements aren't outputting anything!
I actually put it in the #Before method. But I believe it could (and should) be placed in the #BeforeClass.
If you set it in the class body you'll get compiler errors.

slf4j logging with jdk – how to enable debug?

By default slf4j, when using with jdk (slf4j-jdk14-1.6.1.jar), does not log debug messages.
How do I enable them?
I can’t find info neither in the official docs, the web or here on how to enable it.
I found some info on (failed though) creating a file in %JDK_HOME%/lib and defining the level there, in a config file.
However, I would like to define the level at compile-/run-time so I can both run and debug my app from my IDE with different logging levels.
Isn’t there some environment variable I can set, or VM arg?
Why do you think it does not log DEBUG messages?
If you mean that your log.debug(String) logging calls do not end up in java.util.logging log files, then I guess you have to configure the logging.properties configuration file to allow log messages at FINE level.
If you do not want to mess with the global %JRE_HOME%/lib/logging.properties, then you can just pass in -Djava.util.logging.config.file=logging.properties on the command line - this will force the logging system to look for that configuration file in the current directory.
Or use some other (programmatic) way to configure java.util.logging, see below for tutorial.
This has nothing to do with configuring SLF4J; in fact, SLF4J does not have any configuration, everything is configured by simply swapping JAR files.
For your reference:
JDK14LoggerAdapter
Java Logging API tutorial
If you are using slf4j SimpleLogger implementation read this.
There you can see that simpleLogger use INFO as default log level. You can change it by using a system property. This is usefull for non-production evironments:
static {
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "trace");
}
You can add -Dorg.slf4j.simpleLogger.defaultLogLevel=debug to the VM options.
I just put my logging.properties file in my applications WEB-INF/classes file (or use the command line argument identified by Neeme Praks if you're not deploying in a war), and have the properties file open in eclipse so I can fine tune it to log the packages and at the level I'm interested in.
In the logging.properties file, you need to make sure that both the logger level and the handler level are set to the level you want. For example, if you want your output to go to the console, you need to have at least the following:
#logging.properties file contents
#Define handlers
handlers=java.util.logging.ConsoleHandler
#Set handler log level
java.util.logging.ConsoleHandler.level=FINE
#Define your logger level
com.company.application.package.package.level=FINE
#Assign your handler to your logger
com.company.application.package.package.handlers=java.util.logging.ConsoleHandler
You mentioned the slf4j-jdk14-1.6.1.jar. This provides the slf4j binding to java.util.logging. You need to have that in your classpath, but make sure you also have the slf4j api (slf4j-api-1.7.12.jar) in your classpath as well.
I find the example logging.properties file in this link useful for creating a variety of loggers and handlers, to give you fine-grained control over what logs go to the console, and what logs go to a file:.
And here's the slf4j manual.
if you are using lombok Slf4j
package com.space.slf4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* #author anson
* #date 2019/6/18 16:17
*/
#Slf4j
#RestController
public class TestController {
#RequestMapping("/log")
public String testLog(){
log.info("######### info #########");
log.debug("######### debug #########");
log.error("######### error #########");
return null;
}
}
application.yml
logging:
level:
root: debug
In runtime with the default configuration you can enable it with this code:
public class MyTest {
static {
Logger rootLogger = Logger.getLogger("");
rootLogger.setLevel(Level.ALL);
rootLogger.getHandlers()[0].setLevel(Level.ALL);
}
I'm using this code inside TestNG Unit.

Categories