Class ScopedLoggingContext
- java.lang.Object
-
- com.google.common.flogger.context.ScopedLoggingContext
-
public abstract class ScopedLoggingContext extends Object
A user facing API for creating and modifying scoped logging contexts in applications.Scoped contexts provide a way for application code to attach metadata and control the behaviour of logging within well defined contexts. This is most often associated with making "per request" modifications to logging behaviour such as:
- Adding a request ID to every log statement.
- Forcing logging at a finer level for a specific request (e.g. based on a URL debug parameter).
Contexts are nestable and new contexts can be added to provide additional metadata which will be available to logging as long as the context is installed.
Note that in the current API contexts are also modifiable after creation, but this usage is discouraged and may be removed in future. The problem with modifying contexts after creation is that, since contexts can be shared between threads, it is potentially confusing if tags are added to a context when it is being used concurrently by multiple threads.
Note that since logging contexts are designed to be modified by code in libraries and helper functions which do not know about each other, the data structures and behaviour of logging contexts are carefully designed to avoid any accidental "undoing" of existing behaviour. In particular:
- Tags can only be added to contexts, never modified or removed.
- Logging that's enabled by one context cannot be disabled from within a nested context.
One possibly surprising result of this behaviour is that it's not possible to disable logging from within a context. However this is quite intentional, since overly verbose logging should be fixed by other mechanisms (code changes, global logging configuration), and not on a "per request" basis.
Depending on the framework used, it's possible that the current logging context will be automatically propagated to some or all threads or sub-tasks started from within the context. This is not guaranteed however and the semantic behaviour of context propagation is not defined by this class.
In particular, if you haven't explicitly opened a context in which to run your code, there is no guarantee that a default "global" context exists. In this case any attempts to add metadata (e.g. via
addTags(com.google.common.flogger.context.Tags)) will fail, returningfalse.Context support and automatic propagation is heavily reliant on Java platform capabilities, and precise behaviour is likely to differ between runtime environments or frameworks. Context propagation may not behave the same everywhere, and in some situations logging contexts may not be supported at all. Methods which attempt to affect context state may do nothing in some environments, or when called at some points in an application. If application code relies on modifications to an existing, implicit logging context, it should always check the return values of any modification methods called (e.g.
addTags(Tags)).
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classScopedLoggingContext.BuilderA fluent builder API for creating and installing new context scopes.static classScopedLoggingContext.InvalidLoggingContextStateExceptionThrown if it can be determined that contexts have been closed incorrectly.static interfaceScopedLoggingContext.LoggingContextCloseableA logging context which must be closed in the reverse order to which it was created.static classScopedLoggingContext.ScopeListLightweight internal helper class for context implementations to manage a list of scopes.
-
Constructor Summary
Constructors Modifier Constructor Description protectedScopedLoggingContext()
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description <T> booleanaddMetadata(MetadataKey<T> key, T value)Adds a single metadata key/value pair to the current context.booleanaddTags(Tags tags)Adds tags to the current set of log tags for the current context.booleanapplyLogLevelMap(LogLevelMap logLevelMap)Applies the given log level map to the current context.static ScopedLoggingContextgetInstance()Returns the platform/framework specific implementation of the logging context API.abstract ScopedLoggingContext.BuildernewContext()Creates a new context builder to which additional logging metadata can be attached before being installed or used to wrap some existing code.abstract ScopedLoggingContext.BuildernewContext(ScopeType scopeType)Creates a new context builder to which additional logging metadata can be attached before being installed or used to wrap some existing code.ScopedLoggingContext.BuildernewScope()Deprecated.implementers and callers should usenewContext()instead.
-
-
-
Method Detail
-
getInstance
public static ScopedLoggingContext getInstance()
Returns the platform/framework specific implementation of the logging context API. This is a singleton value and need not be cached by callers. If logging contexts are not supported, this method will return an empty context implementation which has no effect.
-
newContext
public abstract ScopedLoggingContext.Builder newContext()
Creates a new context builder to which additional logging metadata can be attached before being installed or used to wrap some existing code.ScopedLoggingContext ctx = ScopedLoggingContext.getInstance(); Foo result = ctx.newContext().withTags(Tags.of("my_tag", someValue)).call(MyClass::doFoo);Implementations of this API must return a subclass of
ScopedLoggingContext.Builderwhich can install all necessary metadata into a new context from the builder's current state.Note for users: if you don't need an instance of
ScopedLoggingContextfor some reason such as testability (injecting it, for example), consider using the static methods inScopedLoggingContextsinstead to avoid the need to callgetInstance():Foo result = ScopedLoggingContexts.newContext() .withTags(Tags.of("my_tag", someValue)) .call(MyClass::doFoo);
-
newContext
public abstract ScopedLoggingContext.Builder newContext(ScopeType scopeType)
Creates a new context builder to which additional logging metadata can be attached before being installed or used to wrap some existing code.This method is the same as
newContext()except it additionally binds a newScopeTypeinstance to the newly created context. This allows log statements to control stateful logging operations (e.g. rate limiting) using theper(ScopeType)method.Note for users: if you don't need an instance of
ScopedLoggingContextfor some reason such as testability (injecting it, for example), consider using the static methods inScopedLoggingContextsinstead to avoid the need to callgetInstance().
-
newScope
@Deprecated public ScopedLoggingContext.Builder newScope()
Deprecated.implementers and callers should usenewContext()instead. This method will be removed in the next Flogger release.Deprecated equivalent tonewContext().
-
addTags
@CanIgnoreReturnValue public boolean addTags(Tags tags)
Adds tags to the current set of log tags for the current context. Tags are merged together and existing tags cannot be modified. This is deliberate since two pieces of code may not know about each other and could accidentally use the same tag name; in that situation it's important that both tag values are preserved.Furthermore, the types of data allowed for tag values are strictly controlled. This is also very deliberate since these tags must be efficiently added to every log statement and so it's important that they resulting string representation is reliably cacheable and can be calculated without invoking arbitrary code (e.g. the
toString()method of some unknown user type).- Returns:
- false if there is no current context, or scoped contexts are not supported.
-
addMetadata
@CanIgnoreReturnValue public <T> boolean addMetadata(MetadataKey<T> key, T value)
Adds a single metadata key/value pair to the current context.Unlike
Tags, which have a well defined value ordering, independent of the order in which values were added, context metadata preserves the order of addition. As such, it is not advised to add values for the same metadata key from multiple threads, since that may create non-deterministic ordering. It is recommended (where possible) to add metadata when building a new context, rather than adding it to context visible to multiple threads.
-
applyLogLevelMap
@CanIgnoreReturnValue public boolean applyLogLevelMap(LogLevelMap logLevelMap)
Applies the given log level map to the current context. Log level settings are merged with any existing setting from the current (or parent) contexts such that logging will be enabled for a log statement if:- It was enabled by the given map.
- It was already enabled by the current context.
The effects of this call will be undone only when the current context terminates.
- Returns:
- false if there is no current context, or scoped contexts are not supported.
-
-