https://github.com/tersesystems/echopraxia
Java Structured Logging API for Logback, Log4J2, and JUL
https://github.com/tersesystems/echopraxia
conditional-logging contextual-logging java logback logging slf4j structured-logging
Last synced: 8 months ago
JSON representation
Java Structured Logging API for Logback, Log4J2, and JUL
- Host: GitHub
- URL: https://github.com/tersesystems/echopraxia
- Owner: tersesystems
- License: other
- Created: 2021-12-06T02:22:48.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2025-02-20T17:55:26.000Z (10 months ago)
- Last Synced: 2025-03-28T06:07:38.585Z (9 months ago)
- Topics: conditional-logging, contextual-logging, java, logback, logging, slf4j, structured-logging
- Language: Java
- Homepage: https://tersesystems.github.io/echopraxia/
- Size: 2.33 MB
- Stars: 55
- Watchers: 2
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- fucking-awesome-java - Echopraxia - API designed around structured logging, rich context, and conditional logging. There are Logback and Log4J2 implementations, but Echopraxia's API is completely dependency-free, meaning it can be implemented with any logging API. (Projects / Logging)
- awesome-java - Echopraxia
- awesome-java - Echopraxia - API designed around structured logging, rich context, and conditional logging. There are Logback and Log4J2 implementations, but Echopraxia's API is completely dependency-free, meaning it can be implemented with any logging API. (Projects / Logging)
- awesome-java-zh - Echopraxia - 围绕结构化日志记录,丰富的上下文和条件日志记录设计的API。有Logback和Log4J2实现,但echoprawia的API是完全无依赖关系的,这意味着它可以用任何日志API实现。 (项目 / 日志记录)
README
[](https://mvnrepository.com/artifact/com.tersesystems.echopraxia)
[](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0))
# Echopraxia
[Echopraxia](https://github.com/tersesystems/echopraxia) is a Java logging API designed around structured logging.
What this means is that all arguments in a logging statement have a name and a value, for example:
```java
var fb = logger.fieldBuilder();
logger.info("arg1 is {} and arg2 is {}", fb.list(
fb.string("name", "value"),
fb.number("age", 13)
));
```
writes out in logfmt as:
```
INFO 13.232 arg1 is name=value and arg2 is age=13
```
and in a JSON format as:
```json
{
"message": "arg1 is name=value and arg2 is age=13",
"name": "value",
"age": 13
}
```
What makes Echopraxia effective -- especially in debugging -- is that you can define your own mappings, and then pass in your own objects and render complex objects. For example, we can render a `Person` object:
```java
import echopraxia.simple.*;
var fb = PersonFieldBuilder.instance();
var logger = LoggerFactory.getLogger(getClass());
Person abe = new Person("Abe", 1, "yodelling");
abe.setFather(new Person("Bert", 35, "keyboards"));
abe.setMother(new Person("Candace", 30, "iceskating"));
logger.info("{}", fb.person("abe", abe));
```
And print out the internal state of the `Person` in both logfmt and JSON.
```
INFO 13.223 abe={Abe, 1, father={Bert, 35, father=null, mother=null, interests=[keyboards]}, mother={Candace, 30, father=null, mother=null, interests=[iceskating]}, interests=[yodelling]}
```
## Fields
Echopraxia also has a "contextual" logging feature that renders fields in JSON:
```java
var fooLogger = logger.withFields(fb.string("foo", "bar"));
fooLogger.info("This logs the 'foo' field automatically in JSON");
```
## Conditions
And has conditional logging based on fields and exceptions, optionally using JSONPath:
```java
import echopraxia.logging.api.*;
JsonPathCondition c = JsonPathCondition.pathCondition((level, ctx) ->
ctx.findString("$.exception.stackTrace[0].methodName")
.filter(s -> s.endsWith("Foo"))
.isPresent());
logger.withCondition(c).error("Only render this error if method name ends in Foo", e);
```
There is also a feature to change logging conditions [dynamically using scripts](https://github.com/tersesystems/smallest-dynamic-logging-example).
## Custom Loggers
Extending the `Logger` class with your own methods is very straightforward.
```java
import echopraxia.api.FieldBuilder;
import echopraxia.logging.api.*;
import echopraxia.logging.spi.*;
import echopraxia.simple.Logger;
class MyLoggerFactory {
public static class MyFieldBuilder implements FieldBuilder {
// Add your own field builder methods in here
}
private static final MyFieldBuilder fieldBuilder = new MyFieldBuilder();
public static MyLogger getLogger(Class> clazz) {
final CoreLogger core = CoreLoggerFactory.getLogger(Logger.class.getName(), clazz);
return new MyLogger(core);
}
public static final class MyLogger extends Logger {
public static final String FQCN = MyLogger.class.getName();
public MyLogger(CoreLogger logger) {
super(logger);
}
@Override
public FieldBuilder fieldBuilder() {
return fieldBuilder;
}
public void notice(String message) {
// the caller is MyLogger specifically, so we need to let the logging framework know how to
// address it.
core().withFQCN(FQCN).log(Level.INFO, message, fb -> fb.bool("notice", true), fieldBuilder());
}
}
}
class Main {
private static final MyLoggerFactory.MyLogger logger = MyLoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
logger.notice("this has a notice field added");
}
}
```
## Documentation
Please see the [online documentation](https://tersesystems.github.io/echopraxia).
## Examples
For the fastest possible way to try out Echopraxia, download and run the [JBang script](https://github.com/tersesystems/smallest-dynamic-logging-example/blob/main/jbang/Script.java).
Simple examples and integrations with [dropwizard metrics](https://metrics.dropwizard.io/4.2.0/) and [OSHI](https://github.com/oshi/oshi) are available at [echopraxia-examples](https://github.com/tersesystems/echopraxia-examples).
For a web application example, see this [Spring Boot Project](https://github.com/tersesystems/echopraxia-spring-boot-example).
## Scala API
There is a Scala API available at [https://github.com/tersesystems/echopraxia-plusscala](https://github.com/tersesystems/echopraxia-plusscala).
## Benchmarks
Benchmarks are available at [BENCHMARKS.md](BENCHMARKS.md).