Link to home
Start Free TrialLog in
Avatar of MattWare
MattWare

asked on

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.

Regards,
Matt
ASKER CERTIFIED SOLUTION
Avatar of nt_colonel
nt_colonel

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of MattWare
MattWare

ASKER

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.  

Thanks,
Matt
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:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MyAppOrDLLName

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:

C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\EventLogMessages.dll

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.
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.

Matt