Trace Log - Execution History

How to capture method execution history in C#?

Executed Output for our example

Below output shows how we have captured the trace information such as "Execution Order", "Elapsed Time", "Executed Time", "Method", "Class" and "Line"

Message Pattern

public class MessageTree
{
    public int ExecutionOrder { get; set; }
    public DateTime ExecutionTime { get; set; }
    public long ElapsedTime { get; set; }
    public long TotalElapsedTime { get; set; }
    public dynamic TraceMessage { get; set; }
    public string Method { get; set; }
    public string Class { get; set; }
    public int Line { get; set; }
}

The above is the model class which holds the message of each executed methods.

Full Class

TraceTree.cs
public class TraceTree : IDisposable
{        
    static IList<MessageTree> lstMsgTrees;
    static int messageCount = 0;
    static long calExeTime = 0;//Calculate Execution Time
    static Stopwatch watch;

    public TraceTree()
    {
        LogStart();
    }
    private  void LogStart()
    {
        watch = Stopwatch.StartNew();
        lstMsgTrees = new List<MessageTree>();           
    }
    public void LogTrace(string message)
    {
        if(lstMsgTrees == null)
        {
            Console.WriteLine("Initiate TraceTrace, by 'using' block and invoke .LogTrace(..)'.");
            throw new Exception("Initiate TraceTrace, by 'using' block and invoke .LogTrace(..)'.");
        }
        else
        {
            LogTree(message);
        }           
    }
    public static void LogTree(string message)
    {
        var obj = new StackTrace(true);
        messageCount++;//method execution count iterated.
        calExeTime = watch.ElapsedMilliseconds - calExeTime;
        MessageTree messageTree = new MessageTree()
        {
            Class = obj.GetFrame(1).GetMethod().ReflectedType.FullName,
            Method = obj.GetFrame(1).GetMethod().Name,
            ExecutionOrder = messageCount,
            ExecutionTime = DateTime.Now,
            ElapsedTime = calExeTime,
            TotalElapsedTime = watch.ElapsedMilliseconds,
            Line = obj.GetFrame(1).GetFileLineNumber(),
            TraceMessage = message                
        };
        lstMsgTrees.Add(messageTree);                     
        obj = null;
        Console.WriteLine(message);//just to show case the message.
    }
    private static void Print()
    {
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine("Log Tree: {0}", JsonConvert.SerializeObject(lstMsgTrees, Formatting.Indented));
        //Logger.Log.Information(JsonConvert.SerializeObject(lstTrace, Formatting.Indented));
    }
    private static void LogStop()
    {
        Print();
        watch.Stop();
        watch = null;
        lstMsgTrees.Clear();
        lstMsgTrees = null;
    }

    #region Disposable Object
    protected virtual void Dispose(bool disposing)
    {
        LogStop();
        // Dispose managed state (managed objects).
    }
    public void Dispose() => Dispose(true);
    #endregion

}

How to invoke or how to use this ?

using (var trace = new TraceTree())
{
    //Do your stuff
    TraceTree.LogTree("Capture Initiated.");
    ChildMethod();
}

public void ChildMethod()
{
    TraceTree.LogTree("Child method invoked..");
    //It goes on you can have 'n' number of methods to capture
}

Last updated