Automation of function input logging

    Since time immemorial, in our company there has been a publicly-unspoken rule about logging the entrance to each function. And okay, this would be limited to a simple line of Logger.LogEntering () at the beginning (although, probably, I would also be tired of it), also our “wonderful” homegrown logger does not know how to get the names of functions from which it is called, and as a result, this is the only the line grew to an epic Logger.Log ("Classname.FunctionName - Entering") or something like that.

    It is not surprising that under the influence of recent topics about Mono.Cecil the task of process automation was born.



    In order for the product to be not only of internal corporate value, but also to be socially useful, it was decided not to limit ourselves to the support of the "internal" logger, but also to support third-party log4net and nlog (good, and for internal needs we smoothly switch to log4net).

    Concretizing the task, it is necessary to add the calls of the logger to the beginning of the functions, as well as log not only the fact of entry, but also the parameters with which the function was called.

    The entry was delayed, and it was time to move from words to deeds.
    An implementation is an msbuild-task that runs at the post-compilation stage and injects Logger.Debug ("Entering") calls at the beginning of each function. Rather, not each, but only marked with the [Log] attribute. Or in all class functions marked with this attribute. Well, or at the very beginning, at the beginning of each function of the module, if the [Log] attribute is hooped up in AssemblyInfo. If you don’t feel like logging any functions, you can mark them with the [NoLog] attribute .

    For this msbuild task to be executed, you must add its call to .csproj \ .vbproj. For example, like this:
    
    <Import Project="c:\path\to\Logging.NLog.targets" />
    

    Well, or a little change, if you prefer log4net.

    In addition, of course, it is necessary to create a logger instance into which this will be logged. LoggingMagic at the moment implies that a logger instance is accessible through a static field of a class.
    //имя класса - Logger - имеет значение. Можно менять, но тогда надо его менять и в .targets-файлеpublicclassLogger
        {
            publicstatic NLog.Logger Log = NLog.LogManager.GetLogger("NlogConsoleApp");
        }
    


    That is all. Filtering the resulting stream of logs rests entirely with the logging library. LoggingMagic is quite easy to expand, the names of the attributes and the class with the logger change in the parameters of the msbuild task.

    A serious drawback is the lack of support for the logger-per-class technique (which is propagated, for example, by nlog), logging is possible either through a static field or through a static function. In the comments, it would be interesting to find out which logging method you use :) Per-class logging will probably be added under persistent community requirements :)

    The result is a stripped-down similarity to Log4Postsharp, but without binding to proprietary components and without the need for linking with anything third-party and delivering this during installations (the loggingmagic libraries go beyond Buildserver nowhere).

    The source codes of all this disgrace are laid out on codeplex

    PS I hope that everything will not come down to a discussion about the necessity-unnecessaryness of input logging itself, because this is most often determined by the subject area. In our particular case, this is sometimes the only way to collect detailed information when problems are detected on client installations.

    Also popular now: