Search code examples
c#loggingarchitecturesolid-principlessingle-responsibility-principle

Logging operations, how to implement better


I need to implement logging of some calls of methods with many logging information (time etc). I can do it like this:

var stopwatch = new Stopwatch();
OCRResult ocrResult = await ocr.GetTextAsync(dataStream, filename, language);
stopwatch.Stop();
// log here, with time, result etc

It would work, but I don't like this approach. First at all, I have many such calls in many places and I have to dublicate code. Secondly, this approach violates SRP (single responsible principle), where each call does one work. I need to do a wrapper or use Strategy pattern, in any case I should create one more class to do it. But how to implement it?


Solution

  • You can create a generic method that measures the time of a function and logs it:

    public static void LogFunc<T>(Func<T> func)
    {
        var stopwatch = Stopwatch.StartNew();
        T result = func();
        stopwatch.Stop();
        long time = stopwatch.ElapsedMilliseconds;
        // log here, with time, result etc
    }
    
    LogFunc(async () => await ocr.GetTextAsync(dataStream, filename, language));
    

    An async version of this method:

    public static async Task LogFuncAsync<T>(Func<Task<T>> func)
    {
        var stopwatch = Stopwatch.StartNew();
        T result = await func();
        stopwatch.Stop();
        long time = stopwatch.ElapsedMilliseconds;
        // log here, with time, result etc
    }
    
    await LogFuncAsync(() => ocr.GetTextAsync(dataStream, filename, language));