Skip to content

Commit

Permalink
version 2 rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
osiegmar committed Nov 5, 2023
1 parent 9303ecc commit 6757bfb
Show file tree
Hide file tree
Showing 12 changed files with 667 additions and 470 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Java 11
- uses: actions/checkout@v4
- name: Set up Java 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
java-version: '17'
- uses: gradle/wrapper-validation-action@v1
- uses: gradle/gradle-build-action@v2
- name: Build with Gradle
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.0] - 2023-??-??
### Changed
- Complete rewrite
- Update to Java 17
- Update Logback dependency to 1.4.11

## [1.1.1] - 2022-01-04
### Changed
- Update Logback dependency to 1.2.10
Expand Down
148 changes: 95 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# Logback awslogs JSON encoder

> :point_up: Logback contains a [JsonEncoder](https://logback.qos.ch/manual/encoders.html#JsonEncoder) since 1.3.8.
> Therefore I do no longer consider this library as relevant.
[![build](https://github.com/osiegmar/logback-awslogs-json-encoder/actions/workflows/build.yml/badge.svg)](https://github.com/osiegmar/logback-awslogs-json-encoder/actions/workflows/build.yml)
[![javadoc](https://javadoc.io/badge2/de.siegmar/logback-awslogs-json-encoder/javadoc.svg)](https://javadoc.io/doc/de.siegmar/logback-awslogs-json-encoder)
[![Maven Central](https://img.shields.io/maven-central/v/de.siegmar/logback-awslogs-json-encoder.svg)](https://search.maven.org/artifact/de.siegmar/logback-awslogs-json-encoder)
[![Maven Central](https://img.shields.io/maven-central/v/de.siegmar/logback-awslogs-json-encoder.svg)](https://central.sonatype.com/artifact/de.siegmar/logback-awslogs-json-encoder)

Logback encoder for producing JSON output that is handled by
AWS [CloudWatch Logs Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html). This
library has no external dependencies and thus very light footprint.

Since version 1.3.8, Logback ships with a [JsonEncoder](https://logback.qos.ch/manual/encoders.html#JsonEncoder) itself.
Unfortunately that JsonEncoder produces log output that is poorly suited for use with CloudWatch Logs (Insights).

## Features

- Forwarding of MDC (Mapped Diagnostic Context)
Expand All @@ -21,13 +20,12 @@ library has no external dependencies and thus very light footprint.

## Requirements

- Java 8
- Logback 1.2.10
- Java 17
- Logback 1.4.11

## Prerequisites

Ensure that the task definition of your ECS task uses the `awslogs` log driver with
the option `awslogs-datetime-format` set to `%Y-%m-%dT%H:%M:%S.%f%z`.
Ensure that the task definition of your ECS task uses the `awslogs` log driver.

A full example (excerpt from a full task definition JSON) could look like this:

Expand All @@ -37,16 +35,15 @@ A full example (excerpt from a full task definition JSON) could look like this:
"logDriver": "awslogs",
"options": {
"awslogs-group": "myloggroup",
"awslogs-region": "eu-central-1",
"awslogs-datetime-format": "%Y-%m-%dT%H:%M:%S.%f%z"
"awslogs-region": "eu-central-1"
}
}
}
```

## Example
## Configuration

Simple configuration:
A basic configuration with defaults would look like this:

```xml
<configuration>
Expand All @@ -56,57 +53,102 @@ Simple configuration:
</appender>

<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="STDOUT"/>
</root>

</configuration>
```

Enhanced configuration:
An extended version (with all default values set explicitly, custom static fields and mapper) would look like this:

```xml
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="de.siegmar.logbackawslogsjsonencoder.AwsJsonLogEncoder">
<includeRawMessage>false</includeRawMessage>
<includeMarker>true</includeMarker>
<includeMdcData>true</includeMdcData>
<includeCallerData>false</includeCallerData>
<includeRootCauseData>false</includeRootCauseData>
<messageLayout class="ch.qos.logback.classic.PatternLayout">
<pattern>%m%nopex</pattern>
</messageLayout>
<fullMessageLayout class="ch.qos.logback.classic.PatternLayout">
<pattern>%m%n</pattern>
</fullMessageLayout>
<staticField>app_name:backend</staticField>
<staticField>os_arch:${os.arch}</staticField>
<staticField>os_name:${os.name}</staticField>
<staticField>os_version:${os.version}</staticField>
</encoder>
</appender>

<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="de.siegmar.logbackawslogsjsonencoder.AwsJsonLogEncoder">
<includeTimestamp>true</includeTimestamp>
<includeNanoseconds>false</includeNanoseconds>
<includeSequenceNumber>false</includeSequenceNumber>
<includeLevelName>true</includeLevelName>
<includeThreadName>true</includeThreadName>
<includeLoggerName>true</includeLoggerName>
<includeFormattedMessage>true</includeFormattedMessage>
<includeRawMessage>false</includeRawMessage>
<includeStacktrace>true</includeStacktrace>
<includeRootCause>false</includeRootCause>
<includeMarker>true</includeMarker>
<includeMdc>true</includeMdc>
<includeKeyValues>true</includeKeyValues>
<includeCaller>false</includeCaller>

<staticField>app_name:backend</staticField>
<staticField>os_arch:${os.arch}</staticField>

<customMapper class="your.custom.Mapper"/>
</encoder>
</appender>

<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>

</configuration>
```

## Configuration
## Example output

Typical output:

`de.siegmar.logbackawslogsjsonencoder.AwsJsonLogEncoder`

* **includeRawMessage**: If true, the raw message (with argument placeholders) will be included, too.
Default: false.
* **includeMarker**: If true, logback markers will be included, too. Default: true.
* **includeMdcData**: If true, MDC keys/values will be included, too. Default: true.
* **includeCallerData**: If true, caller data (source file-, method-, class name and line) will be
included, too. Default: false.
* **includeRootCauseData**: If true, root cause exception of the exception passed with the log
message will be exposed in the root_cause_class_name and root_cause_message fields.
Default: false.
* **messageLayout**: Message format for messages without an exception. Default: `"%m%nopex"`.
* **fullMessageLayout**: Message format for messages with an exception. Default: `"%m%n"`.
* **staticFields**: Additional, static fields to include. Defaults: none.
```json
{
"timestamp": 1698595093642,
"level": "DEBUG",
"thread": "Test worker",
"logger": "my.app.MyClass",
"message": "Message 1"
}
```

Maximal output:

```json
{
"timestamp": 1698595093642,
"nanoseconds": 642725000,
"sequenceNumber": 0,
"level": "DEBUG",
"thread": "Test worker",
"logger": "my.app.MyClass",
"message": "Message 1",
"rawMessage": "Message {}",
"markers": {
"foo": 1,
"bar": 1
},
"mdc": {
"foo": "bar",
"baz": null
},
"keyValues": {
"foo": "bar",
"bar": null,
"null": "bar"
},
"caller": {
"file": "NativeMethodAccessorImpl.java",
"line": -2,
"class": "jdk.internal.reflect.NativeMethodAccessorImpl",
"method": "invoke0"
},
"stacktrace": "java.lang.IllegalStateException: Error processing data\n\tat my.app.MyClass.foo(MyClass.java:123)",
"rootCause": {
"class": "java.lang.IllegalStateException",
"message": "Error processing data"
},
"staticFields": {
"app_name": "backend",
"os_arch": "amd64"
},
"custom": "A field added by a custom mapper"
}
```
5 changes: 2 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ version = "2.0.0-SNAPSHOT"

java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
languageVersion = JavaLanguageVersion.of(17)
}
withJavadocJar()
withSourcesJar()
}

Expand All @@ -26,7 +25,7 @@ dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation("org.assertj:assertj-core:3.11.1")
testImplementation("net.javacrumbs.json-unit:json-unit-assertj:2.38.0")
testImplementation("net.javacrumbs.json-unit:json-unit-assertj:3.2.2")
testImplementation("com.fasterxml.jackson.core:jackson-databind:2.15.2")
}

Expand Down
6 changes: 5 additions & 1 deletion config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,14 @@
</module>

<module name="LineLength">
<property name="max" value="100"/>
<property name="max" value="120"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>

<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>

<module name="TreeWalker">

<property name="tabWidth" value="4"/>
Expand Down
4 changes: 4 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version("0.7.0")
}

rootProject.name = "logback-awslogs-json-encoder"
Loading

0 comments on commit 6757bfb

Please sign in to comment.