How to get a list of all Windows Event Logs (Event Viewer Logs) with their hierarchy and friendly names in C#
Asked Answered
S

1

8

I'm trying to replicate the following from the Event Viewer:

enter image description here

I'm having trouble with a few things.

  1. Some of the names I get back are not the display names or friendly names. For example, for "Microsoft Office Alerts" I just get back "OAlerts". How can I get the full "Microsoft Office Alerts" from "OAlerts"?
  2. Figuring out the hierarchy. It seems all I can do is parse out the dashes and do some sort of a best guess. There doesn't seem to be an easy way in the API to figure it out. The GetLogNames just gives you a flat list of all the logs

    EventLogSession session = new EventLogSession();
    List<string> logNames = new List<string>(session.GetLogNames());
    foreach (string name in logNames)
    {
        //EventLogConfiguration config = new EventLogConfiguration(name); //looks useful but doesn't give me any of the info i'm looking for.
    
       Console.WriteLine(name);
    }  
    
Squarrose answered 6/6, 2016 at 16:21 Comment(0)
P
7

This blog here: The EventSource NuGet package and support for the Windows Event Log (Channel Support) has a link to a rare EventSource User's Guide document that states this:

Do use the EventSourceAttribute’s Name property to provide a descriptive, qualified name for the ETW event provider represented by your event source. The default is the short name of your event source type, which can easily lead to collisions, as ETW provider names share one machine-wide namespace. An example of a good provider name “<CompanyName>-<Product>-<Component>”. Following this 3-element convention will ensure Event Viewer displays your event logs in a logical folder hierarchy: “Application and Services Logs/<CompanyName>/<Product>/<Component>”.

Which tends to indicate the dashes are more a convention than a strict requirement (So I believe you can parse it by yourself). Note the blog is still open for comments.

As for names that don't match, there is an undocumented EvtIntGetClassicLogDisplayName function that can get you the name displayed in Event Viewer. Here is how to use it with a session and a log name:

    static void Main(string[] args)
    {
        var session = new EventLogSession();
        foreach (string name in session.GetLogNames())
        {
            Console.WriteLine(GetDisplayName(session, name));
        }
    }

And here is the support code (since it's undocumented, use at your own risks, plus it seems to be useful mostly for this 'OAlert' entry, so I'm not sure it's worth it):

    public static string GetDisplayName(EventLogSession session, string logName)
    {
        var sb = new StringBuilder(512);
        int bufferUsed = 0;
        if (EvtIntGetClassicLogDisplayName(GetSessionHandle(session).DangerousGetHandle(), logName, 0, 0, sb.Capacity, sb, out bufferUsed))
            return sb.ToString();

        return logName;
    }

    private static SafeHandle GetSessionHandle(EventLogSession session)
    {
        return (SafeHandle)session.GetType().GetProperty("Handle", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(session);
    }

    [DllImport("wevtapi.dll", CharSet = CharSet.Unicode)]
    private static extern bool EvtIntGetClassicLogDisplayName(IntPtr session, [MarshalAs(UnmanagedType.LPWStr)] string logName, int locale, int flags, int bufferSize, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder displayName, out int bufferUsed);
Pierrette answered 8/6, 2016 at 23:7 Comment(3)
Thanks Simon. What a great answer. The GetDisplayName works like a charm (though it is scary to use DangerousGetHandle - i wonder if this would pass a code review:). However the naming convention doesn't seem to stick properly. Even in the above screenshot that i've added, Microsoft-SQLServerDataTools isn't being placed under Microsoft. Also, when i call GetLogNames() i see Microsoft-IIS-Configuration which isn't showing up under Microsoft in the screenshot above. I think there may be another "hidden" API like the one you discovered.Squarrose
Similar example would be Microsoft-Rdms-UI log.Squarrose
Microsoft-SQLServerDataTools simply doesn't follow the 3-element convention (only 2 parts, some guy at MS didn't read the doc...). Also, many things will show up if you check EventViewer's menu View/Show Analytic and Debug Logs. These logs are marked with "Diagnostic" or "Analytic". As for Microsoft-IIS-Configuration, it's a Log that is linked to the Provider "Microsoft-Windows-IIS-Configuration" (you can discover that link using new ProviderMetadata("Microsoft-Windows-IIS-Configuration", session, null).LogLinks). The namespaces between logs and their provider are not always consistent...Pierrette

© 2022 - 2024 — McMap. All rights reserved.