Skip to content

DiagnosticSource Tracing #1126

@alistairjevans

Description

@alistairjevans

With the new pipelines architecture coming in v6.0, the ability to trace Autofac operations has been significantly improved.

At the moment, there is an interface IResolvePipelineTracer, that can be implemented to watch the various stages of the Resolve Pipeline.

There is also a default Diagnostic tracer, DefaultDiagnosticTracer, which I put in as a debugging tool more than anything else really, which dumps out detailed trace data for each resolve operation, for example:

Resolve Operation Starting
{
  Resolve Request Starting
  {
    Service: Autofac.Specification.Test.Features.DecoratorTests+IDecoratedService
    Component: Autofac.Specification.Test.Features.DecoratorTests+ImplementorA

    Pipeline:
    -> CircularDependencyDetectorMiddleware
      -> ScopeSelectionMiddleware
        -> DecoratorMiddleware
          -> SharingMiddleware
            -> ActivatorErrorHandlingMiddleware
              -> DisposalTrackingMiddleware
                -> ImplementorA (ReflectionActivator)
                <- ImplementorA (ReflectionActivator)
              <- DisposalTrackingMiddleware
            <- ActivatorErrorHandlingMiddleware
          <- SharingMiddleware
          Resolve Operation Starting
          {
            Resolve Request Starting
            {
              Service: Decorator (Autofac.Specification.Test.Features.DecoratorTests+IDecoratedService)
              Component: Autofac.Specification.Test.Features.DecoratorTests+DecoratorA
              Target: Autofac.Specification.Test.Features.DecoratorTests+ImplementorA

              Pipeline:
              -> CircularDependencyDetectorMiddleware
                -> ScopeSelectionMiddleware
                  -> DecoratorMiddleware
                    -> SharingMiddleware
                      -> ActivatorErrorHandlingMiddleware
                        -> DisposalTrackingMiddleware
                          -> DecoratorA (ReflectionActivator)
                          <- DecoratorA (ReflectionActivator)
                        <- DisposalTrackingMiddleware
                      <- ActivatorErrorHandlingMiddleware
                    <- SharingMiddleware
                  <- DecoratorMiddleware
                <- ScopeSelectionMiddleware
              <- CircularDependencyDetectorMiddleware
            }
            Resolve Request Succeeded; result instance was Autofac.Specification.Test.Features.DecoratorTests+DecoratorA
          }
          Operation Succeeded; result instance was Autofac.Specification.Test.Features.DecoratorTests+DecoratorA
        <- DecoratorMiddleware
      <- ScopeSelectionMiddleware
    <- CircularDependencyDetectorMiddleware
  }
  Resolve Request Succeeded; result instance was Autofac.Specification.Test.Features.DecoratorTests+DecoratorA
}
Operation Succeeded; result instance was Autofac.Specification.Test.Features.DecoratorTests+DecoratorA

In addition to this diagnostic tooling, it may also be good to add support for the .NET Diagnostic Source, as a production-time tracing feature.

I think it's important to distinguish between investigative tracing, and production tracing.

https://github.com/dotnet/runtime/blob/master/src/libraries/System.Diagnostics.DiagnosticSource/src/DiagnosticSourceUsersGuide.md

There are probably the following things to consider:

  • Does the DiagnosticSource tracing just become another implementation of IResolvePipelineTracer, which feeds data to a DiagnosticSource? Should it instead just be baked into Autofac generally?

My instinct is that if people aren't using the DiagnosticSource, they may not want the performance cost of us writing to it (or trying to write to it). It could either be a custom tracer they explicitly attach, or a global ContainerBuilder option that lets you enable DiagnosticSource tracing separately from regular tracing.

  • What data we capture? We should probably capture less than the detailed tracer, but capturing ResolveRequests and any errors would probably be useful.

  • How do we mitigate any run-time performance concerns?

Anything else?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions