Log4Net如何同时使用ErrorFormat和Error

时间:2015-05-07 06:35:35

标签: c# log4net

在log4net中有2个非常好的功能:

Log.Error("Message", myException);

Log.ErrorFormat("Message {0}", CustomerId);

产生日志记录在输出日志文件中非常好。例外情况很好,因为它可以很好地打印堆栈跟踪和所有异常细节,而Format 1很好,因为它允许我指定导致失败的参数。是否存在“两全其美”的方法,或某种方式来实现它?

Log.ErrorFormatEx("Message {0}", CustomerId, myException)

编辑:我经历了可能的重复问题,但是它们格式错误,并且没有完全像这样问...我正在寻找扩展方法或现有方法

5 个答案:

答案 0 :(得分:5)

您可以创建一个扩展方法:

namespace log4net.Core
{
    public class Log4NetExtensions 
    {    
         public static void ErrorFormatEx(this ILog logger, string format, Exception exception, params object[] args) 
         {
               logger.Error(string.Format(format, args), exception);
         }
    }
}

然后您可以像使用任何其他Log4Net方法一样使用它:

Log.ErrorFormatEx("Message {0}", exception, CustomerId);

答案 1 :(得分:3)

现在用字符串插值解决了这个问题:

Log.Error($"Message {CustomerId}", myException);

答案 2 :(得分:2)

知道这已经得到了解答,但仅适用于可能会发现此替代方案有用的其他用户。我创建了一个ILog接口和一个日志类来集中"我的log4net方法和逻辑。我还为"错误"创建了多个重载。方法

<强> ILog.cs

public interface ILog
{
    void Error(Exception exception);
    void Error(string customMessage, Exception exception);
    void Error(string format, Exception exception, params object[] args);
    void Warn(Exception exception);
    void Info(string message);
}

<强> Log.cs

public class Log : ILog
{
    public void Error(Exception exception)
    {
        log4net.ILog logger = log4net.LogManager.GetLogger(exception.TargetSite.DeclaringType);
        logger.Error(exception.GetBaseException().Message, exception);
    }

    public void Error(string customMessage, Exception exception)
    {
        log4net.ILog logger = log4net.LogManager.GetLogger(exception.TargetSite.DeclaringType);
        logger.Error(customMessage, exception);
    }

    public void Error(string format, Exception exception, params object[] args)
    {
        log4net.ILog logger = log4net.LogManager.GetLogger(exception.TargetSite.DeclaringType);
        logger.Error(string.Format(format, args), exception);
    }

    public void Warn(Exception exception)
    {
        log4net.ILog logger = log4net.LogManager.GetLogger(exception.TargetSite.DeclaringType);
        logger.Warn(exception.GetBaseException().Message, exception);
    }

    public void Info(string message)
    {
        log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        logger.Info(message);
    }
}

使用示例

public MyClass DeserializeJsonFile(string path)
{
    try
    {
        using (StreamReader r = new StreamReader(path))
        {
            string json = r.ReadToEnd();
            return JsonConvert.DeserializeObject<MyClass>(json);
        }
    }
    catch (Exception ex)
    {       
        this.log.Error("Error deserializing  jsonfile. FilePath: {0}", ex, path);
        return null;                
    }
}

答案 3 :(得分:0)

最简单的方法是使用:

Log.Error($"Message {CustomerId}, {myException}");

答案 4 :(得分:0)

就我而言,我需要临时使用两个记录器(Log4Net 和 Serilog)。我没有写出很好的代码,因为解决方案是暂时的。下面是我用的。

    public void Error(Exception exception, string messageTemplate, params object[] propertyValues)
    {
        _messageTemplateProcessor.Process(messageTemplate, propertyValues, out var parsedMessage);
        Log.Error(parsedMessage, exception); //Log4Net
        _logger.Error(exception, messageTemplate, propertyValues); //Serilog
    }



using System.Collections.Generic;

namespace CommonServices
{
    class MessageTemplateProcessor
    {
        public void Process(string messageTemplate, object[] messageTemplateParameters, out string parsedMessage)
        {
            var blocks = Parse(messageTemplate);
            parsedMessage = string.Empty;

            var i = 0;
            foreach (var block in blocks)
            {
                if (!block.IsProperty)
                {
                    parsedMessage += block.Text;
                    continue;
                }

                parsedMessage += messageTemplateParameters[i];
                i++;
            }
        }


        private IEnumerable<Block> Parse(string messageTemplate)
        {
            var blocks = new List<Block>();
            
            if (string.IsNullOrEmpty(messageTemplate))
            {
                return blocks;
            }
            
            var stack = new Stack<char>();
            var word = string.Empty;

            foreach (var ch in messageTemplate)
            {
                if (ch == '{' && stack.Count == 0)
                {
                    if (!string.IsNullOrEmpty(word))
                    {
                        blocks.Add(new Block(word, false));
                        word = string.Empty;
                    }
                    
                    stack.Push(ch);
                    word += ch;
                    continue;
                }
                
                word += ch;

                if ((ch != '{' && ch != '}') || (ch == '}' && stack.Count == 0))
                {
                    continue;
                }

                if (ch == '{' && stack.Count > 0)
                {
                    stack.Push(ch);
                    continue;
                }

                if (ch == '}' && stack.Count > 0)
                {
                    if (stack.Count == 1)
                    {
                        blocks.Add(new Block(word, true));
                        word = string.Empty;
                        stack.Pop();
                        continue;
                    }

                    if (stack.Peek() == '{')
                    {
                        stack.Pop();
                    }
                    else
                    {
                        stack.Push(ch);
                    }
                }
            }

            if (!string.IsNullOrEmpty(word))
            {
                blocks.Add(new Block(word, false));
            }


            return blocks;
        }

        class Block
        {
            public Block(string text, bool isProperty)
            {
                Text = text;
                IsProperty = isProperty;
            }
            
            public string Text { get; }
            public bool IsProperty { get; }
        }
    }
}