Skip to content
A demonstration reactive custom Polly policy, to log faults and results the policy is configured to handle.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
.gitignore
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
GitVersionConfig.yaml
LICENSE.txt
README.md
appveyor.yml
build.bat
build.cake
build.ps1

README.md

Polly.Contrib.LoggingPolicy

This repo contains a custom Polly policy to log exceptions or handled results, then rethrow.

For more background on Polly see the main Polly repo.

Usage

Asynchronous executions

Define an Action<ILogger, Context, DelegateResult<TResult>> logAction to log exceptions or results. The Context input parameter allows filtering based on Polly's in-built execution metadata or context you pass in to the execution.

Action<ILogger, Context, DelegateResult<HttpResponseMessage>> logAction = (logger, context, outcome) => 
{
    logger.LogError("The call resulted in outcome: {happened}", outcome.Exception?.Message ?? outcome.Result.StatusCode.ToString());
}

Define a Func<Context, ILogger> loggerProvider to select an ILogger based on Context. This can use the extension method Context.GetLogger() defined on Polly.Context, if execution dispatch uses the Context.WithLogger(ILogger) overload, as demonstrated in the ConsoleApp example.

Configure the policy:

var loggingPolicy = Policy<HttpResponseMessage>
    .Handle<HttpRequestException>()
    .OrResult((int)response.StatusCode >= 500 || response.StatusCode == HttpStatusCode.RequestTimeout)
    .AsyncLog(ctx => ctx.GetLogger(), logAction);

The policy would typically be combined with other policies in a PolicyWrap - see below.

Synchronous executions

Define a logAction and loggerProvider as above.

Configure the policy, for example:

var loggingPolicy = Policy
    .Handle<Exception>()
    .Log(ctx => ctx.GetLogger(), logAction);

Using LoggingPolicy in PolicyWrap

The LoggingPolicy can be used in any position in a PolicyWrap.

It will log the faults it is configured to handle, based on faults bubbled outwards from the next-inner level.

  • A LoggingPolicy used outermost (configured first) in a PolicyWrap will log any eventual failure, after all policies of the PolicyWrap have exited.
  • A LoggingPolicy used innermost (configured last) in a PolicyWrap will log any failure from the underlying delegate executed through the PolicyWrap. For instance, if the PolicyWrap includes retries, a logging policy configured inside (after, in HttpClientFactory sequence) the retry policy, will log any exception/fault thrown by each try.

The sole purpose of the policy is to log. After logging, it bubbles faults further outwards to be handled by any policies further out or bubbled back to the caller.

Blog post example

The policy is an example for the blog [Custom policies Part III: Authoring a reactive custom policy](LINK WHEN PUBLISHED).

The policy in this repo differs in small ways from the blog post, as this repo offers LoggingPolicy in all four combinations:

  • LoggingPolicy (synchronous non-generic)
  • LoggingPolicy<TResult> (synchronous generic)
  • AsyncLoggingPolicy (asynchronous non-generic)
  • AsyncLoggingPolicy<TResult> (asynchronous generic)

Interested in developing your own custom policies?

See our blog series:

And see the templates for developing custom policies: Polly.Contrib.CustomPolicyTemplates.

You can’t perform that action at this time.