Keys and Context Data

Dylan Reisenberger edited this page Apr 11, 2018 · 6 revisions

Policy keys and context data are intended to provide supplementary information that can be used to track policy activity and events, in logging and metrics. (See the Roadmap for metrics proposals.)

Every single call through a Polly policy carries an instance of Context with it: this carries the values of the keys, for each call.

Available keys

PolicyWrapKey

Key type PolicyWrapKey
Description / Purpose A unique key for each PolicyWrap instance. While Context.PolicyKey varies with each policy instance used in a wrap, Context.PolicyWrapKey remains constant over the wrap.
Primary use Include in emitted events/stats/logging, to indicate PolicyWrap in use
Additional use (forthcoming) Retrieve a Policy Wrap from Registry?
Default if not set short-type-name+some-guid-part; null if execution not part of a PolicyWrap
Behaviour in PolicyWrap Retains own value. In a nested-wrap, takes value of outermost PolicyWrap in the wrap.
How specified? extension method .WithPolicyKey(string policyKey) on PolicyWrap; set-once-only enforced
How exposed? PolicyWrap.PolicyKey; exposed to execution as Context.PolicyWrapKey

PolicyKey

Key type Policy Key
Description / Purpose A unique key for an individual configured Policy instance
Primary use Include in emitted events/stats/logging, to indicate policy in use
Additional use (forthcoming) Retrieve a policy from registry
Default if not set short-type-name+some-guid-part
Behaviour in PolicyWrap Retains own value
How specified? extension method .WithPolicyKey(string policyKey) on Policy; set-once-only enforced
How exposed? Policy.PolicyKey; exposed to execution as Context.PolicyKey

OperationKey

Renamed OperationKey from v5.9. Prior, was ExecutionKey. See #426.

Key type OperationKey
Description / Purpose A unique key for each call site usage of a policy. (A single policy instance may be re-used in multiple code locations (see wiki)).
Primary use Used by CachePolicy as the cache key for the given execution
Additional use Include in emitted events/stats/logging, to indicate where policy in use
Default if not set null
Behaviour in PolicyWrap Takes value passed by any preceding policy in the wrap
How specified? by passing a new Context(operationKey) with the Execute call
How exposed? Context.OperationKey

CorrelationId

Renamed CorrelationId from v5.9. Prior, was ExecutionGuid. See #426.

Key type CorrelationId
Description / Purpose A unique GUID for each invocation through a policy
Primary use Distinguish individual calls through the policy, so that stats-interpreting code can distinguish calls in multi-threaded environment
Additional use .
Default if not set Guid.NewGuid()
Behaviour in PolicyWrap Takes value passed by any preceding policy in the wrap
How specified? not for the user to specify - generated randomly by each call to Execute
How exposed? Context.CorrelationId

Usage

// Identify policies with a PolicyKey, using the WithPolicyKey() extension method
// (for example, for correlation in logs or metrics)

var policy = Policy
    .Handle<DataAccessException>()
    .Retry(3, onRetry: (exception, retryCount, context) =>
       {
           logger.Error($"Retry {retryCount} of {context.PolicyKey} at {context.OperationKey}, due to: {exception}.");
       })
    .WithPolicyKey("MyDataAccessPolicy");

// Identify call sites with an OperationKey, by passing in a Context
var customerDetails = policy.Execute(myDelegate, new Context("GetCustomerDetails"));

// "MyDataAccessPolicy" -> context.PolicyKey 
// "GetCustomerDetails  -> context.OperationKey


// Pass additional custom information from call site into the context
var policy = Policy
    .Handle<DataAccessException>()
    .Retry(3, onRetry: (exception, retryCount, context) =>
       {
           logger.Error($"Retry {retryCount} of {context.PolicyKey} at {context.OperationKey}, getting {context["Type"]} of id {context["Id"]}, due to: {exception}.  CorrelationId: {context.CorrelationId}");
       })
    .WithPolicyKey("MyDataAccessPolicy");

int id = ... // customer id from somewhere
var customerDetails = policy.Execute(() => GetCustomer(id), 
    new Context("GetCustomerDetails", new Dictionary<string, object>() {{"Type","Customer"},{"Id",id}}
    ));
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.