tags:

views:

4049

answers:

2

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;
    }
}
+4  A: 

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
thats good, but it has nothing to do with his actual question o.O
Stan R.
True, but I have no stacktrace to work from.
Nelson
+1  A: 

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