How do I write to a custom event source using .net core's ILoggerFactory? Is there a way to specify the source?

7k Views Asked by At

I am trying to write to a custom event source in .netcore/c# but have not found a way to specify the target source of .net core's logger object. In this case, I want to write to "My Event Log" as opposed to the Application log. The code below writes successfully to the Application log, but I want to point it at the "My Event Log" event source.

if (!EventLog.SourceExists("My Event Log"))
{
    EventLog.CreateEventSource("My Event Log", "My Program");
}

ILoggerFactory loggerFactory = new LoggerFactory()
        .AddConsole()
        .AddDebug()
        .AddEventLog();

ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("DAILY LOAD starting...");
1

There are 1 best solutions below

0
On

Code and explanation below that got my .NETCore/C# console app writing to a "custom application log" in event viewer successfully WITHOUT Event ID Description errors (see ISSUE #1 FIX if you are having this issue).

//libraries needed..
//using Microsoft.Extensions.Logging;
//using Microsoft.Extensions.Logging.EventLog;

string _sourceName = "My Program"; //source program name
string _logName = "My Event Log"; //new event log or targeted event log name

//if custom event log does not exist, create it
if (!EventLog.SourceExists(_logName))
{
    //event log creates new app log and associates program, "My Program", with new log, "My Event Log"
    EventLog.CreateEventSource(_sourceName, _logName);
}

EventLogSettings myEventLogSettings = new EventLogSettings
    {
        SourceName = _sourceName,
        LogName = _logName
    };

ILoggerFactory loggerFactory = new LoggerFactory()
            .AddConsole()
            .AddDebug()
            .AddEventLog(myEventLogSettings);

ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation(1000, "DAILY LOAD starting...");

NOTE #1: if you are changing the targeted log of an existing source program... or in other words, if you are re-pointing a program that is ALREADY writing to an event log, this will require a reboot to register. If the log is newly created, it will write successfully. See this thread for more info: Windows Event Log - how to register an event source?

ISSUE #1: When you open event viewer to take a look at your custom application log's first event, you will see that your event is buried in an error message.

The description for Event ID 0 from source My Program cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer. If the event originated on another computer, the display information had to be saved with the event.The following information was included with the event: myProgram DAILY LOAD starting...the message resource is present but the message is not found in the string/message table

ISSUE #1 FIX: the new application log is either referencing a non-existing Message Table file or the EventId being passed is NOT in the Message Table. The easiest way to resolve this issue is to have your log reference an existing Message Table file (for example, .NET Runtime) and pass it a documented EventId (I used 1000). This requires a registry change, steps below (article for reference and screenshots):

  1. Open registry
  2. Navigate to Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog
  3. Click on the folder of the new event log. In this case, "My Event Log".
  4. Create new string in the folder.

    Value name = "EventMessageFile"
    Value data = "C:\Windows\System32\mscoree.dll"

IMPORTANT: the Value data path above is referencing the existing .NET Runtime Message table, you can reference a different message table if you would like. Because the .NET Runtime message table does NOT have an EventID equal to 0, I continued to get the same error. Once I changed the eventId being passed to an existing value in the .NET Runtime Message table (in this case, 1000), it worked as expected with NO error message!