Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify "Emit a LogRecord" API #3383
Clarify "Emit a LogRecord" API #3383
Changes from all commits
4544f21
8860a88
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
Logs Bridge API
Status: Experimental
Table of Contents
Note: this document defines a log backend API. The API is not intended to be called by application developers directly. It is provided for logging library authors to build log appenders, which use this API to bridge between existing logging libraries and the OpenTelemetry log data model.
The Logs Bridge API consist of these main classes:
Logger
s.LoggerProvider
Logger
s can be accessed with aLoggerProvider
.In implementations of the API, the
LoggerProvider
is expected to be the stateful object that holds any configuration.Normally, the
LoggerProvider
is expected to be accessed from a central place. Thus, the API SHOULD provide a way to set/register and access a global defaultLoggerProvider
.LoggerProvider operations
The
LoggerProvider
MUST provide the following functions:Logger
Get a Logger
This API MUST accept the following parameters:
name
: This name uniquely identifies the instrumentation scope, such as the instrumentation library (e.g.io.opentelemetry.contrib.mongodb
), package, module or class name. If an application or library has built-in OpenTelemetry instrumentation, both Instrumented library and Instrumentation library may refer to the same library. In that scenario, thename
denotes a module name or component name within that library or application.version
(optional): Specifies the version of the instrumentation scope if the scope has a version (e.g. a library version). Example value: 1.0.0.schema_url
(optional): Specifies the Schema URL that should be recorded in the emitted telemetry.attributes
(optional): Specifies the instrumentation scope attributes to associate with emitted telemetry. This API MUST be structured to accept a variable number of attributes, including none.Logger
s are identified byname
,version
, andschema_url
fields. When more than oneLogger
of the samename
,version
, andschema_url
is created, it is unspecified whether or under which conditions the same or differentLogger
instances are returned. It is a user error to create Loggers with differentattributes
but the same identity.The term identical applied to
Logger
s describes instances where all identifying fields are equal. The term distinct applied toLogger
s describes instances where at least one identifying field has a different value.The effect of associating a Schema URL with a
Logger
MUST be that the telemetry emitted using theLogger
will be associated with the Schema URL, provided that the emitted data format is capable of representing such association.Logger
The
Logger
is responsible for emittingLogRecord
s.Logger operations
The
Logger
MUST provide functions to:LogRecord
Emit a LogRecord
LogRecord
s encapsulate the fields identified in theLogRecord
data model and are emitted to the processing pipeline using this API.The effect of calling this API is to emit a
LogRecord
to the processing pipeline.The API MUST accept the following parameters:
LogRecord
. The API MAY implicitly use the current Context as a default behavior.All parameters are optional.
Optional and required parameters
The operations defined include various parameters, some of which are marked optional. Parameters not marked optional are required.
For each optional parameter, the API MUST be structured to accept it, but MUST NOT obligate a user to provide it.
For each required parameter, the API MUST be structured to obligate a user to provide it.
Concurrency requirements
For languages which support concurrent execution the Logs Bridge APIs provide specific guarantees and safeties.
LoggerProvider - all methods are safe to be called concurrently.
Logger - all methods are safe to be called concurrently.
Artifact Naming
The Logs Bridge API is not intended to be called by application developers directly, and SHOULD include documentation that discourages direct use. However, in the event OpenTelemetry were to add a user facing API, the Logs Bridge API would be a natural starting point. Therefore, Log Bridge API artifact, package, and class names MUST NOT include the terms "bridge", "appender", or any other qualifier that would prevent evolution into a user facing API.
Usage
How to Create a Log4J Log Appender
A log appender implementation can be used to bridge logs into the Log SDK OpenTelemetry LogRecordExporters. This approach is typically used for applications which are fine with changing the log transport and is one of the supported log collection approaches.
The log appender implementation will typically acquire a Logger from the global LoggerProvider at startup time, then call Emit LogRecord for
LogRecord
s received from the application.Implicit Context Injection and Explicit Context Injection describe how an Appender injects
TraceContext
intoLogRecord
s.This same approach can be also used for example for:
Log appenders can be created in OpenTelemetry language libraries by OpenTelemetry maintainers, or by 3rd parties for any logging library that supports a similar extension mechanism. This specification recommends each OpenTelemetry language library to include out-of-the-box Appender implementation for at least one popular logging library.
Implicit Context Injection
When Context is implicitly available (e.g. in Java) the Appender can rely on automatic context propagation by NOT explicitly setting
Context
when calling emit a LogRecord.Some log libraries have mechanisms specifically tailored for injecting contextual information info logs, such as MDC in Log4j. When available, it may be preferable to use these mechanisms to set the Context. A log appender can then fetch the Context and explicitly set it when calling emit a LogRecord. This allows the correct Context to be included even when log records are emitted asynchronously, which can otherwise lead the Context to be incorrect.
TODO: clarify how works or doesn't work when the log statement call site and the log appender are executed on different threads.
Explicit Context Injection
In order for
TraceContext
to be recorded inLogRecord
s in languages where the Context must be provided explicitly (e.g. Go), the end user must capture the Context and explicitly pass it to the logging subsystem. The log appender must take this Context and explicitly set it when calling emit a LogRecord.Support for OpenTelemetry for logging libraries in these languages typically can be implemented in the form of logger wrappers that can capture the context once, when the span is created and then use the wrapped logger to execute log statements in a normal way. The wrapper will be responsible for injecting the captured context in the logs.
This specification does not define how exactly it is achieved since the actual mechanism depends on the language and the particular logging library used. In any case the wrappers are expected to make use of the Trace Context API to get the current active span.
See an example of how it can be done for zap logging library for Go.