AWS Lambda logs in context of traces
This page describes how to include TraceId
and SpanId
information in user-generated log messages. This way, you can associate log messages with the surrounding trace.
Prerequisites
- Set up AWS Lambda log collection or AWS log forwarding.
- Enable OpenTelemetry interoperability for the Lambda function.
- The log output generated by the AWS Lambda function must be formatted so that the
TraceId
andSpanId
information can be picked up. The expected format of the enriched fields in an unstructured log is as follows:- Encapsulated in square brackets
[]
with a!dt
prefix dt.trace_id
anddt.span_id
must be hex-encoded strings Example:[!dt dt.trace_id=0af7651916cd43dd8448eb211c80319c,dt.span_id=00f067aa0ba902b7]
- Encapsulated in square brackets
OpenTelemetry Python
In the example below, a dt_log
function has been created to enrich a given log message with trace_id
and span_id
information. Printing this enriched message to stdout
associates the log message with the currently active span in the Dynatrace web UI.
1from opentelemetry import trace23def dt_log(msg):4 ctx = trace.get_current_span().get_span_context()5 trace_id = format(ctx.trace_id, "032x")6 span_id = format(ctx.span_id, "016x")7 print("[!dt dt.trace_id={},dt.span_id={}] - {}".format(trace_id, span_id, msg));89def lambda_handler(event, context):10 msg = "Hello World"1112 dt_log(msg)1314 return {15 "statusCode": 200,16 "body": msg17 }
OpenTelemetry JavaScript (Node.js)
In the example below, a dt_log
function has been created to enrich a given log message with trace_id
and span_id
information. Printing this enriched message to stdout
associates the log message with the currently active span in the Dynatrace web UI.
1const opentelemetry = require('@opentelemetry/api');23function dtLog(msg) {4 const spanContext = opentelemetry.trace.getSpanContext(opentelemetry.context.active()) ?? opentelemetry.INVALID_SPAN_CONTEXT;5 console.log(`[!dt dt.trace_id=${spanContext.traceId},dt.span_id=${spanContext.spanId}] - ${msg}`);6}78exports.handler = function(event, context) {9 const msg = "Hello World"1011 dtLog(msg);1213 context.succeed({14 statusCode: 200,15 body: msg16 });17};
Logs created by some commonly used Node.js logging frameworks are automatically associated with traces by using the corresponding OpenTelemetry instrumentations.
Node.js logging framework | OpenTelemetry instrumentation |
---|---|
In the example below, the winston instrumentation is used to enrich a winston info log with TraceId and SpanId. The created log is associated with the currently active span in the Dynatrace web UI.
1const otelApi = require('@opentelemetry/api');2const { registerInstrumentations } = require('@opentelemetry/instrumentation');3const { WinstonInstrumentation } = require('@opentelemetry/instrumentation-winston');45registerInstrumentations({6 instrumentations: [new WinstonInstrumentation()],7});89const winston = require('winston');1011exports.handler = function (event, context, callback) {12 const logger = winston.createLogger({13 transports: [new winston.transports.Console()],14 });1516 logger.info('winston info log');1718 context.succeed({19 statusCode: 200,20 body: 'Hello from AWS Lambda Node.js',21 });22}
OpenTelemetry Java
In the example below, a dtLog
method has been created to enrich a given log message with TraceId
and SpanId
information. Printing this enriched message via System.out
associates the log message with the currently active span in the Dynatrace web UI.
1package com.amazonaws.lambda.demo;23import com.amazonaws.services.lambda.runtime.Context;4import com.amazonaws.services.lambda.runtime.RequestHandler;56import io.opentelemetry.api.trace.Span;7import io.opentelemetry.api.trace.SpanContext;89public class HelloJava implements RequestHandler<Object, String> {1011 private static void dtLog(final String msg) {12 SpanContext spanContext = Span.current().getSpanContext();13 System.out.printf(14 "[!dt dt.trace_id=%s,dt.span_id=%s] - %s%n",15 spanContext.getTraceId(),16 spanContext.getSpanId(),17 msg18 );19 }2021 @Override22 public String handleRequest(Object input, Context context) {23 String msg = "Hello World";2425 dtLog(msg);2627 return msg;28 }29}