dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.26k stars 4.73k forks source link

EventLog should support directory generation #42475

Open taori opened 4 years ago

taori commented 4 years ago

Is your feature request related to a problem? Please describe.

I began developing a worker service and want to utilize AddEventLog in my logging configuration - Unfortunately i can't seem to find a way to configure my event logging in a way where the eventlog that is generated results in a nested structure (using folders in

eventvwr -> "applications and service programs" -> AMU -> MyEventLog instead of eventvwr -> "applications and service programs" -> AMU/MyEventLog

Describe the solution you'd like

Ideally instead of EventSource creation to fail if i pick AMU\MyEventLog it would generate a folder structure instead.

Describe alternatives you've considered

A custom event log provider would work obviously, but this functionality should be available to everyone.

Additional context

namespace LaunchProcessInCurrentUserService
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // see https://web.archive.org/web/20200423120541/https://csharp.christiannagel.com/2019/10/15/windowsservice/
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .ConfigureLogging(builder =>
                {
                    builder.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Information);
                })
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddLogging(configure =>
                    {
                        configure.AddEventLog();
                        configure.AddDebug();
                        if (hostContext.HostingEnvironment.IsDevelopment())
                        {
                            configure.AddConsole();
                        }
                    });

                    services.AddHostedService<Worker>()
                        .Configure<EventLogSettings>(els =>
                        {
                            els.LogName = hostContext.Configuration.GetValue<string>("Application:EventLogApplicationName") ?? "CurrentUserService";
                            els.SourceName = hostContext.Configuration.GetValue<string>("Application:EventLogSource") ?? "CurrentUserService Source";
                        });
                });
    }
}
KalleOlaviNiemitalo commented 4 years ago

Event Viewer shows a folder in "Applications and Services Logs" if the provider is registered with a Windows Event Log manifest, or nested folders if the name of the provider contains two or more "-" (U+002D HYPHEN-MINUS) characters. The manifest has to be registered by running wevtutil.exe, which writes under the undocumented Registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT.

I don't know whether it is possible to make Event Viewer show folders for legacy Event Logging logs that are registered in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog. That is what the EventLog class uses.

The EventSource class uses the newer Windows Event Log API. The LoggingEventSource class is derived from that but hardcodes "Microsoft-Extensions-Logging" as the name and uses the ETW self-describing format rather than a manifest.

A custom event log provider would work obviously

Have you implemented that?

taori commented 4 years ago

Event Viewer shows a folder in "Applications and Services Logs" if the provider is registered with a Windows Event Log manifest, or nested folders if the name of the provider contains two or more "-" (U+002D HYPHEN-MINUS) characters. The manifest has to be registered by running wevtutil.exe, which writes under the undocumented Registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT.

I don't know whether it is possible to make Event Viewer show folders for legacy Event Logging logs that are registered in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog. That is what the EventLog class uses.

The EventSource class uses the newer Windows Event Log API. The LoggingEventSource class is derived from that but hardcodes "Microsoft-Extensions-Logging" as the name and uses the ETW self-describing format rather than a manifest.

A custom event log provider would work obviously

Have you implemented that?

No i haven't because i figured it does not matter that much to me, but according to the documentation simply adding backslashes in the source name will already result in a directory structure for the event log.

KalleOlaviNiemitalo commented 4 years ago

What documentation is that? According to Event Sources, names of event sources cannot contain the backslash character.

taori commented 4 years ago

What documentation is that? According to Event Sources, names of event sources cannot contain the backslash character.

I can't find the source just now, but if you use the constructor it does not work, but if you call a method like CreateSource() it'll work. Need to do some digging first, but the change to make it work was rather small.

ghost commented 4 years ago

Tagging subscribers to this area: @tommcdon, @krwq See info in area-owners.md if you want to be subscribed.

ghost commented 4 years ago

Tagging subscribers to this area: @maryamariyan See info in area-owners.md if you want to be subscribed.