serilog / serilog-settings-configuration

A Serilog configuration provider that reads from Microsoft.Extensions.Configuration
Apache License 2.0
444 stars 129 forks source link

Assembly 'Serilog.Settings.Configuration' produced trim warnings => Runtime error #408

Closed BPodszun closed 7 months ago

BPodszun commented 7 months ago

I'm trying to build a self-contained, trimmed application that should be able to use Serilog.Sinks.Console and Serilog.Sinks.EventLog. I'm targeting dotnet8 and use the latest (at the time of this writing) versions of the relevant Serilog nuget packages.

The application works if I either

Warning during compilation:

C:\Users\Ben.nuget\packages\serilog.settings.configuration\8.0.0\lib\net8.0\Serilog.Settings.Configuration.dll : warning IL2104: Assembly 'Serilog.Settings.Configuration' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries C:\Users\Ben.nuget\packages\serilog\3.1.1\lib\net7.0\Serilog.dll : warning IL2104: Assembly 'Serilog' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries

Runtime error (as stated above, it works without trimming):

Unhandled exception. System.IO.FileNotFoundException:
IO_FileName_Name, Serilog.Sinks.Console, Culture=neutral, PublicKeyToken=null
   at System.Reflection.RuntimeAssembly.<InternalLoad>g____PInvoke|49_0(NativeAssemblyNameParts*, ObjectHandleOnStack, StackCrawlMarkHandle, Int32, ObjectHandleOnStack, ObjectHandleOnStack)
   at System.Reflection.RuntimeAssembly.InternalLoad(NativeAssemblyNameParts*, ObjectHandleOnStack, StackCrawlMarkHandle, Boolean , ObjectHandleOnStack, ObjectHandleOnStack)
   at System.Reflection.RuntimeAssembly.InternalLoad(AssemblyName, StackCrawlMark&, AssemblyLoadContext , RuntimeAssembly , Boolean )
   at System.Reflection.Assembly.Load(AssemblyName)
   at Serilog.Settings.Configuration.ConfigurationReader.LoadConfigurationAssemblies(IConfiguration, AssemblyFinder)
   at Serilog.Settings.Configuration.ConfigurationReader..ctor(IConfiguration, AssemblyFinder, ConfigurationReaderOptions, IConfiguration )
   at Serilog.ConfigurationLoggerConfigurationExtensions.GetConfigurationReader(IConfiguration, ConfigurationReaderOptions, DependencyContext )
   at Serilog.ConfigurationLoggerConfigurationExtensions.Configuration(LoggerSettingsConfiguration, IConfiguration, ConfigurationReaderOptions )

My config, in case it matters:

{
  "Serilog": {
    "Using": [ "Serilog", "Serilog.Sinks.Console", "Serilog.Settings.Configuration" ],
    "MinimumLevel": "Debug",
    "WriteTo": [
      { "Name": "Console" }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
  }
}

Code to initialize the logger:

var defaultAppSettingsStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Updater.appsettings.default.json");
var configuration = new ConfigurationBuilder()
  .SetBasePath(AppContext.BaseDirectory)
  .AddJsonStream(defaultAppSettingsStream)
  .Build();
return new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();

Is there any way to make this work WITH trimming? Things I tried:

bartelink commented 7 months ago

Ordinarily I'd be saying "better to ask on SO as it's got v little to do with this package". In this case, you have provided good detail and having a story wrt trimming for this package is probably a good idea at some point, so it's not invalid to ask. However, I would suggest duplicating this question on SO with a link to here as the chances are you'll get more useful viewers there (vs the watchers on this repo, who watch there too, and will rarely have time to go off and investigate/comment knowledgeably on a question like this) are higher (and some people are happier to chuck in a quick answer and/or drive by comment that might be useful there vs here)

BPodszun commented 7 months ago

Thank you for your reply. I solved most of this using a combination of (in my csproj)

<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>

(already existed in my project, note that I don't use IncludeAllContentForSelfExtract here)

and explicitly excluding all Serilog files from trimming¹

<ItemGroup>
  <TrimmerRootDescriptor Include="TrimmerRoots.xml" />
</ItemGroup>

where TrimmerRoots.xml is this for me:

<?xml version="1.0" encoding="utf-8" ?>
<linker>
  <assembly fullname="Serilog" />
  <assembly fullname="Serilog.Settings.Configuration" />
  <assembly fullname="Serilog.Sinks.Console" />
  <assembly fullname="Serilog.Sinks.EventLog" />
</linker>

①: https://devblogs.microsoft.com/dotnet/customizing-trimming-in-net-core-5/#using-xml-files-to-control-trimming

BPodszun commented 7 months ago

In case anyone ever runs into the above and stumbles along the same path: I'm still having issues to get the EventLog sink to work and filed https://github.com/serilog/serilog-sinks-eventlog/issues/51 (and asked on SO in parallel, as suggested)

darklajid commented 7 months ago

Actually, after quite some time of trying to get to the bottom of this I'm stuck looking at https://github.com/serilog/serilog-settings-configuration/blob/dev/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs#L460 now, which IS in this repository. It seems that in my case it does find the two extension methods that Serilog.Sinks.EventLog provides, but cannot match which one to use because ... the parameter names are empty via Reflection or something? Is this something that would be interesting for this repository/project to look into, is this a "bug" or at least a potential hard limitation to take note of?

sungam3r commented 5 months ago

@darklajid I suggest to open new issue.