views:

187

answers:

2

hey guys

We have a "log" class which uses Relection.MethodBase to send current class info to the log.

The reflection.MethodBase stuff happens in the class itself.

However, I'd like to move that stuff to a single external "log" singleton type class.

In this scenario the external log class needs to get the CALLING info, not the current method info. I'm using stacktrace to do this, which isn't in the Reflection namespace.

Can I guarantee that "that" specific information (calling method) will be there in a production environment?

 var stackTrace = new StackTrace();
 return LogManager.GetLogger(stackTrace.GetFrame(1).GetMethod().DeclaringType);

cheers!

+4  A: 

Yes, even in a "release" build without any PDB's you will have the method names in a stack trace. But personally I would consider this a code smell. It implies a very fragile code path (for example what happens if you make a WriteLine method that calls a Write method, do you look at the caller's caller in that case?). It also is probably not cheap to take a snapshot of the stack trace on every logging call.

I recently posted a question about using MEF to inject a logger into my class and I wanted to associate a type name with the log data as well. MEF worked out pretty well for me as I was able to import an ILogger instance for each class that wanted to use it and when the ILogger instance was imported, I would set its Category property to the name of the current class. No reflection, no stack trace. It worked pretty nicely for me.

Josh Einstein
agreed. Any better recommendation? Ideally I wouldn't want to put reflection stuff in other classes, I'd like the logger to handle it internally... any ideas?
andy
As you were writing that I just edited my answer to point to a method I used.
Josh Einstein
+2  A: 

Josh has it right. Taking stack traces is very expensive and should be avoided. It's a bit hard to understand exactly what you are doing, but it sounds rather bad. My first suggest would be to take another look at your production environment and see what logging services are already in place and how you can use them.

If you cannot, then I'd be looking into already available APIs such as Log4j, SLF4j and Commons logging to see how you could utilise them. Finally, if still not useable, you can at least look at their source to see how they do things. Also the source for JUnit does stack trace analysis if I remember correctly so there's another source of ideas.

But my last word would be to keep things as simple as possible. Don't go around creating stack traces. Generally speaking you are really only concerned about them when an exception happens and then it is handed to you. You don't need to do anything except pass it along.

Derek Clarkson
yeah I'm using log4net, which you still have to pass reflection info to, and I want the logger to handle that. however +1 for pointing out the obvious I missed! only care about it if it's an error, good point!
andy