Skip to content

Commit c0d37ad

Browse files
committed
Rename AwsLambdaAppender to StdOutAppender, plus support configuring component and environment
1 parent 6d5d6bf commit c0d37ad

File tree

4 files changed

+176
-63
lines changed

4 files changed

+176
-63
lines changed

README.md

Lines changed: 108 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,123 @@
44
[![Discord](https://img.shields.io/discord/1074074312421683250?color=%237289da&label=discord)](https://discord.gg/Qcqf9R27BR)
55

66
# avaje-logback-encoder
7-
logback encoder that uses avaje-jsonb to log events as json
7+
Logback encoder that log events as json (similar to Logstash).
88

9-
## Usage
9+
Example:
10+
```json
11+
{"timestamp":"2025-01-10T14:47:42.313+13:00","level":"INFO","logger":"org.example.Foo","message":"Hi","thread":"main"}
12+
```
13+
14+
Example with component and environment:
15+
```json
16+
{"component":"my-component","env":"DEV","timestamp":"2025-01-10T14:47:42.313+13:00","level":"INFO","logger":"org.example.Foo","message":"Hi","thread":"main"}
17+
```
18+
19+
## Fields
20+
#### Standard Fields
21+
- `timestamp`
22+
- `level`
23+
- `logger`
24+
- `message`
25+
- `thread`
26+
- `stacktrace`
27+
28+
#### MDC Fields
29+
MDC key/values are included in logged events.
30+
31+
#### Custom Fields
32+
Extra Custom fields can be declared in JSON form, these are added to all logged events.
33+
34+
#### Extra recommended Fields
35+
- `component` - Use to define the "component" (approximately application or a specific component of an application)
36+
- `env` - Use to define the "environment" such as dev, test, prod etc
37+
38+
These default by reading System Environment variables `COMPONENT` and `ENVIRONMENT` respectively and
39+
can also be explicitly set via configuration.
40+
41+
42+
43+
# How to use
44+
45+
#### 1 - Add dependency
46+
47+
For Java 11+ and Logback 1.2.x+ use version `1.0` of the dependency:
48+
```xml
49+
<dependency>
50+
<groupId>io.avaje</groupId>
51+
<artifactId>avaje-logback-encoder</artifactId>
52+
<version>1.0</version>
53+
</dependency>
54+
```
1055

11-
Add the encoder to your appender
56+
For Java 8 and Logback 1.1.x use version `1.0-java8` of the dependency.
57+
```xml
58+
<dependency>
59+
<groupId>io.avaje</groupId>
60+
<artifactId>avaje-logback-encoder</artifactId>
61+
<version>1.0-java8</version>
62+
</dependency>
63+
```
1264

65+
#### 2 - Use the Encoder in logback.xml
66+
67+
In `logback.xml` specify JsonEncoder as the encoder like:
1368
```xml
69+
<appender name="app" class="your.appender.class">
70+
<encoder class="io.avaje.logback.encoder.JsonEncoder"/>
71+
</appender>
72+
```
1473

74+
Optionally, configure with `component` and `environment` like:
75+
```xml
1576
<appender name="app" class="your.appender.class">
16-
<encoder class="io.avaje.logback.encoder.JsonEncoder">
17-
<-- configuration -->
18-
</encoder>
77+
<encoder class="io.avaje.logback.encoder.JsonEncoder">
78+
<component>my-component</component> <!-- OPTIONAL -->
79+
<enviroment>dev</enviroment> <!-- OPTIONAL -->
80+
</encoder>
1981
</appender>
2082
```
2183

22-
### JPMS Use
84+
Optionally specify custom fields that will appear in every LoggingEvent like:
85+
```xml
86+
<encoder class="io.avaje.logback.encoder.JsonEncoder">
87+
<customFields>{"appname":"myWebservice","roles":["orders","auth"]}</customFields>
88+
</encoder>
89+
```
90+
91+
#### AWS Lambda / StdOutAppender
92+
93+
For AWS Lambda log events are written to `System.out` and so this also provides
94+
an appender that defaults to using JsonEncoder to write log events to `System.out`.
95+
We can specify to use that appender like:
96+
97+
```xml
98+
<!-- Defaults to using the JsonEncoder -->
99+
<appender class="io.avaje.logback.encoder.StdOutAppender"/>
100+
```
101+
102+
Or with configuration options for component and environment like:
103+
104+
```xml
105+
<appender class="io.avaje.logback.encoder.StdOutAppender">
106+
<component>my-foo</component>
107+
</appender>
108+
```
109+
110+
Or with an encoder (potentially a different encoder):
111+
112+
```xml
113+
<appender class="io.avaje.logback.encoder.StdOutAppender">
114+
<encoder class="io.avaje.logback.encoder.JsonEncoder">
115+
<component>my-foo</component>
116+
<environment>prod</environment>
117+
<customFields>{"appname":"myWebservice","buildinfo":42, "roles":["customerorder","auth"],"f":true}</customFields>
118+
</encoder>
119+
</appender>
120+
```
121+
122+
123+
## Java modules
23124
To ensure `jlink` correctly determines the runtime modules required, add the following to your `module-info.java`:
24125

25126
```java
@@ -28,18 +129,7 @@ module my.module {
28129
}
29130
```
30131

31-
## Global Custom Fields
32-
33-
Add custom fields that will appear in every LoggingEvent like this :
34-
35-
```xml
36132

37-
<encoder class="io.avaje.logback.encoder.JsonEncoder">
38-
<customFields>{"appname":"myWebservice","roles":["customerorder","auth"],"buildinfo":{"version":"Version
39-
0.1.0-SNAPSHOT","lastcommit":"75473700d5befa953c45f630c6d9105413c16fe1"}}
40-
</customFields>
41-
</encoder>
42-
```
43133

44134
## Customizing Timestamp
45135

@@ -50,7 +140,6 @@ By default, timestamps are written as string values in the format specified by
50140
You can change the pattern like this:
51141

52142
```xml
53-
54143
<encoder class="io.avaje.logback.encoder.JsonEncoder">
55144
<timestampPattern>yyyy-MM-dd'T'HH:mm:ss.SSS</timestampPattern>
56145
</encoder>
@@ -64,7 +153,6 @@ The value of the `timestampPattern` can be any of the following:
64153
The formatter uses the default TimeZone of the host Java platform by default. You can change it like this:
65154

66155
```xml
67-
68156
<encoder class="io.avaje.logback.encoder.JsonEncoder">
69157
<timeZone>UTC</timeZone>
70158
</encoder>

src/main/java/io/avaje/logback/encoder/AwsLambdaAppender.java

Lines changed: 0 additions & 42 deletions
This file was deleted.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package io.avaje.logback.encoder;
2+
3+
import ch.qos.logback.classic.spi.ILoggingEvent;
4+
import ch.qos.logback.core.UnsynchronizedAppenderBase;
5+
import ch.qos.logback.core.encoder.Encoder;
6+
7+
import java.io.IOException;
8+
9+
/**
10+
* Appender that writes to STDOUT that defaults to using JsonEncoder.
11+
*/
12+
public final class StdOutAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
13+
14+
private Encoder<ILoggingEvent> encoder;
15+
16+
public StdOutAppender() {
17+
this.encoder = new JsonEncoder();
18+
}
19+
20+
@Override
21+
protected void append(ILoggingEvent event) {
22+
try {
23+
System.out.write(encoder.encode(event));
24+
} catch (IOException e) {
25+
// NOTE: When actually running on AWS Lambda, an IOException would never happen
26+
e.printStackTrace();
27+
}
28+
}
29+
30+
@Override
31+
public void start() {
32+
encoder.start();
33+
super.start();
34+
}
35+
36+
/**
37+
* Change the encoder from the default JsonEncoder.
38+
*/
39+
public void setEncoder(Encoder<ILoggingEvent> encoder) {
40+
this.encoder = encoder;
41+
}
42+
43+
/**
44+
* Set the component on an underlying JsonEncoder otherwise throw IllegalStateException.
45+
*/
46+
public void setComponent(String component) {
47+
if (encoder instanceof JsonEncoder) {
48+
((JsonEncoder) encoder).setComponent(component);
49+
} else {
50+
throw new IllegalStateException("Can only set component when using JsonEncoder");
51+
}
52+
}
53+
54+
/**
55+
* Set the environment on an underlying JsonEncoder otherwise throw IllegalStateException.
56+
*/
57+
public void setEnvironment(String environment) {
58+
if (encoder instanceof JsonEncoder) {
59+
((JsonEncoder) encoder).setEnvironment(environment);
60+
} else {
61+
throw new IllegalStateException("Can only set environment when using JsonEncoder");
62+
}
63+
}
64+
65+
}

src/test/java/io/avaje/logback/encoder/JsonEncoderTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ void throwable_usingConverter() {
101101

102102
@Test
103103
void awsAppender() {
104-
AwsLambdaAppender appender = new AwsLambdaAppender();
104+
StdOutAppender appender = new StdOutAppender();
105+
appender.setComponent("my-other");
106+
appender.setEnvironment("localdev");
105107
appender.start();
106108

107109
appender.append(createLogEvent());

0 commit comments

Comments
 (0)