Operation context

Operation context represents a hierarchy of logical operations or steps in application code flow (handling a query, sending a request, performing an iteration of a periodical process).

Unlike source context, operation context is bound to current ExecutionContext and can be manipulated independently of any log instances.

Operation context is maintained by defining named scopes that represent logical operations.

Structure

Like source context, operation context is also hierarchical. Nested operation scopes produce a stack-based sequence of contextual values:

// current operation context is null
using (new OperationContextToken("op1"))
{
// current operation context is ["op1"]
using (new OperationContextToken("op2"))
{
// current operation context is ["op1", "op2"]
using (new OperationContextToken("op3"))
{
// current operation context is ["op1", "op2", "op3"]
}
// current operation context is ["op1", "op2"]
}
// current operation context is ["op1"]
}
// current operation context is null

Implementation details

Operation context is implemented as an extension over log interface. It can be enabled as follows:

log = log.WithOperationContext();

Returned log instance will enrich incoming log events with a special well-known OperationContext property whose value is represented by OperationContextValue class.

Context scopes are started by constructing OperationContextTokens and ended by disposing these tokens.

Rendering in text-based logs

Here's an example of how text-based logs render operation context:

var log = new SynchronousConsoleLog().WithOperationContext();
using (new OperationContextToken("op1"))
{
log.Info("Message 1");
using (new OperationContextToken("op2"))
{
log.Info("Message 2");
using (new OperationContextToken("op3"))
{
log.Info("Message 3");
}
}
}

Sample output from this code:

2019-03-10 01:30:06,727 INFO [op1] Message 1
2019-03-10 01:30:06,761 INFO [op1] [op2] Message 2
2019-03-10 01:30:06,762 INFO [op1] [op2] [op3] Message 3