EventLog "The description for Event ID ( 1001 ) in Source ( CustomCompany ) cannot be found ..."

  • Thread starter Thread starter Alan Dean
  • Start date Start date
A

Alan Dean

Hi,

I have been trying to leverage a custom event source, for which I have
compiled a message library.

The event source gets installed just fine, and when I write entries
the category info gets pulled out of the message library correctly.
The problem is that the message info seems to be completely ignored. I
get:

"The description for Event ID ( 1001 ) in Source ( Custom Company )
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: ."

To be clear, this is not an issue that can be resolved using the /
AUXSOURCE= flag. I am on the local machine, and anyway I need it to
work for all consumers - not just mmc.

I am running Server 2003 Standard Edition SP2 and the code is written
in VS2008 targeting C:\WINDOWS\Microsoft.NET\Framework
\v2.0.50727\System.dll

There is no way to demonstrate the issue with a simple code snippet
(the build is multi-step) but I have put the demonstration solution in
a zip file on my Google Code sandpit [1] (it is install-application-
event-source.zip [2]).

The solution is built using VSTS 2008 and has an MSTest project which
will create entries.

I have included instructions. See README.txt in the solution root.

I have posted this issue to the MSDN forums [3] but have had no answer
as yet.

[1] http://code.google.com/p/alan-dean/downloads/list
[2] http://alan-dean.googlecode.com/files/install-application-event-source.zip
[3] http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3085109

Regards,
Alan Dean
http://thoughtpad.net/alan-dean
http://simplewebservices.org
 
Alan said:
I have been trying to leverage a custom event source, for which I have
compiled a message library.
That may be your problem. Managed applications do not use message libraries.

The CLR uses a simple but effective trick for event logging: it uses a
message table with every possible ID set to the string "%s", that is, just
the first argument of the event logging call. The message source is set to
mscoree.dll, the main CLR runtime. In this way, managed applications can log
whatever they wish to the event log without bothering with message libraries
(as managed applications have their own mechanisms for localization).
 
Jeroen said:
That may be your problem. Managed applications do not use message
libraries.

The CLR uses a simple but effective trick for event logging: it uses a
message table with every possible ID set to the string "%s", that is,
just the first argument of the event logging call.

This should be "%1", obviously.
 
That may be your problem. Managed applications do not use message libraries.

The CLR uses a simple but effective trick for event logging: it uses a
message table with every possible ID set to the string "%s"

Jeroen,

Thanks for the reply.

Yes, I know that the default implementation for .NET apps is to drop
the whole string entry into the log, which I don't regard as
acceptable for an enterprise application. This is why I am trying to
get the 'correct' localized message library implementation working.

In Framework 1.x, this was not possible using the WriteEntry(...)
method [1]. However, 2.0 supposedly fixed this problem with
WriteEvent(...) [2].

Indeed, in April 2007, there was an MSDN Magazine Security Brief
entitled "Improve Manageability through Event Logging" [3] which
outlined the message library approach.

[1] http://msdn2.microsoft.com/en-us/library/system.diagnostics.eventlog.writeentry.aspx
[2] http://msdn2.microsoft.com/en-us/library/system.diagnostics.eventlog.writeevent.aspx
[3] http://msdn2.microsoft.com/en-us/magazine/cc163446.aspx

Regards,
Alan Dean
http://thoughtpad.net/alan-dean
http://simplewebservices.org
 
Alan said:
Yes, I know that the default implementation for .NET apps is to drop
the whole string entry into the log, which I don't regard as
acceptable for an enterprise application.

The only real drawback I can see is that it takes up more disk space. But
unless you've got a very chatty application (which is bad in itself) this
isn't likely to make a big difference. You'll be able to fit a few less log
entries in the event log, but it's probably not order-of-magnitude stuff
(parameters will always take up space, after all).

Alright, there's one important advantage that message libraries offer that
can't be replicated by logging strings, and that is being able to change the
language of all entries (including already logged ones) by replacing the
DLL. This is an advantage in that it allows you to transfer event logs from
foreign machines and still end up with something that's readable to you. I
can't say I've seen much need for this myself yet, but I can see how it
might be useful to others.
This is why I am trying to get the 'correct' localized message library
implementation working.
..NET has extensive localization support, so getting the events into the
event log in such a way that it's readable to local support is not a
problem. Indeed, that .NET separates localization from event logging is a
plus. Using message libraries forces you to either maintain two localization
resources if you have more to localize than event log entries, or to use
unmanaged localized resources throughout your managed application, which is
almost equally painful.
In Framework 1.x, this was not possible using the WriteEntry(...)
method [1]. However, 2.0 supposedly fixed this problem with
WriteEvent(...) [2].
I Did Not Know That! Actually, I think I might have seen it in passing once,
but I forgot all about it.

Alright, so basic troubleshooting then. I took a look at your source (when
all else fails...) and I saw the problem: you're using the wrong event IDs.
This code:

log.WriteEvent(new EventInstance(1001, 2, EventLogEntryType.Error), null
as object);

Won't work in combination with this code:

MessageId=1001 SymbolicName=MSG_BAD_COMMAND
Severity=Error
Facility=Runtime

Because the resulting event ID is not 1001, it's 0xC00203E9 (or -1073609751
if you're so inclined), as the header produced by mc.exe will show; the
severity and facility are part of the ID too. This is what I meant when I
mentioned that it's a pain having two different systems. Ideally you'd want
a way to use those autogenerated IDs (and the symbolic names) in your .NET
code without having to manually duplicate them.

The MSDN article you linked to does not touch this issue because it does not
define any facility or severity for the event it uses as an example (1003)
so the ID will happen to end up correctly. Also note that, to further
complement this confusion, Event Viewer will only display the lower 16 bits
of the event ID even if higher bits were set.

Leave out the severity and facility and things should work fine (a check of
my own event logs show that most applications do this, MS and non-MS alike,
despite the MSDN samples). Because the higher bits are invisible to almost
everybody and event IDs usually don't share space with other IDs, there's
little point to using them anyway.
 
The only real drawback I can see is that it takes up more disk space. But
unless you've got a very chatty application (which is bad in itself) this
isn't likely to make a big difference. You'll be able to fit a few less log
entries in the event log, but it's probably not order-of-magnitude stuff
(parameters will always take up space, after all).

In many or most applications, this may well be true. However, I have
done a lot of work with web applications and services with very large
traffic profiles. In this kind of situation, even a perfectly
reasonable log entry type can rapidly use up the configured space
allowance. Say that you are taking 500 requests / sec on a machine and
a sys admin guy mis-configures something ... give it one minute before
he realises and you have 30,000 entries! Using a 'native' message
library is so much more efficient that it is worth doing in these
circumstances.
Alright, so basic troubleshooting then. I took a look at your source (when
all else fails...) and I saw the problem: you're using the wrong event IDs.
This code:

log.WriteEvent(new EventInstance(1001, 2, EventLogEntryType.Error), null
as object);

Won't work in combination with this code:

MessageId=1001 SymbolicName=MSG_BAD_COMMAND
Severity=Error
Facility=Runtime

Because the resulting event ID is not 1001, it's 0xC00203E9 (or -1073609751
if you're so inclined), as the header produced by mc.exe will show; the
severity and facility are part of the ID too.

Fantastic! That solves my problem :-) Your help is much appreciated.

Alan
 
Alan said:
In many or most applications, this may well be true. However, I have
done a lot of work with web applications and services with very large
traffic profiles.

So have I, but...
In this kind of situation, even a perfectly reasonable log entry type can
rapidly use up the configured space allowance. Say that you are taking
500 requests / sec on a machine and a sys admin guy mis-configures
something ... give it one minute before he realises and you have 30,000
entries!

....when you're doing this much logging, I've usually found it a lot more
convenient to use a separate logging library (like log4net) and log to
files. Imagine if IIS logged every request to the event log -- you'd run out
of space before you could blink. A separate logging facility has the benefit
that you can log as much or as little as you like without having to worry
about ruining it for everyone else.

The event log still has its place, mind you, but most applications should be
conservative about logging there. Pretty much the only things I will log as
an event are start/stop events and major news like "low on memory/DB
unreachable/going to crash and burn now". And even then, I'll usually be
careful to ensure that there's a strict upper limit to the frequency with
which such messages get logged. In short, I don't give the sysadmin guy a
chance to misconfigure things.

The reasoning here is not so much the limited space, but the fact that event
log spam makes it very hard to distill meaningful information, since the
event log isn't very convenient to search and analyze without separate
tools. If an application logs an event, it better be worth reading (or
getting out of bed for, even).

For troubleshooting something specific, an extensive separate log is usually
more convenient. What you certainly should not log as events are individual
client requests, because that just doesn't scale, no matter what approach
you use to do event logging.
 
Back
Top