https://github.com/goodforgod/slf4j-simple-logger
⚙️ SLF4J based, simple, efficient and structured logger implementation.
https://github.com/goodforgod/slf4j-simple-logger
graalvm java json logger logging-library simple slf4j slf4j-api slf4j-logger structured-logging
Last synced: 2 months ago
JSON representation
⚙️ SLF4J based, simple, efficient and structured logger implementation.
- Host: GitHub
- URL: https://github.com/goodforgod/slf4j-simple-logger
- Owner: GoodforGod
- License: apache-2.0
- Created: 2021-10-09T10:27:57.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2023-10-07T22:36:42.000Z (over 1 year ago)
- Last Synced: 2025-03-17T13:46:26.647Z (2 months ago)
- Topics: graalvm, java, json, logger, logging-library, simple, slf4j, slf4j-api, slf4j-logger, structured-logging
- Language: Java
- Homepage: http://goodforgod.dev/slf4j-simple-logger/
- Size: 267 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# SLF4J Simple Logger

[](https://openjdk.org/projects/jdk/11/)
[](https://maven-badges.herokuapp.com/maven-central/io.goodforgod/slf4j-simple-logger)
[](https://github.com/GoodforGod/slf4j-simple-logger/actions?query=workflow%3ACI+Master)
[](https://sonarcloud.io/dashboard?id=GoodforGod_slf4j-simple-logger)
[](https://sonarcloud.io/dashboard?id=GoodforGod_slf4j-simple-logger)
[](https://sonarcloud.io/dashboard?id=GoodforGod_slf4j-simple-logger)[SLF4J](https://github.com/qos-ch/slf4j) based, simple, efficient logger.
This logger is great for applications that use synchronous output or run in single-thread like command line applications or Serverless applications.
Features:
- Performance optimizations.
- GraalVM friendly.
- JSON format support.
- Environment variables logging.
- [slf4j-simple-logger](https://www.slf4j.org/api/org/slf4j/impl/SimpleLogger.html) compatible configuration.And more...
## Dependency :rocket:
[**Gradle**](https://mvnrepository.com/artifact/io.goodforgod/slf4j-simple-logger)
```groovy
implementation "io.goodforgod:slf4j-simple-logger:2.0.0"
```[**Maven**](https://mvnrepository.com/artifact/io.goodforgod/slf4j-simple-logger)
```xmlio.goodforgod
slf4j-simple-logger
2.0.0```
## Content
- [Logging example](#logging-example)
- [Text format](#text-format)
- [Json format](#json-format)
- [Features](#features)
- [Performance Optimizations](#performance-optimizations)
- [Output format](#output-format)
- [DateTime output](#datetime-output)
- [Logger name abbreviation](#logger-name-abbreviation)
- [Environment logging](#environment-logging)
- [Environment configuration](#environment-configuration)
- [Runtime refresh](#runtime-refresh)
- [Output split](#output-split)
- [Callable and Supplier](#callable-and-supplier)
- [Logger level change](#logger-level-change)
- [Configuration](#configuration)
- [Compatability](#slf4j-compatability)## Logging example
### Text format
Below is example of logged message in text format:
```java
Marker myMarker = MarkerFactory.getMarker("my_marker");
myMarker.add(MarkerFactory.getMarker("my_marker_ref"));
logger.debug(myMarker, "Message is printed for this logger");
```Result logged message:
```text
Date Time Implementation Log Level Markers Environment variables Thread Logger Name Log Message
| | | | | | | |
___________|__________ ______|_______ __|__ ________________|______________ __________________|_______________ __|__ ___________|___________ ________________|________________
| | | | | | | | | | | | | | |
| | | | | | | | | | | | | | |
2022-02-23T15:43:40.331 [0.9.0-SNAPSHOT] [DEBUG] [markers=my_marker,my_marker_ref] [SESSION=Console, PROCESSOR_LEVEL=6] [main] io.goodforgod.Application - Message is printed for this logger
```### Json format
Below is example of logged message in json format:
```java
Exception e = new RuntimeException();
Marker myMarker = MarkerFactory.getMarker("my_marker");
myMarker.add(MarkerFactory.getMarker("my_marker_ref"));
logger.debug(myMarker, "Message is printed for this logger", e);
```Result logged message:
```json
{
"timestamp": "2022-02-23T15:43:40.331",
"implementation": "0.9.0-SNAPSHOT",
"level": "DEBUG",
"thread": "main",
"logger": "io.goodforgod.Application",
"markers": ["my_marker", "my_marker_ref"],
"environment": [
{
"name": "SESSION",
"value": "Console"
},
{
"name": "PROCESSOR_LEVEL",
"value": "6"
}
],
"message": "Message is printed for this logger",
"exception": "Ops",
"stacktrace": [
{
"clazz": "io.goodforgod.slf4j.simplelogger.JsonLoggerLayoutTests",
"message": "Ops",
"method": "throwableOutput:279"
},
{
"clazz": "jdk.internal.reflect.NativeMethodAccessorImpl",
"method": "invoke0:-2"
}
]
}
```## Features
### Performance optimizations
This implementation is based on default *slf4j-simple-logger*, but there are plenty of performance and feature improvements.
Some cases are 200% faster others are 800% faster, you can read more about here in my [JVM benchmark](https://github.com/GoodforGod/java-logger-benchmark).
### Output format
There is option to output logged messages in different formats, currently supported formats:
- TEXT
- JSONYou can check example of each format [here](#logging-example).
Configuration for format is below for TEXT (default value).
```properties
org.slf4j.simpleLogger.format=TEXT
```And same for JSON:
```properties
org.slf4j.simpleLogger.format=JSON
```### DateTime output
There are three options to output date & time:
1) DATE_TIME - in format *uuuu-MM-dd'T'HH:mm:ss.SSS*, example is - *2022-02-23T15:43:40.331* (read more about Java [Date & Time formats here](https://goodforgod.dev/posts/2/))
2) TIME - in format *HH:mm:ss.SSS*, example is - *15:43:40.331* (read more about Java [Date & Time formats here](https://goodforgod.dev/posts/2/))
3) UNIX_TIME - time [since epoch](https://en.wikipedia.org/wiki/Unix_time).
4) MILLIS_FROM_START - Millis from SimpleLoggerConfiguration initialization (may not properly work in GraalVM setups)You can also change formatter for DATE_TIME and TIME via configuration:
```properties
org.slf4j.simpleLogger.dateTimeFormat=uuuu-MM-dd'T'HH:mm:ss.SSS
```### Logger name abbreviation
There is configuration to abbreviate logger name, like in logback.
If configuration is:
```properties
org.slf4j.simpleLogger.showShortLogName=false
org.slf4j.simpleLogger.showLogName=true
org.slf4j.simpleLogger.logNameLength=36
```And logger is:
```java
package io.goodforgod.internal.logger.example;import org.slf4j.LoggerFactory;
import org.slf4j.Logger;public class Application {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Application.class);
logger.info("Message is printed for this logger");
}
}
```Then logger name will be outputted like:
```text
2022-02-23T15:43:40.331 [DEBUG] i.g.i.logger.example.Application - Message is printed for this logger
```Abbreviation happened to full logger name:
*io.goodforgod.internal.logger.example.Application* -> *i.g.i.logger.example.Application*### Environment logging
It is possible to log environment, format how it will be outputted can be seen [here](#log-example).
If the configuration is:
```properties
# Set environment names to show in output. Envs will be printed out in order they preserve in configuration.
org.slf4j.simpleLogger.environments=SESSION,PROCESSOR_LEVEL
# Set to true to show environment with nullable values.
org.slf4j.simpleLogger.environmentShowNullable=false
# Set to true to show environment names.
org.slf4j.simpleLogger.environmentShowName=true
# Set to true to caches environment values on configuration initialization and then always uses them when logging.
org.slf4j.simpleLogger.environmentRememberOnStart=false
```Then the output will be:
```text
2022-02-23T15:43:40.331 [DEBUG] [SESSION=Console, PROCESSOR_LEVEL=6] [main] io.goodforgod.Application - Message is printed for this logger
```Environment variables are printed in order they preserve in configuration (in example above first SESSION, then PROCESSOR_LEVEL).
### Environment configuration
You can use environment variables to configure values for property config.
Below is example where there are two environment variables are used for configuration (*SHOW_LOG_NAME* and *LOG_NAME_LENGTH*):
```
org.slf4j.simpleLogger.showLogName=${SHOW_LOG_NAME}
org.slf4j.simpleLogger.logNameLength=${LOG_NAME_LENGTH:36}
```If environment variable value is absent, then [default value](#configuration) is used.
#### Runtime refresh
Environment variable configuration can be refresh in runtime. This can be useful when environment changed, and it is required to update logger config without stopping application.
```java
SimpleLoggerFactory.refresh();
```Only these properties can be changed in runtime:
```properties
# Default logging level for all loggers. Must be one of ("TRACE", "DEBUG", "INFO", "WARN", or "ERROR"). (default INFO)
org.slf4j.simpleLogger.defaultLogLevel=INFO
# Set logging message output format. Must be one of ("TEXT", "JSON"). (default TEXT)
org.slf4j.simpleLogger.format=TEXT
# Set to true to show current datetime in output. (default true)
org.slf4j.simpleLogger.showDateTime=true
# Set datetime output type. Must be one of ("TIME", "DATE_TIME", "UNIX_TIME", "MILLIS_FROM_START"). (default DATE_TIME)
org.slf4j.simpleLogger.dateTimeOutputType=DATE_TIME
# The date and time formatter pattern to be used in the output. (default uuuu-MM-dd'T'HH:mm:ss.SSS)
org.slf4j.simpleLogger.dateTimeFormat=uuuu-MM-dd'T'HH:mm:ss.SSS
# Set ZoneId to use as adjustment for DATE_TIME or TIME. (default ZoneId.systemDefault())
org.slf4j.simpleLogger.zoneId=UTC
# Set to true if to show application implementation version from MANIFEST.MF (default false)
org.slf4j.simpleLogger.showImplementationVersion=false
# Set to true to show logging level in brackets like: [INFO] (default true)
org.slf4j.simpleLogger.levelInBrackets=true
# Set to true if to show current thread in output. (default false)
org.slf4j.simpleLogger.showThreadName=false
# Set to true if to show marker parameter values. (default false)
org.slf4j.simpleLogger.showMarkers=false
# Set to true to show only class name in output. (default false)
org.slf4j.simpleLogger.showShortLogName=false
# Set to true if to show full class name in output (package + class name). (default true)
org.slf4j.simpleLogger.showLogName=true
# Set maximum logger name to output and abbreviate if it exceeds length. (default null)
org.slf4j.simpleLogger.logNameLength=36
# Set environment names to show in output. Envs will be printed out in order they preserve in configuration. (default null)
org.slf4j.simpleLogger.environments=SESSION_ID,ORIGIN,HOST
# Set to true to show environment with nullable values. (default false)
org.slf4j.simpleLogger.environmentShowNullable=false
# Set to true to show environment names. (default false)
org.slf4j.simpleLogger.environmentShowName=false
```### Output split
There is possibility to split *WARN* and *ERROR* logs to different output.
If configuration is:
```properties
# Set default logger output file or System.out or System.error (default System.out)
org.slf4j.simpleLogger.logFile=System.out
# Set logger WARN logs output file or System.out or System.error (default System.out)
org.slf4j.simpleLogger.logFileWarn=System.error
# Set logger ERROR logs output file or System.out or System.error (default System.out)
org.slf4j.simpleLogger.logFileError=System.error
```Then all logs of TRACE, DEBUG, INFO will be forwarded to *System.out* and all WARN & ERROR logs will be forwarded to *System.error*.
### Callable and Supplier
Callable or Supplier can be passed as arguments to logger and computed correctly:
```java
Callable supplier = () -> "argument";
logger.info("Value supplier is {}.", supplier);
```
Resulted output:
```text
Value supplier is argument.
```### Logger level change
You can change loggers level using *io.goodforgod.slf4j.simplelogger.SimpleLoggerFactory*:
```java
SimpleLoggerFactory factory = (SimpleLoggerFactory) LoggerFactory.getILoggerFactory();
factory.setLogLevel(Level.DEBUG);
```Or you can use predicate to filter out loggers:
```java
SimpleLoggerFactory factory = (SimpleLoggerFactory) LoggerFactory.getILoggerFactory();
factory.setLogLevel(Level.DEBUG, logger -> logger.getName().startsWith("io.goodforgod.internal.logger.example"));
```## Configuration
Library is fully compatibly with *slf4j-simple-logger* configuration, you can check it [here](https://www.slf4j.org/api/org/slf4j/impl/SimpleLogger.html).
Example of full *simplelogger.properties* file:
```properties
# Default logging level for all loggers. Must be one of ("TRACE", "DEBUG", "INFO", "WARN", or "ERROR"). (default INFO)
org.slf4j.simpleLogger.defaultLogLevel=INFO
# Set logging message output format. Must be one of ("TEXT", "JSON"). (default TEXT)
org.slf4j.simpleLogger.format=TEXT
# Set to true to show current datetime in output. (default true)
org.slf4j.simpleLogger.showDateTime=true
# Set datetime output type. Must be one of ("TIME", "DATE_TIME", "UNIX_TIME", "MILLIS_FROM_START"). (default DATE_TIME)
org.slf4j.simpleLogger.dateTimeOutputType=DATE_TIME
# The date and time formatter pattern to be used in the output. (default uuuu-MM-dd'T'HH:mm:ss.SSS)
org.slf4j.simpleLogger.dateTimeFormat=uuuu-MM-dd'T'HH:mm:ss.SSS
# Set ZoneId to use as adjustment for DATE_TIME or TIME. (default ZoneId.systemDefault())
org.slf4j.simpleLogger.zoneId=UTC
# Set to true if to show application implementation version from MANIFEST.MF (default false)
org.slf4j.simpleLogger.showImplementationVersion=false
# Set to true to show logging level in brackets like: [INFO] (default true)
org.slf4j.simpleLogger.levelInBrackets=true
# Set to true if to show current thread in output. (default false)
org.slf4j.simpleLogger.showThreadName=false
# Set to true if to show marker parameter values. (default false)
org.slf4j.simpleLogger.showMarkers=false
# Set to true to show only class name in output. (default false)
org.slf4j.simpleLogger.showShortLogName=false
# Set to true if to show full class name in output (package + class name). (default true)
org.slf4j.simpleLogger.showLogName=true
# Set maximum logger name to output and abbreviate if it exceeds length. (default null)
org.slf4j.simpleLogger.logNameLength=36
# Set logger output charset to use (default UTF-8)
org.slf4j.simpleLogger.charset=UTF-8
# Set environment names to show in output. Envs will be printed out in order they preserve in configuration. (default null)
org.slf4j.simpleLogger.environments=SESSION_ID,ORIGIN,HOST
# Set to true to show environment with nullable values. (default false)
org.slf4j.simpleLogger.environmentShowNullable=false
# Set to true to show environment names. (default false)
org.slf4j.simpleLogger.environmentShowName=false
# Set to true to caches environment values on configuration initialization and then always uses them when logging. (default false)
org.slf4j.simpleLogger.environmentRememberOnStart=false
# Set default logger output file or System.out or System.error (default System.out)
org.slf4j.simpleLogger.logFile=System.out
# Set logger WARN logs output file or System.out or System.error (default System.out)
org.slf4j.simpleLogger.logFileWarn=System.out
# Set logger ERROR logs output file or System.out or System.error (default System.out)
org.slf4j.simpleLogger.logFileError=System.out# Set log level for custom loggers
org.slf4j.simpleLogger.log.path.to.class=WARN
```## SLF4J Compatability
Starting from version *2.0.0* library ships for [SLF4J 2.0.0+](https://www.slf4j.org/manual.html). (Based on SLF4J 2.0.7+)
Starting from version *1.0.0* library ships for [SLF4J 1.7.5+](https://www.slf4j.org/manual.html). (Based on SLF4J 1.7.36+)
## License
This project licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details