56

I'm trying to write to the event viewer in my c# code, but I'm getting the wonderful "Object reference not set to an instance of an object" message. I'd appreciate some help with this code, either what's wrong with it or even a better way to do it. Here's what I have for writing to the event log:

private void WriteToEventLog(string message)
{
    string cs = "QualityDocHandler";
    EventLog elog = new EventLog();
    if (!EventLog.SourceExists(cs))
    {
        EventLog.CreateEventSource(cs, cs);
    }
    elog.Source = cs;
    elog.EnableRaisingEvents = true;
    elog.WriteEntry(message);
}

And here's where I'm trying to call it:

private readonly Random _rng = new Random();
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private string RandomString(int size)
{
    try
    {
        char[] buffer = new char[size];
        for (int i = 0; i < size; i++)
        {
            buffer[i] = _chars[_rng.Next(_chars.Length)];
        }
        return new string(buffer);
    }
    catch (Exception e)
    {
        WriteToEventLog(e.ToString());
        return null;
    }
}
PushCode
  • 3,077
  • 4
  • 25
  • 26
  • 1
    "Object reference not set to an instance of an object" - means that you are referencing a NULL, it is much more helpful to know the line of code where this happens, because then you can see what it is that is NULL that you're referencing. – Stan R. Jul 15 '09 at 19:17
  • All I have is this: Error loading and running event receiver QualityDocHandler.DocumentHandler in QualityDocHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e33ce5caa212a16d. Additional information is below. : Object reference not set to an instance of an object. ...this is running on a SharePoint site so I don't see the stack trace. There was no error before adding the WriteToEventLog and the try/catch to my RandomString method. – PushCode Jul 15 '09 at 19:18
  • Think you have to do some jiggery pokery with the Registry to get the EventLog to log properly with .NET - is the key created? see: http://support.microsoft.com/kb/329291 Also suggest you run WriteToEventLog outside the scope of this function to see if it works. – Squiggs. Jul 15 '09 at 19:26

3 Answers3

87

The problem is probably that you are trying to create an event source in a log that doesn't exist. You need to specify the "Application" log.

Try changing it to:

if (!EventLog.SourceExists(cs))
   EventLog.CreateEventSource(cs, "Application");    

EventLog.WriteEntry(cs, message, EventLogEntryType.Error);

Also: Inside of sharepoint, if the app is running as logged in user(via windows auth or delegation), the user won't have access to create the event source. If this is the case, one trick is to create the event using a ThreadPool thread, which when created, will have the security context of the user the App Pool is running as.

Brian Rudolph
  • 6,142
  • 2
  • 23
  • 19
22

Here's how I implemented Event logging. I created a generic ILogger interface so I can swap in different logging mechanisms:

interface ILogger
{
    void Debug(string text);

    void Warn(string text);

    void Error(string text);
    void Error(string text, Exception ex);
}

My implementation class is very simple:

class EventLogger : ILogger
{
    public void Debug(string text)
    {
        EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Information);
    }

    public void Warn(string text)
    {
        EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Warning);
    }

    public void Error(string text)
    {
        EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Error);
    }

    public void Error(string text, Exception ex)
    {
        Error(text);
        Error(ex.StackTrace);
    }
}

Note that I do not instantiate EventLog. To use my logger class I just have the following reference (you could have this returned by a static factory method):

private static readonly ILogger log = new EventLogger();

And the actual usage is like this:

try
{
    // business logic
}
catch (Exception ex)
{
    log.Error("Exception in MyMethodName()", ex);
}
Nelson
  • 464
  • 4
  • 10
  • 12
    thats good, but it has nothing to do with his actual question o.O – Stan R. Jul 15 '09 at 19:52
  • This would actually have answered the question, if you added in a the default constructor `if (!EventLog.SourceExists(source))` to check that it exists, and a `const string source` that you set in code (or via prop or constructor override) and reuse through out the class. Then everytime you instantiate the EventLogger class it makes sure the actual error the OP experienced wont happen. I used this code combined with the accepted answer. +1 – Piotr Kula Jun 24 '15 at 09:43
1
   private void WriteEventLogToFile()
    {
        try
        {
            using (EventLog eventLog = new EventLog("Application"))
            {
             // source for your event 
                eventLog.Source = "IAStorDataMgrSvc";

             // Syntax details
            // eventLog.WriteEntry("details",type of event,event id);
             eventLog.WriteEntry("Hard disk Failure details", EventLogEntryType.Information, 11);
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
Dutt93
  • 118
  • 10