Java Util Logging Configuration¶
The java util logging configuration is defined by a file logging.properties
:
java.util.logging.config.file
system propertyjava.util.logging.config.class
identifying a class in your application responsible for configurationJava 11:
$JAVA_HOME/conf/logging.properties
And can be detected during application startup if necessary:
public void static main(String ...){
File logging = new File("logging.properties");
if( logging.exists() && !System.getProperties().hasKey("java.util.logging.config.file")){
System.setProperty("java.util.logging.config.file", path);
}
else {
System.setProperty("java.util.logging.config.class", "ApplicationDefaultLogging");
}
}
Falling back to ApplicationDefaultLogging (reading logging.properties
from src/main/resources/logging.properties resource included in jar:
class ApplicationDefaultLogging {
public ApplicationDefaultLogging(){
try( Inputstream stream : ApplicationDefaultLogging.class.getResourceAsStream("/logging.properties")){
LogManager.readConfiguration(stream);
}
}
}
To define a default configuration level provide a the .level property to the minimal level of interest for you:
.level= FINER
You can specify a different level to be shown to the console (than is saved out to xml). To define the java.util.logging.ConsoleHandler.level property to the minimal level you want to see on the console:
# Limit the message that are printed on the console to FINE and above.
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
For Windows user, check the value displayed by chcp on the command line - you may need to add:
# windows users may need to provide character encoding
java.util.logging.ConsoleHandler.encoding = Cp850
To list detailed messages for a specific module you can define a different logging level may be specified for each module.:
org.geotools.gml.level = FINE
org.geotools.referencing.level = INFO
Provides fairly detailed logging message from the GML module, but not from the referencing module.
Custom Levels¶
Logging defines two custom levels to better map to logging frameworks:
Logging.FATAL
- unrecoverable error that will cause application or operation to failLogging.OPERATION
- operation configuration
MonolineFormatter¶
GeoTools can produces a console output similar to the Log4J one (single-line instead of multi-line log message) if the following code is invoked once at application starting time:
Logging.ALL.forceMonolineConsoleOutput();
Alternatively, this formatter can also be configured in the logging.properties
without the need for the above-cited method call:
java.util.logging.ConsoleHandler.formatter = org.geotools.util.logging.MonolineFormatter
java.util.logging.ConsoleHandler.level = FINE
# Optional
# org.geotools.util.logging.MonolineFormatter.time = HH:mm:ss.SSS
# org.geotools.util.logging.MonolineFormatter.source = class:short
See the MonolineFormatter javadoc for details.
Java Util Logging Guidance¶
Logging frameworks mechanism to delegate to java.util.logging
as a backend.
SL4J: Add
slf4j-jdk14.jar
to classpath:<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>${sl4j.version}</version> </dependency>
Log4J 1.2: configure an appender route to java util logging
<appender name="jul" class="org.apache.log4j.JulAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p %c - %m%n "/> </layout> </appender>
commons-logging:
Use
commons-logging.properties
:org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger
Java Util Logging Integration¶
The following example is taken from our integration testing, this test has no additional libraries in play so GeoTools.init()
defaults to direct use of Java Logger implementation.
Setup
pom.xml
with dependencies on geotools:<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.geotools.tutorial</groupId> <artifactId>logging</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>GeoTools Logging Integration Example</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.deploy.skip>true</maven.deploy.skip> <geotools.version>32-SNAPSHOT</geotools.version> </properties> <dependencies> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-metadata</artifactId> <version>${geotools.version}</version> </dependency> <dependency> <groupId>org.geotools.ogc</groupId> <artifactId>net.opengis.ows</artifactId> <version>${geotools.version}</version> </dependency> </dependencies> <repositories> <repository> <id>osgeo</id> <name>OSGeo Release Repository</name> <url>https://repo.osgeo.org/repository/release/</url> <snapshots><enabled>false</enabled></snapshots> <releases><enabled>true</enabled></releases> </repository> <repository> <id>osgeo-snapshot</id> <name>OSGeo Snapshot Repository</name> <url>https://repo.osgeo.org/repository/snapshot/</url> <snapshots><enabled>true</enabled></snapshots> <releases><enabled>false</enabled></releases> </repository> </repositories> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.1.0</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <configuration> <executable>java</executable> <arguments> <argument>-classpath</argument> <classpath/> <argument>-Djava.util.logging.config.file=logging.properties</argument> <argument>-Djava.awt.headless=true</argument> <argument>-Duser.country=US</argument> <argument>-Duser.language=en</argument> <argument>org.geotools.tutorial.logging.LoggingIntegration</argument> </arguments> </configuration> </plugin> </plugins> </build> </project>
Configure
java.util.logging
withlogging.properties
:handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = org.geotools.util.logging.MonolineFormatter org.geotools.util.logging.MonolineFormatter.source = class:short # Loggers created by org.geotools.util.logging.Logging .level= ALL org.geotools.level = CONFIG # Not created by LoggingIntegration (so this setting is never used) org.geotools.tutorial.level = FINE # Created by LoggingInteraction org.geotools.tutorial.logging.level = FINEST
Warning
Only Loggers that are used are configured, this can be frustrating if you assume a parent logger has been setup and will provide an expected default level.
During startup java util logging will use:
The
logging.properties
included in your Java Runtime Environment.The
/WEB-INF/logging.properties
included in web application
You can override this behaviour with system property:
-Djava.util.logging.config.file=logging.properties
Application
LogbackJIntegration.java
startup example forsrc/min/java
.Example is taking care to call
GeoTools.init()
prior to logger use:/* * GeoTools Sample code and Tutorials by Open Source Geospatial Foundation, and others * https://docs.geotools.org * * To the extent possible under law, the author(s) have dedicated all copyright * and related and neighboring rights to this software to the public domain worldwide. * This software is distributed without any warranty. * * You should have received a copy of the CC0 Public Domain Dedication along with this * software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. */ package org.geotools.tutorial.logging; import java.io.File; import java.util.logging.Logger; import java.util.logging.Level; import org.geotools.util.factory.GeoTools; import org.geotools.util.logging.DefaultLoggerFactory; import org.geotools.util.logging.Logging; /** * Logging integration demonstration illustrating use of logging.properties to configure GeoTools. */ public class LoggingIntegration { static { GeoTools.init(); } static final Logger LOGGER = Logging.getLogger(LoggingIntegration.class); public static void main(String args[]) { if (Logging.ALL.getLoggerFactory() != DefaultLoggerFactory.getInstance()) { System.err.println( "Expected GeoTools.init() use native java util logging factory, was " + Logging.ALL.getLoggerFactory()); } LOGGER.info("Welcome to Logging Integration Example"); checkProperty("java.util.logging.config.file"); LOGGER.config("Configuration " + Logging.ALL.lookupConfiguration()); LOGGER.finest("Everything is finest..."); LOGGER.finer("Everything is finer..."); LOGGER.fine("Everything is fine..."); LOGGER.config("Everything is configured..."); LOGGER.log(Logging.OPERATION, "Everything is operating..."); LOGGER.info("Everything is okay."); LOGGER.warning("Everything is alarming!"); LOGGER.severe("Everything is terrible!"); LOGGER.log(Logging.FATAL, "Everything has died!"); } private static void checkProperty(String property) { if (System.getProperties().containsKey(property)) { LOGGER.config(property + "=" + System.getProperty(property)); } } }
An
exec:exec
target is provided to make this easier to test:mvn exec:exec
The exec:exec goal was configured with
-Djava.util.logging.config.file=logging.properties
.Note
Avoid testing with
exec:java
which uses maven java runtime environment (already pre-configured for logging).