Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle Logging Output Levels

In my project classes I've used java.util.logging.Logger and added various log output's throughout my code, using various log levels ie.

src/main/java/Run.java

import java.util.logging.Level;
import java.util.logging.Logger;

public class Run{


    public static void main( String args[] ){
      System.out.println("Hello World");

      logger.log(Level.CONFIG, "Just some config info");
      Logger logger = Logger.getLogger(Run.class.getName());
      logger.log(Level.INFO, "Just logging some info");
      logger.log(Level.FINE, "Fine logging");
      logger.log(Level.FINER, "Finer logging");
      logger.log(Level.WARNING, "This is a warning log!");

    }
}

Currently when I run gradle -i test all log messages with the Level.INFO defined are shown but none of the config, warn or fine messages are output.

I've tried updating my build.gradle file such that:

apply plugin: 'java'
apply plugin:'application'
mainClassName = "Run"

repositories {
    mavenCentral()
}

dependencies {
    testCompile "junit:junit:4.11"
}

run{
    systemProperties = ['java.util.logging.config.file' : 'logging.properties']
}

I've included:

systemProperties = ['java.util.logging.config.file' : 'logging.properties']

Then created /src/main/resource/logging.propertiess

handlers= java.util.logging.ConsoleHandler
.level= CONFIG
java.util.logging.ConsoleHandler.level = FINER
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

Running:

gradle run

I get:

:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
Hello World

BUILD SUCCESSFUL

And when running gradle -i run I get: Successfully started process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/bin/java'' Hello World :run (Thread[main,5,main]) completed. Took 0.202 secs.

BUILD SUCCESSFUL

ie. no logging information. However commenting out the system.properties from within the run task and re-running gradle -i run I get:

Successfully started process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/bin/java''
Hello World
Nov 05, 2014 12:07:42 PM Run main
INFO: Just logging some info
Nov 05, 2014 12:07:42 PM Run main
WARNING: This is a warning log!
:run (Thread[main,5,main]) completed. Took 0.229 secs.

BUILD SUCCESSFUL

The info and warning level logs, but not the fine or finer ones.

tldr;

How do I get the config, fine & finer level logs to log to the console in a generic gradle java project ?

like image 212
SS44 Avatar asked Oct 29 '14 16:10

SS44


1 Answers

Several options (I personally prefer option 2.2):

1) Custom logging.properties file:

The Java Logging API has a default logging configuration file at <JRE_HOME>/lib/logging.properties. You can use your own config file setting the JVM property java.util.logging.config.file.

handlers = java.util.logging.ConsoleHandler

Run.handlers = java.util.logging.ConsoleHandler
Run.level = FINER
Run.useParentHandlers = false

java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

You have to set useParentHandlers = false to avoid getting duplicate prints from parent handlers.

1.1) Set above property with absolute path

Did not even try ;-)

1.2) Load custom file as follows in Run.java

Loading it as follows in Run.java:

    InputStream inputStream = Run.class.getResourceAsStream("mylogging.properties");
    try {
        LogManager.getLogManager().readConfiguration(inputStream);
    } catch(Exception e) {
        e.printStackTrace();
    }

2) Custom system property (i.e.: logLevel)

Define a systemProperty in your build.gradle:

run {
    systemProperty 'logLevel', System.getProperty('logLevel')
}

Add a defaultLogLevel in Run.java:

public static Level defaultLevel = Level.INFO;

Get the value of logLevel property:

String logLevel = System.getProperty("logLevel");

And set the defined level in logger:

Logger logger = Logger.getLogger(Run.class.getName());
logger.setLevel(logLevel.isEmpty() ? defaultLevel : Level.parse(logLevel));

2.1) Create a new ConsoleHandler and switch-off print from parent handlers

    System.out.println(Run.class.getName());
    Logger logger = Logger.getLogger(Run.class.getName());
    logger.setLevel(logLevel.isEmpty() ? defaultLevel : Level.parse(logLevel));

    Handler consoleHandler = new ConsoleHandler();
    consoleHandler.setLevel(logLevel.isEmpty() ? defaultLevel : Level.parse(logLevel));
    logger.addHandler(consoleHandler);

    logger.setUseParentHandlers(false);

2.2) Find parent ConsoleHandler and set defined level

    Logger topLogger = Logger.getLogger("");

    Handler consoleHandler = null;
    for (Handler handler : topLogger.getHandlers()) {
        if (handler instanceof ConsoleHandler) {
            //found the console handler
            consoleHandler = handler;
            break;
        }
    }

    if (consoleHandler == null) {
        // not found, create a new one
        consoleHandler = new ConsoleHandler();
        topLogger.addHandler(consoleHandler);
    }
    //set the console handler level
    consoleHandler.setLevel(logLevel.isEmpty() ? defaultLevel : Level.parse(logLevel));

With that, gradle run yields messages above the default level (INFO). With

gradle run -DlogLevel=FINE

you can control which messages are shown.

like image 61
jalopaba Avatar answered Oct 11 '22 01:10

jalopaba