Skip to content

Commit

Permalink
Change OTel quickstart to use log4j2 instead of logback
Browse files Browse the repository at this point in the history
Log4j2's `JsonTemplateLayout` supports most of the Cloud Logging special JSON keys directly through the [`GcpLayout` event template](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html#event-templates). I still needed to map the OTel MDC keys for trace correlation, but am planning to contribute [this upstream](https://github.com/apache/logging-log4j2/blob/rel/2.17.2/log4j-layout-template-json/src/main/resources/GcpLayout.json).

One outstanding issue is converting the `trace_flags` hex value to a boolean, but it doesn't break Cloud Console if `logging.googleapis.com/trace_sampled` key is unset/false. See apache/logging-log4j2#2482.
  • Loading branch information
aabmass committed Apr 18, 2024
1 parent 97a8f20 commit b2e696e
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 8 deletions.
12 changes: 9 additions & 3 deletions examples/instrumentation-quickstart/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,15 @@ spotless {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'

// Cannot be updated until logback is updated to 1.3+, probably in the next Spring Boot
// major version
implementation 'net.logstash.logback:logstash-logback-encoder:7.3'
// Use log4j2 for logging
// https://docs.spring.io/spring-boot/docs/2.7.18/reference/html/howto.html#howto.logging.log4j
implementation "org.springframework.boot:spring-boot-starter-log4j2"
modules {
module("org.springframework.boot:spring-boot-starter-logging") {
replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback")
}
}
implementation "org.apache.logging.log4j:log4j-layout-template-json"

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.testcontainers:testcontainers:1.19.4'
Expand Down
24 changes: 19 additions & 5 deletions examples/instrumentation-quickstart/otel-collector-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,26 @@ receivers:
layout: '%Y-%m-%dT%H:%M:%S.%fZ'
severity:
parse_from: body.severity
preset: none
# parse minimal set of severity strings that Cloud Logging explicitly supports
# https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity
mapping:
debug: debug
info: info
info3: notice
warn: warning
error: error
fatal: critical
fatal3: alert
fatal4: emergency

# set trace_flags to SAMPLED if GCP attribute is set to true
- type: add
field: body.trace_flags
value: "01"
if: body["logging.googleapis.com/trace_sampled"] == true
# TODO(aaronabbott): uncomment once the log4j2 config is correctly outputing the
# logging.googleapis.com/trace_sampled value
## set trace_flags to SAMPLED if GCP attribute is set to true
# - type: add
# field: body.trace_flags
# value: "01"
# if: body["logging.googleapis.com/trace_sampled"] == true

# parse the trace context fields from GCP attributes
- type: regex_parser
Expand Down
48 changes: 48 additions & 0 deletions examples/instrumentation-quickstart/src/main/resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--
Copyright 2024 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<!-- [START opentelemetry_instrumentation_setup_logging] -->
<!-- Format JSON logs for the Cloud Logging agent
https://cloud.google.com/logging/docs/structured-logging#special-payload-fields -->

<!-- Log4j2's JsonTemplateLayout includes a template for Cloud Logging's special JSON fields
https://logging.apache.org/log4j/2.x/manual/json-template-layout.html#event-templates -->
<JsonTemplateLayout eventTemplateUri="classpath:GcpLayout.json">
<!-- Extend the included GcpLayout to include the trace and span IDs from Mapped
Diagnostic Context (MDC) so that Cloud Logging can correlate Logs and Spans -->
<EventTemplateAdditionalField
key="logging.googleapis.com/trace"
format="JSON"
value='{"$resolver": "mdc", "key": "trace_id"}'
/>
<EventTemplateAdditionalField
key="logging.googleapis.com/spanId"
format="JSON"
value='{"$resolver": "mdc", "key": "span_id"}'
/>
</JsonTemplateLayout>
<!-- [END opentelemetry_instrumentation_setup_logging] -->
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>

0 comments on commit b2e696e

Please sign in to comment.