logging-log4net-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Duncan Woods" <duncan.wo...@garradhassan.com>
Subject RE: When to log, when to throw - Help!
Date Thu, 06 Jul 2006 13:35:13 GMT
Hi there,

I have come up with a solution which I think works well enough for me.
It is to store the deepest level of context reached and instead of
popping off each level as the context goes out of scope, it is only
updated when a new context block is started.

The only drawback is that if an exception is thrown /after/ a context
block then it will be misleading. In the code below, if you throw at
XXX, then the NDC will be for the preceding block. I'll simply have to
treat this as part of the coding standards to only apply context to
entire levels of scope.

Any better suggestions?

Thanks,
Duncan




using System;
using System.Collections.Generic;
using System.Text;
using log4net;
using log4net.Appender;
using log4net.Layout;
using log4net.Config;
using System.Diagnostics;

namespace ConsoleApplication1
{

    class Program
    {
        static ConsoleAppender consoleAppender;
        static ILog log;

        static void Main(string[] args)
        {
            consoleAppender = new ConsoleAppender();
            consoleAppender.Layout = new PatternLayout("MESSAGE
[%message] NDC [%ndc]%newline");
            BasicConfigurator.Configure(consoleAppender);
            log = LogManager.GetLogger(typeof(Program));

            int[] oddNumbers = new int[5] { 1, 3, 5, 7, 9 };
            int[] evenNumbers = new int[5] { 2, 4, 6, 8, 10 };

            try
            {
                foreach (int oddNumber in oddNumbers)
                {
                    using (Context.Push("oddNumber: " + oddNumber))
                    {
                        foreach (int evenNumber in evenNumbers)
                        {
                            using (Context.Push("evenNumber: " +
evenNumber))
                            {
                                if (oddNumber == 7)
                                {
                                    throw new ApplicationException("Oh
no!");
                                }
                                log.DebugFormat("Sum: {0}", oddNumber +
evenNumber);
                            }
                            // XXX
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Context.LogException(log, "Unhandled exception '" +
ex.Message + "'", ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public class Context : IDisposable
        {
            public static Context Push(string s)
            {                
                return new Context(s);
            }
           
            // Log the exception with the deepest ndc reached
            public static void LogException(ILog log, string message,
Exception e)
            {
                Stack<string> ndc = new Stack<string>();                
                while (NDC.Depth > 0)
                {
                    ndc.Push(NDC.Pop());
                }

                NDC.Push(DeepestNdc);

                log.Error(message, e);
                
                NDC.Pop();
                
                while (ndc.Count > 0)
                {
                    NDC.Push(ndc.Pop());
                }
            }

            // Convert the deepest ndc to a string
            public static string DeepestNdc
            {
                get
                {
                    int i =
System.Threading.Thread.CurrentThread.ManagedThreadId;

                    Stack<string> context;
                    if (!deepest.TryGetValue(i, out context))
                    {
                        return "";
                    }
                    
                    Stack<string> temp = new Stack<string>();
                    StringBuilder sb = new StringBuilder();
                    while (context.Count > 0)
                    {
                        temp.Push(context.Pop());
                    }
                    while (temp.Count > 0)
                    {
                        string ndc = temp.Pop();
                        sb.AppendFormat("{0} ", ndc);
                        context.Push(ndc);
                    }
                    return sb.ToString();
                }
            }

            // Reset the deepest context to the current NDC value
            public Context(string s)
            {
                int i =
System.Threading.Thread.CurrentThread.ManagedThreadId;

                Stack<string> context;
                if (!deepest.TryGetValue(i, out context))
                {
                    context = new Stack<string>();
                    deepest[i] = context;
                }

                while (context.Count > NDC.Depth)
                {
                    context.Pop();
                }
                context.Push(s);

                NDC.Push(s);
            }

            public void Dispose()
            {
                NDC.Pop();                
            }

            static Dictionary<int, Stack<string>> deepest = new
Dictionary<int, Stack<string>>();
        }

    }

}

Mime
View raw message