Solved

COM+ Logging Services

Posted on 2003-12-11
4
708 Views
Last Modified: 2013-11-25
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
0
Comment
Question by:MattWare
  • 2
  • 2
4 Comments
 

Accepted Solution

by:
nt_colonel earned 250 total points
Comment Utility
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);
      CloseEventLog(hEventLog);
}

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.
0
 
LVL 2

Author Comment

by:MattWare
Comment Utility
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
0
 

Expert Comment

by:nt_colonel
Comment Utility
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.
0
 
LVL 2

Author Comment

by:MattWare
Comment Utility
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
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
commonTwo  challenge 63 98
factorial example challenge 10 61
python question 5 57
Problem to page 4 16
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now