225

api 1.7 and slf4j-simple as implementation. I just can't find how to configure the logging level with this combination.

Can anyone help out?

1

5 Answers 5

307

It's either through system property

-Dorg.slf4j.simpleLogger.defaultLogLevel=debug

or simplelogger.properties file on the classpath

see https://www.slf4j.org/api/org/slf4j/simple/SimpleLogger.html for details

Sign up to request clarification or add additional context in comments.

5 Comments

thanks I set "org.slf4j.simpleLogger.defaultLogLevel" to "error" in System.properties, however slf4j still log INFO level messages. Any idea? BTW, where should I put simplelogger.properties?
try org.slf4j.simplelogger.defaultlog instead of org.slf4j.simpleLogger.defaultLogLevel. File must be on the classpath, default package
Actually it (defaultLogLevel) works.Just found I was modifying the program in a wrong folder ;-) And defaultlog doesn't work. So you probably want to edit your answer though I've accepted it
Just a note: actually both answers are good, depending on the version of SimpleLogger you're using. For example, defaultLogLevel works for 1.7.5, but defaultlog works for 1.6.6. I found this out when configuring my project logging and coming upon this post
I spent a bunch of time wondering why this wasn't working, and eventually realized that I had capitalized the L in simplelogger.properties. It's supposed to be all lowercase!
179

This is a sample simplelogger.properties which you can place on the classpath (uncomment the properties you wish to use):

# SLF4J's SimpleLogger configuration file
# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.

# Default logging detail level for all instances of SimpleLogger.
# Must be one of ("trace", "debug", "info", "warn", or "error").
# If not specified, defaults to "info".
#org.slf4j.simpleLogger.defaultLogLevel=info

# Logging detail level for a SimpleLogger instance named "xxxxx".
# Must be one of ("trace", "debug", "info", "warn", or "error").
# If not specified, the default logging detail level is used.
#org.slf4j.simpleLogger.log.xxxxx=

# Set to true if you want the current date and time to be included in output messages.
# Default is false, and will output the number of milliseconds elapsed since startup.
#org.slf4j.simpleLogger.showDateTime=false

# The date and time format to be used in the output messages.
# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
# If the format is not specified or is invalid, the default format is used.
# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z

# Set to true if you want to output the current thread name.
# Defaults to true.
#org.slf4j.simpleLogger.showThreadName=true

# Set to true if you want the Logger instance name to be included in output messages.
# Defaults to true.
#org.slf4j.simpleLogger.showLogName=true

# Set to true if you want the last component of the name to be included in output messages.
# Defaults to false.
#org.slf4j.simpleLogger.showShortLogName=false

In a Maven or Gradle project, a convenient place "on the classpath" is src/main/resources/simplelogger.properties.

9 Comments

@RobertHunt How to save this log into file ?
@Devavrata add the property org.slf4j.simpleLogger.logFile - The output target which can be the path to a file, or the special values "System.out" and "System.err". Default is "System.err". See slf4j.org/api/org/slf4j/impl/SimpleLogger.html
Is it possible to have multiple values? If yes how? Like I want org.slf4j.simpleLogger.logFile=test.log, System.err?
@LOLWTFasdasdasdad Unfortunately not, it only supports single targets, either System.out, System.err or a path to a file. It's designed to be simple, you should consider a full logging implementation like Log4J or Logback if you want more advanced features.
I saved this file in the class path and removed the comments but still see the logs.
|
94

You can programatically change it by setting the system property:

public class App {
  public static void main(String[] args) {
    // for the code below to work, it must be executed before the
    ​// logger is created. see note below
    System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "TRACE");
       
    ​org.slf4j.Logger log = LoggerFactory.getLogger(App.class);
       ​
    ​log.trace("trace");
    ​log.debug("debug");
    ​log.info("info");
    ​log.warn("warning");
    ​log.error("error");
  ​}
​}

The log levels are ERROR > WARN > INFO > DEBUG > TRACE.

Please note that once the logger is created the log level can't be changed. If you need to dynamically change the logging level you might want to use log4j with SLF4J.

10 Comments

"Please note that once the logger is created the log level can't be changed." - Where is this actually specified?
ksl, in org.slf4j.impl.SimpleLogger. When the first logger is created, init() method is run and it fetches the default logging level from system properties. This isn't refreshed at any point. Also, org.slf4j.impl.SimpleLoggerFactory creates a logger for a class only once, thus, the same logger is always returned for given class (or name). However, it is possible to have loggers with different level. So possible workaround could be that you assign these different level loggers to your "log" variable when you want to change logging level. It is not very neat solution but should work.
@Eemuli By org.slf4j.impl.SimpleLogger you mean the actual source code rather than doc?
Yes, I mean the actual source code. I'm not sure about LOG_FILE_KEY.
I got a 'Cannot resolve symbol SimpleLogger` error.
|
4

I noticed that Eemuli said that you can't change the log level after they are created - and while that might be the design, it isn't entirely true.

I ran into a situation where I was using a library that logged to slf4j - and I was using the library while writing a maven mojo plugin.

Maven uses a (hacked) version of the slf4j SimpleLogger, and I was unable to get my plugin code to reroute its logging to something like log4j, which I could control.

And I can't change the maven logging config.

So, to quiet down some noisy info messages, I found I could use reflection like this, to futz with the SimpleLogger at runtime.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.spi.LocationAwareLogger;
    try
    {
        Logger l = LoggerFactory.getLogger("full.classname.of.noisy.logger");  //This is actually a MavenSimpleLogger, but due to various classloader issues, can't work with the directly.
        Field f = l.getClass().getSuperclass().getDeclaredField("currentLogLevel");
        f.setAccessible(true);
        f.set(l, LocationAwareLogger.WARN_INT);
    }
    catch (Exception e)
    {
        getLog().warn("Failed to reset the log level of " + loggerName + ", it will continue being noisy.", e);
    }

Of course, note, this isn't a very stable / reliable solution... as it will break the next time the maven folks change their logger.

2 Comments

For the record, here's more information about the slf4j-simple resp. MavenSimpleLogger included in Maven by default: maven.apache.org/ref/3.9.7/maven-embedder/logging.html
Oh. and here's a nice description how to configure the logger: maarten.mulders.it/2024/07/reduce-maven-plugin-logging
0

I don't know why. I use simplelogger.properties and org.slf4j.simpleLogger.showDatetime, it's not working.

I lookup the SimpleLogger class source code and got this part of the code

static {
      // Add props from the resource simplelogger.properties
      InputStream in = (InputStream)AccessController.doPrivileged(
              new PrivilegedAction() {
                  public Object run() {
                      ClassLoader threadCL = Thread.currentThread().getContextClassLoader();
                      if (threadCL != null) {
                          return threadCL.getResourceAsStream(CONFIGURATION_FILE);
                      } else {
                          return ClassLoader.getSystemResourceAsStream(CONFIGURATION_FILE);
                      }
                  }
              });
      if(null != in) {
          try {
              simpleLoggerProps.load(in);
              in.close();
          } catch(java.io.IOException e) {
              // ignored
          }
      }

      showLogName    = getBooleanProperty(systemPrefix + "showlogname",      showLogName);
      showShortName  = getBooleanProperty(systemPrefix + "showShortLogname", showShortName);
      showDateTime   = getBooleanProperty(systemPrefix + "showdatetime",     showDateTime);
      showThreadName = getBooleanProperty(systemPrefix + "showthreadname",   showThreadName);
      dateTimeFormat = getStringProperty(systemPrefix + "dateTimeFormat",    dateTimeFormat);

      if(showDateTime) {
          try {
              dateFormatter = new SimpleDateFormat(dateTimeFormat);
          } catch(IllegalArgumentException e) {
              Util.report("Bad date format in " + CONFIGURATION_FILE + "; reverting to default", e);
              // If the format pattern is invalid - use the default format
              dateTimeFormat = DEFAULT_DATE_TIME_FORMAT;
              dateFormatter = new SimpleDateFormat(dateTimeFormat);
          }
      }
  }

systemPrefix + "showdatetime" is org.slf4j.simplelogger.showdatetime When I try write org.slf4j.simplelogger.showdatetime=true to simplelogger.properties, It works normally. I hope it can help some people.

1 Comment

The system is case sensitive. You can't mix showdatetime and showDatetime.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.