Tuesday, October 23, 2007

ASP.NET and EventLog: Event ID issues when writing to Event Log

If you get the following message (except your application name): The description for Event ID ( 234 ) in Source ( dotNET Sample App ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: Sample Event. The best part of this is that the existing logs no longer have this message either once you follow the steps below. What it is trying to tell you is that when it tries to look up Event ID 234 in the Source Called dotNET Sample App, it can't figure out what 234 is supposed to represent because it can't find the dll that maps the event ids to localized messages. What it wants is an entry in the Registry that points to the dll. For example, if you are writing to the Application event log and using the source called dotNET Sample App, the key needs to be at: HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App\EventMessageFile. The value needs to point to a .dll file that has been compiled specially for this purpose using. It appears that if this key does not exist, you can add the above key (Expandable String Value), and point the value to (slightly different path if v1.x): C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\EventLogMessages.dll If you want user friendly messages in the event log instead of number for the event id, you will need to do the following. If the key is not already there, you can add a new Expandable String Value with the name Event MessageFile and the value of the path (including the .dll) to the dll. The following url is a good start: http://msdn2.microsoft.com/en-us/library/system.diagnostics.eventinstance.aspx Here is how to use Message Compiler (to create the event id dll): http://msdn2.microsoft.com/en-us/library/aa385638.aspx If you want to fix this the quick way and have a generic dll get used automatically then just do the following. This step may or may not be necessary if you are running a Windows application, but is necessary if you want an ASP.NET application to log events. 1. Launch RegEdit 2. Navigate to Delete the key at HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App 3. From the Edit menu select Permissions. 4. Add the ASPNET user (or whatever user your application is running under or impersonating if using ASP.NET) and give it Read and Write permission. Verify that the Application and Security Keys now have these permissions also. NOTE: Under IIS 6.0 the user isn't ASPNET, it is Network Service Tip: If you need help debugging permission, you can always add Everyone with Full Control and reduce permissions until you figure out what permissions you really need. Be sure to not leave it this way though. It is a small security hole. NOTE: You are probably not writing to System, but if you have code like the following in your application, the SourceExists() method will throw an exception. To avoid this, you need to grant permissions to it also (at least until the CreateEventSource()) method successfully creates the key. After that, you should not get the error when SourceExists() is called. There are other solutions as well. For example, you can always create a standalone Windows application with the same name as your web application and have it run the CreateEventSource() method. This will get you past the SourceExists() call, and this will create the source. You will still need to adjust permissions for your application to log properly though. You can also create an event log installer. I have never done this, and sounds like a complicated solution to me. Permissions is much simpler and falls under the general configuration knowledge that can be used for any web application. if (!EventLog.SourceExists(sourceName)) { EventLog.CreateEventSource(sourceName, "Application"); } 5. Now run your application, and make sure the CreateEventSource() is called. This should create the key: HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\dotNET Sample App NOTE: You may need to run your application twice as it takes a short time for the new Event Source to be synchronized with other parts of Windows. 6. Verify that the EventMessageFile key was created properly. NOTE: If you specify the category id in your code, you will also need to do something similar. I have not tested the solution, but I expect if you create custom message then you will have a file that you can't point to in the registry in much the same way. I know the key for the categories does not automatically get created, but using mc.exe as you would have done for event ids (if you needed custom messages) should work. I welcome feedback on this. I recommend setting the category id to 0 in your code if you don't want to deal with this issue. Another Symptom of this is that MS LogParser will generate errors like the following Task aborted.Too many parse errors - abortingParse errors:Unable to map Event Message from Event Source "dotNET Sample App"Unable to map Event Message from Event Source "dotNET Sample App" when a query like LogParser.exe "select distinct message from application where message like '%display messages from a remote computer%'" -msgErrorMode:ERROR -e 10 is executed to find all the troubled errors in the first place. To fix this, make sure registry key and path to dll exists for source as described above.

No comments: