Giter Club home page Giter Club logo

autofac-serilog-integration's People

Contributors

adrianjsclark avatar augustoproiete avatar driedas avatar jafin avatar krajek avatar mayuanyang avatar michaelpetrinolis avatar nblumhardt avatar rudratransact avatar srogovtsev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

autofac-serilog-integration's Issues

Autofac 6 migration

Hi,

The Autofac team did a lot of fundametal changes in version 6 (what's new).
Specifically:

RegistrationBuilder.RegistrationData no longer exposes the configured ActivatedHandlers, ActivatingHandlers or PreparingHandlers, and IComponentRegistration no longer exposes Preparing, Activating or Activated events.

And current "autofac-serilog-integration" version (4.0) throw an exception, because they've removed a couple of used by you methods.
Are you going to fix it soon ?

Thanks,

Reference for breaking changes between 1.x and 2.x?

Hi @nblumhardt,

Love this integration and am just trying to figure out which version to implement.

We currently have Autofac v3.5.2 in our project and haven't made the leap to 4.x yet (though it's on my list).

Is there anything I should be aware of related to v1.0.15 of this package as opposed to v2.0.0 which depends on Autofac v4? I couldn't find release notes anywhere, but I might not be looking in the correct place.

Unable to install the package in project framework targeted 4.0

The package is not installed if your project framework version = v4.0
Install-Package : Could not install package 'AutofacSerilogIntegration x.x.x'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

Using ILogger from 'Microsoft.Extensions.Logging.Abstractions'

My goal is to inject the Serilog into the host project (.net4.8) and in the domain projects (I use some DDD pattern) use ILogger from 'Microsoft.Extensions.Logging.Abstractions'.
But I see that registering the Serilog is for only the Serilog.ILogger interface and this suggests that I should only use Serilog.ILogger.
Or is the current nuget package not for my case?...
I saw another nuget (link) which allows the use of abstraction from Microsoft.

Injection doesn't work for `AutofacChildLifetimeScopeConfigurationAdapter`

I have an application with the child scope built using this manual: https://github.com/autofac/Documentation/blob/master/docs/integration/aspnetcore.rst#using-a-child-scope-as-a-root

I have this code for registering Serilog in the child container

public void ConfigureContainer(AutofacChildLifetimeScopeConfigurationAdapter adapter)
{
    adapter.Add(builder =>
    {
        builder.RegisterLogger();
    });
}

Parent container has builder.RegisterLogger(); as well.
Context is missing in all cases:

  1. Do not configure child container at all and missing UseSerilog
  2. Add UseSerilog only
  3. Add ConfigureContainer call from the sample above
  4. 2nd + 3rd options together.

Sample log entry with the missing context between <>:
2021-02-03 16:53:37Z [4] DBG <> User login was denied. Reason = InvalidUsernameOrPassword.

Support AutoFac 9, Serilog 3, .NET 4.8.1

Hello, I am using the above versions. When I installed this package, I get a yellow triangle:

image

Visual Studio is fantastic about not telling me why. I can only assume all of my dependencies and my project are not a match for this project. Is an update possible? Did I install it wrong?

SourceContext not being injected into BackgroundService (net core 3.1 app autofac5)

Firstly, I don't believe I've correctly identified the problem but will describe as best to my understanding.

In a net core core 3.1 app, we have background services that trigger at startup. What was being observed was sourcecontext was set on any log messages, yet it does appear fine on the main web process.

Pulled the code locally and updated to autofac 5, the signature for AttachToComponentRegistration was different so updated. Created sample scenario site, and observed that the SourceContext prop is now being correctly applied to the backgroundService.

System.MissingMethodException: Method not found: 'Void Autofac.Core.IComponentRegistration.add_Preparing

when I upgrade Autofac to vsesion 6.0.0 I got the exception

System.MissingMethodException: Method not found: 'Void Autofac.Core.IComponentRegistration.add_Preparing(System.EventHandler1<Autofac.Core.PreparingEventArgs>)'. at AutofacSerilogIntegration.ContextualLoggingModule.AttachToComponentRegistration(IComponentRegistryBuilder componentRegistry, IComponentRegistration registration) at Autofac.Module.<AttachToRegistrations>b__4_0(Object sender, ComponentRegisteredEventArgs e) at Autofac.Core.Registration.ComponentRegistryBuilder.add_Registered(EventHandler1 value)
at Autofac.Module.AttachToRegistrations(IComponentRegistryBuilder componentRegistry)
at Autofac.Module.Configure(IComponentRegistryBuilder componentRegistry)
at Autofac.ContainerBuilder.Build(IComponentRegistryBuilder componentRegistry, Boolean excludeDefaultModules)
at Autofac.ContainerBuilder.Build(ContainerBuildOptions options)
at Autofac.Extensions.DependencyInjection.AutofacServiceProviderFactory.CreateServiceProvider(ContainerBuilder containerBuilder)
at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
at Microsoft.Extensions.Hosting.HostBuilder.Build()

AutofacSerilogIntegration.dll has the wrong file version

After updating to AutofacSerilogIntegration v5.0.0 and then trying to upgrade a previous installation of our WiX installer built MSI, AutofacSerilogIntegration.dll was the only file which did not upgrade. Looking at the MSI debug log, it said that the reason why the dll did not upgrade was because the file versions were the same. Checking the file details for the v3.0.0 dll, the file version was 1.0.0. Then checking file details for v5.0.0, the file version is still 1.0.0 even though the product version changed to 5.0.0. Since the WiX installer is looking at the file version, it believes that the versions are the same and therefore won't upgrade the dll.

The file version for the autofacSerilogIntegration.dll should be incrementing with each new version even if the file version does not necessarily match the product version.

New version of package with serilog 2.x dependency

Would it be possible for you to reference serilog 2.x and create a new package?

I am using Serilog 2.4 and just because I use AutofacSerilogIntegration, I have to add Assembly Redirects to Serilog 2.0.0.0 in every project now...

Thanks for the code!

ILogger for Controller is not correctly resolved

When I add ILogger parameter to regular class Worker it is resolved as instance with context Worker and errors are correctly logged with SourceContext set to Worker.

However, when ILogger is parameter of UserController it is resolved as instance without context. So error messages don't contain SourceContext.

API is .NET Core 2.0.

Method not found ModuleRegistration failed

Hi,

I'm trying to use SeriLog, Console Sink, Autofac, AutofactIntegration package in Azure Functions - v1 runtime.

followed the steps
https://github.com/nblumhardt/autofac-serilog-integration

everything works fine if i perform the same in console application/test

but fails to execute in Azure function runtime.

System.MissingMethodException : Method not found: 'Autofac.Core.Registration.IModuleRegistrar AutofacSerilogIntegration.SerilogContainerBuilderExtensions.RegisterLogger(Autofac.ContainerBuilder, Serilog.ILogger, Boolean)'.

Any pointers?

Regards
Akhilesh

Performance overhead for components not consuming ILogger

Recently we've encountered a performance issue in a project using AutofacSerilogIntegration. The performance profiling was indicating a lot of time spent in registration.Preparing handler attached by ContextualLoggingModule; the strange thing, though, was that none of the components in the dependency tree were actually using an ILogger. So I did a little digging and found out that if you register a delegate factory, the integration is always enabled for it (because, of course, there's no way of knowing if it requires ILogger or not).

Enter the benchmark (Autofac 5.1.2, AutofacSerilogIntegration 3.0.0). Here are there most relevant parts of the registration:

containerBuilder.RegisterInstance(new InstanceDependency());
containerBuilder.Register(_ => new DelegateDependency());
containerBuilder.Register(_ => new DelegateDependency2());
containerBuilder.RegisterType<ReflectionDependency>();
containerBuilder.RegisterType<ReflectionDependencyWithLogger>();

Only ReflectionDependencyWithLogger has ILogger as a dependency. And the consumers are very simple:

public class Service<T>
{
  private readonly T _dependency;
  public Service(T dependency) => _dependency = dependency;
}

public class Service2
{
  private readonly DelegateDependency _dependency;
  private readonly DelegateDependency2 _dependency2;

  public Service2(DelegateDependency dependency, DelegateDependency2 dependency2)
  {
    _dependency = dependency;
    _dependency2 = dependency2;
  }
}

Let's start with pure Autofac, no logger registration

Method Mean Error StdDev Ratio RatioSD
ReflectionNoLogger 1.452 μs 0.0220 μs 0.0349 μs 1.00 0.00
InstanceNoLogger 1.174 μs 0.0106 μs 0.0094 μs 0.80 0.02
DelegateNoLogger 1.285 μs 0.0124 μs 0.0103 μs 0.88 0.02
TwoDelegatesNoLogger 1.733 μs 0.0159 μs 0.0149 μs 1.19 0.04

No wonders here, provided instance is the fastest, delegate is faster than reflection, when we have two delegates it becomes slower. Everything is as expected. Now we add the logger:

Method Mean Error StdDev Ratio RatioSD
Reflection 1.511 μs 0.0264 μs 0.0234 μs 1.00 0.00
ReflectionWithLogger 3.382 μs 0.0674 μs 0.0526 μs 2.24 0.05
Instance 1.202 μs 0.0237 μs 0.0421 μs 0.82 0.03
Delegate 2.807 μs 0.0253 μs 0.0197 μs 1.86 0.03
TwoDelegates 4.960 μs 0.0822 μs 0.0729 μs 3.28 0.08

When we use the logger (ReflectionWithLogger), it is understandably slower. Provided instance is again the fastest. But what happened with the delegates (which, I remind you, don't use ILogger)? They are almost as slow as if we were using the logger, and it grows with the number of consumed delegates.

Here's the culprit:

var ra = registration.Activator as ReflectionActivator;
if (ra != null)
{
  //...some checks...

  // Ignore components known to be without logger dependencies
  if (!usesLogger)
    return;
}

So, for every non-ReflectionActivator component we'll have the Preparing handler attached and firing and the logger being created even if it's not consumed. Which, in our case, was responsible for roughly 3x slowdown (almost the same as in the benchmarks above - we were consuming two delegate dependencies).

As far as I know, Autofac provides 3 activators out-of-the-box: Reflection, ProvidedInstance and Delegate. Reflection is the one the integration properly handles. For the ProvidedInstance the handlers are redundant (nothing will consume the created Parameter), but because it's called only once in the lifecycle, the impact is negligible.

The Delegates, though, are an issue. I'd argue that the handlers are redundant as well, because even while it is possible to consume the Parameter in the factory (using the Register<T>(Func<IComponentContext, IEnumerable<Parameter>, T>) overload) one would have to rely on the private implementation details in the Preparing handler to guess what to consume. It is much easier to simply resolve the logger from the IComponentContext and call ForContext on it. But this is my personal take.

So we have some options here:

  1. provide the logger only for ReflectionActivator, which, I'd say, will cover all the expected uses, but, in theory, might break somebody's edge case
  2. explicitly list the behavior for known activators (provide for Reflection, do not provide for Delegate and ProvidedInstance), which is same as above but covers for someone's custom activator just in case
  3. create a switch, something like RegisterLogger(..., bool onlyForKnownConsumers: false), which will enable the behavior above for implementation cases like ours
  4. replace the check with the strategy:
    interface ILoggerAttachmentStrategy
    {
      bool ShouldAttachToRegistration(IComponentRegistration registration, out PropertyInfo[] targetProperties)
    }

with a default implementation from existing code and allow passing it from outside: RegisterLogger(..., ILoggerAttachmentStrategy strategy), which is a more complex version of 3 with a lot more control for the consumers.

I would personally vote for the option 2, with the option 4 being my next choice.

MissingMethodException in AutofacSerilogIntegration.ContextualLoggingModule.AttachToComponentRegistration

This exception is introduced since version 3.0.0. In version 2.1.0. it is working.

Steps to reproduce
Create a new ASP.NET Core Web API application.
Add nuget packages

    <PackageReference Include="Autofac" Version="6.0.0" />
    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
    <PackageReference Include="AutofacSerilogIntegration" Version="4.0.0" />
    <PackageReference Include="Serilog" Version="2.10.0" />
    <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />

Modify Program.cs

public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .WriteTo.Console()
                .CreateLogger();

            Log.Information("Hello World!");
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseServiceProviderFactory(new AutofacServiceProviderFactory())
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

Modify Startup.cs

public void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterLogger();
        }

Running the application will result in

Unhandled exception. System.MissingMethodException: Method not found: 'Void Autofac.Core.IComponentRegistration.add_Preparing(System.EventHandler`1<Autofac.Core.PreparingEventArgs>)'.
   at AutofacSerilogIntegration.ContextualLoggingModule.AttachToComponentRegistration(IComponentRegistryBuilder componentRegistry, IComponentRegistration registration)
   at Autofac.Module.<AttachToRegistrations>b__4_0(Object sender, ComponentRegisteredEventArgs e)
   at Autofac.Core.Registration.ComponentRegistryBuilder.add_Registered(EventHandler`1 value)
   at Autofac.Module.AttachToRegistrations(IComponentRegistryBuilder componentRegistry)
   at Autofac.Module.Configure(IComponentRegistryBuilder componentRegistry)
   at Autofac.ContainerBuilder.Build(IComponentRegistryBuilder componentRegistry, Boolean excludeDefaultModules)
   at Autofac.ContainerBuilder.Build(ContainerBuildOptions options)
   at Autofac.Extensions.DependencyInjection.AutofacServiceProviderFactory.CreateServiceProvider(ContainerBuilder containerBuilder)
   at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()

When I downgrade the AutfacSerilogIntegration to version 2.1.0 it is working. Am I missing something or is this a bug?

Customization of the ILogger dependency configuration

Hey,
I really like the idea of this module for enriching log entries, however I have one issue with it - where to call Log.CloseAndFlush(). The module specifies the dependency as ExternallyOwned, however if in a project an ILogger instance is always retrieved via Autofac, I would like it to handle the Disposal as well (not relying on Application_End, etc).

How about adding a generic Lambda Action as another parameter to the SerilogContainerBuilderExtensions.RegisterLogger extension method, that would allow something like this:

Action<IRegistrationBuilder<ILogger, SimpleActivatorData, SingleRegistrationStyle>> registrationAction = registration =>
{
	registration.SingleInstance()
		.OnRelease(logger => Log.CloseAndFlush());
};

builder.RegisterLogger(registrationAction);

In order to be backwards compatible, the parameter would be nullable, and the default Action would specify the dependency as being .ExternallyOwned().

If you agree and like this approach, I can submit a PR with this change...

ContextualLoggingModule gets registered twice when using Autofac's assembly scanning

Related to Autofac issues:

I have a scenario where I have a specific ILogger instance to be registered with Autofac via the RegisterLogger extension method`:

var builder = new ContainerBuilder();
builder.RegisterLogger(_mySpecificILoggerInstance);

However, later in the code, there's a call to RegisterAssemblyModules which will pickup the AutofacSerilogIntegration assembly and will register the ContextualLoggingModule again, but now with a null instance of ILogger and will cause it to use the static instance Log.Logger - which is not the instance desired.

e.g.

var assembliesInAppDomain = AppDomain.CurrentDomain.GetAssemblies().ToArray();
builder.RegisterAssemblyModules(assembliesInAppDomain);

I think the ideal scenario would be to have a way to tell Autofac to skip registering the ContextualLoggingModule given we want it to be registered only via the RegisterLogger extension method.

A quick attempt to make ContextualLoggingModule internal, produce the same results (Autofac registers it anyway, by design I think).

A second quick attempt to make ContextualLoggingModule constructor's also internal, causes an exception during registration as Autofac can still see the module but can't find a suitable constructor, and bombs.

Custom ILogger registration?

Currently, this integration wraps everything required to resolve context-aware instances of ILogger from Autofac in a single Autofac module. While extremely convenient (it really doesn't get any easier than builder.RegisterLogger()), I'm currently facing the problem that I need to inject instances of ILogger into imported MEF components (which are being resolved using Autofac with the Autofac.Integration.Mef package), however Autofac doesn't expose any dependencies for resolved MEF components unless they are declared as exports (using IRegistrationBuilder<...>.Export()). Which means I need to change how ILogger is being registered.

Is there a way do to that with this integration? All I can see is that the extension method optionally takes an existing instance of ILogger or allows to declare whether properties are being autowired. And it returns a IModuleRegistrar instead of a IRegistrationBuilder, which is normally expected when registering components on the ContainerBuilder.

Not working with Autofac 6.X.X

System.MissingMethodException: Method not found: 'Void Autofac.Core.IComponentRegistration.add_Preparing(System.EventHandler1<Autofac.Core.PreparingEventArgs>)'. at AutofacSerilogIntegration.ContextualLoggingModule.AttachToComponentRegistration(IComponentRegistryBuilder componentRegistry, IComponentRegistration registration) at Autofac.Module.<AttachToRegistrations>b__4_0(Object sender, ComponentRegisteredEventArgs e) at Autofac.Core.Registration.ComponentRegistryBuilder.add_Registered(EventHandler1 value)
at Autofac.Module.AttachToRegistrations(IComponentRegistryBuilder componentRegistry)
at Autofac.Module.Configure(IComponentRegistryBuilder componentRegistry)
at Autofac.ContainerBuilder.Build(IComponentRegistryBuilder componentRegistry, Boolean excludeDefaultModules)
at Autofac.ContainerBuilder.UpdateRegistry(IComponentRegistryBuilder componentRegistry)
at Autofac.Module.Configure(IComponentRegistryBuilder componentRegistry)
at Autofac.ContainerBuilder.Build(IComponentRegistryBuilder componentRegistry, Boolean excludeDefaultModules)
at Autofac.ContainerBuilder.Build(ContainerBuildOptions options)
at Autofac.Extensions.DependencyInjection.AutofacServiceProviderFactory.CreateServiceProvider(ContainerBuilder containerBuilder)
at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
at Microsoft.Extensions.Hosting.HostBuilder.Build()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.