COM+ Logging Services

COM+ Logging Services

We're building a COM 1.0+ application using VC++ .NET.  The app has a database that will allows us to view most activity on the system, but we still would like to have a discreet logging mechanism to help us keep track of a few things that we won't store in our database (e.g. errors in communicating with the database).  What we're looking for are recommendations on simplifying our logging needs.

I know COM+ has its own logging mechanisms built in, though I'm not sure if we can (or should) expand on this to add our custom logging.

We have used the EventLog Class in a separate C# windows service application and really appreciated the ease with which we could handle logging.  Is there a similiar set of classes accessible via C++ that can be utilized in a COM+ application?  Should we create a "from scratch" mechanism that is specific to our needs and store that in a regular COM dll that can be accessed from both managed and unmanaged code applications?  I'd like to use the windows event log to make life simpler for our support staff to troubleshoot.  However, the real goal is to find the right balance of reusability and simplicity.

Any recommendations are greatly appreciated.

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

I'd just use the NT Event log facility.  If you're using ATL for your component, the includes that expose these Win32 API functions should already be available to you.  If you're using MFC, then I'm not positive this will work.

void LogErr(BSTR strErrMsg)
      //Go ahead and use the Widechar versions of OpenEventLog(), etc. since everything
      //in COM is wide char anyway.
      HANDLE hEventLog = OpenEventLogW(NULL, OLESTR("Your app/dll name goes here"));
      ReportEventW(hEventLog, EVENTLOG_ERROR_TYPE, NULL, NULL, NULL, 1, NULL, (LPCWSTR*)&strErrMsg, NULL);

Now, with this, the Event Log subsystem will more than likely print something at the beginning of your events about you not using a registered event source, but it doesn't really hurt anything.

There is a way around it doing that by using some resource-only dll that came with the .NET runtime, but I don't remember exactly how I did it last time.  Look at RegisterEventSource() in the MSDN library, if you want to expend effort on having a bona-fide registered event source.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MattWareAuthor Commented:
Thanks so much for your feedback.  I followed up on your recommendation to research the RegisterEventSource Method.  I created the following function within my main COM component:

int MyCOMObj::LogEvent(LPCSTR*pErrorMessage, MyCOMObj::eEventType eEventType)
    long lEventID = 0;
    CERBEvent::eLogType eLType;
    CString sServerName;

    //I'll implement this later to handle different
    if(eEventType == CERBEvent::eEventType::EVENT_TYPE_INFORMATION)
        eLType = CERBEvent::eLogType::LOG_TYPE_INFORMATION;
    HANDLE hEventLog = RegisterEventSource(NULL, "MyCOMApp");  
    ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, 0, 1, 0, pErrorMessage, 0);
    return 0;

As you had said, indeed it still doesn't like the fact that my event isn't registered, but the message can still be seen as follows:

The description for Event ID ( 0 ) in Source ( ERBCOM ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. The following information is part of the event: Test Error Message.

This meets my immediate need, but if you've also got a handy way (minimal coding) to get that event registered, I'd feel more confident rolling this out for the support staff to use.  However, I do feel that you've sent me down the right track.  

Any further ideas on registering events in a simple manner is greatly appreciated.  

Ok, I found my notes on creating an event source.  Its somewhat of a hack, because technically, you're supposed to make you own resource-only dll, but why bother when the .NET runtime has one for you already?  This is the same DLL that VB.NET uses for its event-sourcing needs in every VB.NET program, so it can't be all that bad to use it.

Create the following registry key:

In this key, you will place a <right-click context menu>->New->"String Value" called "EventMessageFile".  It should show in regedit as a type REG_SZ.  The value should be set to the path of your (borrowed) resource-only dll.  On my system, it looks like this:


You may be able to copy that EventLogMessages.dll file to somewhere else if you want.    I don't see why you couldn't.  At any rate, that should be about all there is to it.

I think that if you use this dll you may have to use an event type of 1 or an event ID of 1 or something like that.  I had it working when I was playing with it once and it seems to me that might have been the case.

Also, you want to make sure you close the HANDLE hEventLog in you code.  I think MSDN suggests using DeregisterEventSource().

If you don't, you may end up with a handle leak situation, and from what I've read elsewhere, handles are one of those "scarce resources".

I'm guessing that since they're kind of an OS-intrinsic thing, it might make the OS grind to a halt if you leaked enough of them over a long enough period of time.
MattWareAuthor Commented:
That was pretty cool.  I made the registry changes you recommended and the test messages I had created yesterday now only contained the message I had originally wanted.  I thought the registry change would affect new events, but apparently it also corrected existing ones.  I had used an ID of 0 on those messages and I'm pretty sure an event id of 1 would have no effect, but I'll try it out.

Anyway, that was exactly the kind of solution I was looking for.  Thanks for your help and as far as it being a hack - I won't tell if you don't.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.