Custom PostSharp Logging - c#

Using PostSharp for a C# application, I have the following scenario:
Namespace_A.CustomLoggingMethod
Namespace_B.DoSomethingMethod (in fact several different methods)
DoSomethingMethod makes a call to CustomLoggingMethod, which creates the log entry in the desired format and is working well. As expected, the log entry logs the source as CustomLoggingMethod, and I would prefer to override this to show the original calling method (e.g. DoSomethingMethod), which I can obtain from the stack. Does anyone know how I can achieve this for this one method?
As a follow-up is there a way I can also prevent the entry/exit log entries for my custom logging method only?

You can, but at the cost of some performance.
The follow-up is easy: you annotate CustomLoggingMethod with [Log(AttributeExclude=false)] and it will no longer produce automatic logging of entry/exit.
As for the main question, there are overloads for both LogSource.Get() and the .Write method on LogLevelSource where you can supply your own CallerInfo. The CallerInfo object contains both the type and the method name.
What you could do is create the CallerInfo object in your custom method programatically and pass it to those methods. You can get the method name from [CallerMemberName] but you would need to pass the type as an argument.
Or, as you said, you can obtain the type from the stack. You can do this most easily with CallerInfo.GetDynamic, but in my experience, this is slow. If you start logging thousands of lines per second, you will see a performance drop from walking the stack this way.
Here's how the custom method could look like:
[Log(AttributeExclude = true)]
public static void CustomLogging(string message)
{
CallerInfo callerInfo = CallerInfo.GetDynamic(1);
LogSource.Get(ref callerInfo).Warning.Write(FormattedMessageBuilder.Formatted(message), default, ref callerInfo);
}
Writing custom logging without using a custom method avoids the problem because PostSharp rewrites the custom logging call to include the information on the caller in the IL code.

Related

How to avoid passing a context reference among classes

Dynamics CRM 2011 on premise. (But this problem exists in many situations away from Dynamics CRM.)
CRM plugins have an entry point:
void IPlugin.Execute (IServiceProvider serviceProvider)
(http://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.iplugin.execute.aspx)
serviceProvider is a reference to the plugin execution context. Anything useful that a plugin does requires accessing serviceProvider, or a member of it.
Some plugins are large and complex and contain several classes. For example, I'm working on a plugin that has a class which is instantiated multiple times. This class needs to use serviceProvider.
One way to get access to serviceProvider from all the classes that need it would be to add a property to all those classes and then to set that property. Or to add properties for the parts of serviceProvider that each class needs. Either of these approaches would result in lots of duplicate code.
Another approach would be to have a global variable in the scope of the thread. However, according to http://msdn.microsoft.com/en-us/library/cc151102.aspx one "should not use global class variables in plug-ins."
So what is the best way to have access to serviceProvider without passing it around everywhere?
P.S. If an example helps, serviceProvider provides access to a logging object. I want almost every class to log. I don't want to pass a reference to the logging object to every class.
That's not quite what the warning in the documentation is getting at. The IServiceProvider isn't a global variable in this context; it's a method parameter, and so each invocation of Execute gets its own provider.
For improved performance, Microsoft Dynamics CRM caches plug-in instances. The plug-in's Execute method should be written to be stateless because the constructor is not called for every invocation of the plug-in. In addition, multiple threads could be running the plug-in at the same time. All per invocation state information is stored in the context. This means that you should not use global class variables in plug-ins [Emphasis mine].
There's nothing wrong with passing objects from the context to helper classes which need them. The warning advises against storing something in a field ("class variable") on the plugin class itself, which may affect a subsequent call to Execute on the same instance, or cause concurrency problems if Execute is called by multiple threads on the same instance simultaneously.
Of course, this "globalness" has to be considered transitively. If you store anything in either the plugin class or in a helper class in any way that multiple calls to Execute can access (using fields on the plugin class or statics on either plugin or helper classes, for example), you leave yourself open to the same problem.
As a separate consideration, I would write the helper classes involved to accept types as specific to their function as possible - down to the level of individual entities - rather than the entire IServiceProvider. It's much easier to test a class which needs only an EntityReference than one which needs to have an entire IServiceProvider and IPluginExecutionContext mocked up.
On global variables vs injecting values required by classes
You're right, this is something that comes up everywhere in object-oriented code. Take a look at these two implementations:
public class CustomEntityFrubber
{
public CustomEntityFrubber(IOrganizationService service, Guid entityIdToFrub)
{
this.service = service;
this.entityId = entityIdToFrub;
}
public void FrubTheEntity()
{
// Do something with service and entityId.
}
private readonly IOrganizationService service;
private readonly Guid entityId;
}
// Initialised by the plugin's Execute method.
public static class GlobalPluginParameters
{
public static IOrganizationService Service
{
get { return service; }
set { service = value; }
}
public static Guid EntityIdToFrub
{
get { return entityId; }
set { entityId = value; }
}
[ThreadStatic]
private static IOrganizationService service;
[ThreadStatic]
private static Guid entityId;
}
public class CustomEntityFrubber
{
public FrubTheEntity()
{
// Do something with the members on GlobalPluginParameters.
}
}
So assume you've implemented something like the second approach, and now you have a bunch of classes using GlobalPluginParameters. Everything is going fine until you discover that one of them is occasionally failing because it needs an instance of IOrganizationService obtained by calling CreateOrganizationService(null), so it accesses CRM as the system user rather than the calling user (who doesn't always have the required privileges).
Fixing the second approach requires you to add another field to your growing list of global variables, remembering to make it ThreadStatic to avoid concurrency problems, then changing the code of CustomEntityFrubber to use the new SystemService property. You have tight coupling between all these classes.
Not only that, all these global variables hang around between plugin invocations. If your code has a bug that somehow bypasses the assignment of GlobalPluginParameters.EntityIdToFrub, suddenly your plugin is inexplicably operating on data that wasn't passed to it by the current call to Execute.
It's also not obvious exactly which of these global variables the CustomEntityFrubber requires, unless you read its code. Multiply that by however many helper classes you have, and maintaining this code starts to become a headache. "Now, does this object need me to have set Guid1 or Guid2 before I call it?" On top of that, the class itself can't be sure that some other code won't go and change the values of global variables it was relying on.
If you used the first approach, you simply pass in a different value to the CustomEntityFrubber constructor, with no further code changes needed. Furthermore, there's no stale data hanging around. The constructor makes it obvious which dependencies the class has, and once it has them, it can be sure that they don't change except in ways they were designed for.
As you say, you shouldn't put a member variable on the plugin since instances are cached and reused between requests by the plugin pipeline.
The approach I take is to create a class that perform the task you need and pass a modified LocalPluginContext (making it a public class) provided by the Developer Toolkit (http://msdn.microsoft.com/en-us/library/hh372957.aspx) on the constructor. Your class then can store the instance for the purposes of executing it's work just in the same way you would with any other piece of code. You are essentially de-coupling from the restrictions imposed by the Plugin framework. This approach also makes it easier to unit test since you only need to provide the execution context to your class rather than mocking the entire plugin pipeline.
It's worth noting that there is a bug in the automatically generated Plugin.cs class in the Developer Toolkit where it doesn't set the ServiceProvider property - At the end of the constructor of the LocalPluginContext add the line:
this.ServiceProvider = serviceProvider;
I have seen some implementations of an IoC approach in Plugins - but IMHO it makes the plugin code way too complex. I'd recommend making your plugins lean and simple to avoid threading/performance issues.
There are multiple things I would worry about in this design request (not that it's bad, just that one should be aware of, and anticipate).
IOrganizationService is not multi-thread safe. I'm assuming that other aspects of the IServiceProvider are not as well.
Testing things at an IServiceProvider level is much more complicated due to the additional properties that have to be mocked
You'd need a method for handle logging if you ever decided to call logic that is currently in your plugin, outside of the plugin (e.g. a command line service).
If you don't want to be passing the object around everywhere, the simple solution is to create a static property on some class that you can set it upon plugin execution, and then access from anywhere.
Of course now you have to handle issue #1 from above, so it'd have to be a singleton manager of some sort, that would probably use the current thread's id to set and retrieve the value for that thread. That way if the plugin is fired twice, you could retrieve the correct context based on your currently executing thread. (Edit Rather than some funky thread id lookup dictionary, #shambulator's ThreadStatic property should work)
For issue #2, I wouldn't be storing the IServiceProvider as is, but split up it's different properties (e.g. IPluginExecutionContext, IOrganizationService, etc)
For issue #3, it might make sense to store an action or a function in your manager rather than the object values themselves. For example, if rather than storing the IPluginExecutionContext, store a func that accepts a string to log and uses the IPlurginExeuctionContext to log. This allows other code to setup it's own logging, without being dependent on executing from within a plugin.
I haven't made any of these plugins myself, but I would treat the IServiceProvider like an I/O device.
Get the data you need from it and convert that data to format that suits your plugin. Use the transformed data to set up the other classes. Get the the output from the other classes and then translate back to terms the IServiceProvider can understand and use.
Your input and output are dependent on the IServiceProvider, but the processing doesn't have to be.
From Eduardo Avaria at http://social.microsoft.com/Forums/en-US/f433fafa-aff7-493d-8ff7-5868c09a9a9b/how-to-avoid-passing-a-context-reference-among-classes
Well, as someone at SO already told you, the global variables restriction is there cause the plugin won't instantiate again if it's called within the same context (the object context and probably other environmental conditions), so any custom global variable would be shared between that instances, but since the context will be the same, there's no problem in assigning it to a global variable if you want to share it between a lot of classes.
Anyways, I'd rather pass the context on the constructors and share it have a little more control over it, but that's just me.

C# Custom Logger - Best way to capture sending object

I am attempting to build (for learning purposes) my own event logger; I am not interested in hearing about using a non-.net frameworks instead of building my own as I am doing this to better understand .net.
The idea is to have an event system that I can write out to a log file and/or pull from while inside the program. To do this I am creating an LogEvent class that will be stored inside of a Queue<LogEvent>.
I am planning on using the following fields in my LogEvent class:
private EventLogEntryType _eventType //enum: error, info, warning...
private string _eventMessage
private Exception _exception
private DateTime _eventTime
What I am not sure is the best way to capture the object that caused the event to be called. I thought about just doing a private Object _eventObject; but I am thinking that is not thread safe or secure.
Any advice on how to best store the object that called the event would be appreciated. I am also open to any other suggestions you may have.
Thanks, Tony
First off, nothing wrong with writing your own. There are some good frameworks our there, but sometimes you reach the point where some bizarre requirement gets you rolling your own, I've been there anyway...
I don't think you should be using text messages. After doing this type of logging in several projects, I have come the the conclusion that the best approach is to have a set of event types (integer IDs) with some type of extra information field.
You should have an enum of LogEvetTypes that looks something like this:
public enum LogEventTypes
{
//1xxx WS Errors
ThisOrThatWebServiceError = 1001,
//2xxx DB access error
//etc...
}
This, from my experience will make your life much easier when trying to make use of the information you logged. You can also add an ExtraInformation field in order to provide event instance specific information.
As for the object that caused the event, I would just use something like typeof(YourClass).ToString();. If this a custom class you created, you can also implement a ToString override that will name sense in your logging context.
Edit: I am adding several details I wrote about in the comments, since I think they are important. Passing objects, which are not immutable, by ref to service methods is generally not a good idea. You might reassigne the same variable in a loop (for example) and create a bug that is near-impossible to find. Also, I would recommend doing some extra work now to decouple the logging infrastructure from the implementation details of the application, since doing this later will cause a lot of pain. I am saying this from my own very painful experience.

Logging in C#: Getting the class/method name performance

I've recently been tasked with adding logging statements to every method call in a solution. These log entries need to contain the class and method name.
I know I can use MethodBase.GetCurrentMethod() and the StackFrame.GetMethod() methods. Which is better? Is there a better (or more performant) way to get the class and method name?
Well, the best/fastest way is to include a string in every function. That may not appear the most practical solution, but MethodBase.GetCurrentMethod() requires coding inside every method that using it anyway. i.e. You can write
string funcName = "MyClass.MyFunction(int, int)";
or you can write
string funcName = MethodBase.GetCurrentMethod().Name
Now, if you want to get the Name of the function that called the current function (i.e., you want to do this in one spot in your logging function), then your only option is reading through the StackFrame.
I have two suggestions:
Use ready-made AOP frameworks (like http://www.sharpcrafters.com/ ) they can handle this easily
Do a custom prebuild action where you replace some kind of stub in the beginning of every method:
void PerformSomeAction()
{
//PUT_LOGGING_HERE
}
then in custom tool replace those stubs with method names. This is guaranteed fastest method, but requires some investments.
this.getType().toString() should get you the class
About the method it seems stackFrame and methodbase are the most obvouis solutions, I cant comment on which is more efficient.

Use Attributes To Check Whether to Access a Method

I have a method that is only accessible if a certain criteria is fulfilled, if it's not, then the method won't be executed. Currently, this is how I code the thing:
public void CanAccessDatabase()
{
if(StaticClass.IsEligible())
{
return;
}
// do the logic
}
Now, this code is ugly because out of no where there is this if(StaticClass.IsEligible()) condition that is not relevant to the concern of the method.
So I am thinking about putting the IsEligible method in the attribute, so that my code will look like this. If the condition is not fulfilled, then this method will just return without executing the logic below.
[IsEligibleCheck]
public void CanAccessDatabase()
{
// do the logic
}
Eligibility is a runtime decision, of course.
Any idea on how to code up the logic for IsEligibleCheck ? Thanks
Edit: I know PostSharp can do this, but I am looking at something that works out of box, not depending on any third party library.
Any idea on how to code up the logic for IsEligibleCheck?
This is a perfect spot for AOP.
Edit: I know PostSharp can do this, but I am looking at something that works out of box, not depending on any third-party library.
Is Microsoft considered third-party? If not, you could look at Unity from their Patterns & Practices team. Look at the Interceptor mechanism in Unity.
Otherwise, you effectively have to roll your own implementation using reflection. Effectively what you have to do is wrap your objects in a proxy wherein the proxy uses reflection to check the attributes and interpret them appropriately. If IsEligibleCheck succeeds then the proxy invokes the method on the wrapped object. Really, it's easier to just reuse an already existing implementation.
My advice is just use Unity (or another AOP solution).
Unfortunately, attributes doesn't get executed at runtime. A handful of built-in attributes modify the code that gets compiled, like the MethodImpl attributes and similar, but all custom attributes are just metadata. If no code goes looking for the metadata, it will sit there and not impact the execution of your program at all.
In other words, you need that if-statement somewhere.
Unless you can use a tool like PostSharp, then you cannot get this done in out-of-the box .NET, without explicit checks for the attributes.
This looks like a perfect candidate for AOP. In a nutshell, this means that the CanAccessDatabase logic will live in an "aspect" or "interceptor", that is, separate from the business logic, thus achieving separation of concerns (the aspect is only responsible for security, business code is only responsible for business things).
In C#, two popular options for doing AOP are Castle.DynamicProxy and PostSharp. Each has its pros and cons. This question sums up their differences.
Here are other options for doing AOP in .Net, some of them can be done without 3rd-party libraries. I still recommend using either DynamicProxy, PostSharp, LinFu, Spring.AOP or Unity, other solutions are not nearly as flexible.
Custom attributes go hand in hand with Reflection.
You will need to create another class that is responsible for calling the methods in your CanAccessDatabase() class.
Using reflection, this new class will determine the attributes on each method. If the IsEligibleCheck attribute is found, it will perform the StatiClass.IsEligible() check and only call CanAccessDatabase() if the check passes.
Heres an introduction to doing this at MSDN. It revolves around using the MemberInfo.GetCustomAttributes() method.
Heres the pseudocode:
Get the Type of the CanAccessDatabase() class
Using this type, get all methods in this class (optionally filtering public, private etc).
Loop through the list of methods
Call GetCustomAttributes() on the current method.
Loop through the list of custom attributes
If the IsEligibleCheck attribute is found
If StaticClass.IsEligible is true
Call the current method (using MethodInfo.Invoke())
End If
End If
End Loop
End Loop
I know this is an old thread...
You can use the Conditional Attribute: http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx
"Indicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined."
#define IsEligibleCheck // or define elsewhere
[Conditional("IsEligibleCheck")]
public void CanAccessDatabase()
{
// do the logic
}
check AOP that will help you a lot in this, one of the powerful components in the market is PostSharp

C# conditional logging/tracing

I want to add logging or tracing to my C# application but I don't want the overhead of formatting the string or calculating values to be logged if the log verbosity level is set so low that the message will not be logged.
In C++, you can use the preprocessor to define macros that will prevent code from being executed at all like this:
#define VLOG(level,expr) if (level >= g_log.verbosity) { g_log.output << expr; }
Used like this:
VLOG(5,"Expensive function call returns " << ExpensiveFunctionCall());
How do you do that in C#?
I've read the Microsoft docs explaining the Trace and Debug facilities here, and they claim that using #undef DEBUG and #undef TRACE removes all tracing and debugging code from the produced executable, but does it really remove the whole call? Meaning, if I write
System.Diagnostics.Trace.WriteLineIf(g_log.verbosity>=5,ExpensiveFunctionCall());
it won't call my expensive function if I undefine TRACE? Or does make the call, then decide it won't trace anything?
Anyway, even if it does remove it, this is inferior to the C++ macro because I can't make that big ugly call look like my simple VLOG() call in C++ and still avoid evaluating parameters, can I? Nor can I avoid the overhead by defining the verbosity lower at runtime like I can in C++, right?
To answer one of your questions, all method calls that must evaluate in order to call Trace.WriteLine (or its siblings/cousins) do not get called if Trace.WriteLine is compiled out. So go ahead and put your expensive method calls in directly as parameters to the Trace call and it will be removed at compile-time if you don't define the TRACE symbol.
Now for your other question regarding changing your verbosity at runtime. The trick here is that Trace.WriteLine and similar methods take 'params object[] args' for their string formatting arguments. Only when the string is actually emitted (when verbosity is set sufficiently high) does the method call ToString on those objects to get a string out of them. So a trick I often play is to pass objects rather than fully-assembled strings to these methods, and leave the string creation in the ToString of the object I pass in. That way the runtime performance tax is only paid when logging is actually occurring, and it gives you the freedom to change verbosity without recompiling your app.
A solution that has worked for me is using a singleton class. It can expose your logging functions and you can control its behavior efficiently. Lets call the class 'AppLogger'. Her is an example
public class AppLogger
{
public void WriteLine(String format, params object[] args)
{
if ( LoggingEnabled )
{
Console.WriteLine( format, args );
}
}
}
Note, the Singleton stuff is left out of the above example. There are TONS of good examples out the tubes. NOw the interesting thing is how to support multi-threading. I've done it like this: (abbreviated for brevity, hahahaha)
public static void WriteLine( String format, params object[] args )
{
if ( TheInstance != null )
{
TheInstance.TheCreatingThreadDispatcher.BeginInvoke( Instance.WriteLine_Signal, format, args );
}
}
In this way, any thread can log and the messages are handled on the original creating thread. Or you could create a special thread just for handling logging output.
ConditionalAttribute is your best friend. The call will be completely removed (as though call sites were #if'd) when the #define is not set.
EDIT: someone put this in a comment (thanks!), but worth noting in the main answer body:
All the methods of Trace class are decorated with Conditional("TRACE"). Just saw this using reflector.
Which means Trace.Blah(...expensive...) does completely disappear if TRACE is not defined.
All the info about Conditional(Trace) is good - but I assume your real question is that you want to leave the Trace calls in your production code but (usually) disable them at run-time unless you experience a problem.
If you're using TraceSource's (which I believe you should, rather than calling Trace directly because it gives you more fine-grained control over tracing at a component-level at run-time), you can do something like this:
if (Component1TraceSource.ShouldTrace(TraceEventType.Verbose))
OutputExpensiveTraceInformation()
This assumes you are able to isolate the tracing parameters in another function (i.e. they mostly depend on members of the current class rather than expensive operations on the parameters to the function in which this code is in).
The advantage of this approach is because the JITer compiles on a function-by-function basis as it needs to, if the "if" evaluates to false, the function will not only not be called - it won't even be JITed. The downside is (a) you've separated knowledge of the tracing level between this call and the function OutputExpensiveTraceInformation (so if you e.g. change the TraceEventType there to be TraceEventType.Information, for instance, it won't work because you'll never even call it unless the TraceSource is enabled for Verbose level tracing in this example) and (b) it's more code to write.
This is a case where it would seem that a C-like preprocessor would help (since it could make sure, for instance,that the parameter to ShouldTrace and to the eventual TraceEvent call are the same), but I understand why C# doesn't include that.
Andrew's suggestion of isolating expensive operations in the .ToString methods of the objects you pass to TraceEvent is also a good one; in that case, you could for instance develop an object which is just used for Trace to which you pass the objects you want to build an expensive string representation of and isolate that code in the ToString method of the trace object rather than doing it in the parameter list to the TraceEvent call (which will cause it to be executed even if the TraceLevel is not enabled at run-time).
Hope this helps.
have you tried a sophisticated logging api like log4net (http://logging.apache.org/log4net/index.html)?
Two of these answers (Andrew Arnott's and Brian's) did answer part of my question. The ConditionalAttribute that is applied to the Trace and Debug class methods causes all calls to the methods to be removed if TRACE or DEBUG are #undef'd, including the expensive parameter evaluation. Thanks!
For the second part, whether you can completely remove all calls at runtime, not at compile time, I found the answer in the log4net fac. According to them, if you set a readonly property at startup time, the runtime will compile away all calls that don't pass the test! This doesn't let you change it after startup but that's fine, it's better than removing them at compile time.
For your comment
"because I can't make that big ugly call look like my simple VLOG() call in C++ " - You could add a using statement as example below.
using System.Diagnostics;
....
Trace.WriteLineIf(.....)
As I understand, it will remove lines containing Trace, if you undefine the Trace symbol.
I'm not sure, but you can find out the answer yourself.
Make it a REALLY expensive function (like Thread.Sleep(10000)) and time the call. If it takes a very long time, then it's calling your function anyway.
(You can wrap the Trace.WriteLineIf() call with #if TRACE and #endif and test it again for a base comparison.)
It will invoke the expensive call because it might have side effects that are desired.
What you can do is decorate your expensive method with a [Conditional("TRACE")] or [Conditional("DEBUG")] attribute. The method will not be compiled into the final executable if the DEBUG or TRACE constant is not defined, nor will any calls to execute the expensive method.

Categories

Resources