如何在log4net的多行日志条目中添加缩进? [英] How to add indentation to multi-line log entry in log4net?

查看:121
本文介绍了如何在log4net的多行日志条目中添加缩进?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道此问题,并且我同意答案,但是我可以使用log4net进行以下操作吗?

I am aware of this question and I agree with the answer, but can I do the following with log4net?

代替:

2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1
Line 2 Line 2 Line 2 
Line 3 Line 3 Line 3
2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1
Line 2 Line 2 Line 2 
Line 3 Line 3 Line 3

我可以:

2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1
                                   Line 2 Line 2 Line 2 
                                   Line 3 Line 3 Line 3
2013-04-09 12:54:47.093 INFO Main: Line 1 Line 1 Line 1
                                   Line 2 Line 2 Line 2 
                                   Line 3 Line 3 Line 3

它是否已受支持,或者我需要编写自定义的附加程序或自定义的布局?

Is it already supported or do I need to write a custom appender or a custom layout?

推荐答案

我不愿意回答自己的问题,但是由于我自己回答了这个问题,因此我想与您分享.

I hate to answer my own questions, but since I have developed the answer myself, I wanted to share it with you.

我扩展了log4net.该解决方案继承自PatternLayout,因此所有PatternLayout功能均可用.此外,还有一个新的%indentation 模式.要获得上述示例中的日志记录,只需使用:

I extended log4net. The solution inherits from PatternLayout, so all PatternLayout features are available. In addition a new pattern %indentation is available. To get the logging like in the example above simply use:

<conversionPattern value="%date - %indentation%message%newline%exception"/>

格式化异常时,log4net代码古怪(或者我不理解).因此,在这种情况下,您应该始终将%exception放入模式中,因为我将其硬编码为"IgnoresException = false".如果IgnoresException = true,log4net会完全忽略任何格式,而您会缩进.

When formatting exceptions log4net code is quirky (or I don't understand it). So in this case you should always put %exception in the pattern, because I hardcoded "IgnoresException = false". With IgnoresException = true, log4net completely ignores any formatting and you loose indentation.

使用以下代码扩展log4net:

Use code below to extend log4net:

/// <summary>
/// Converts %indentation to string
/// </summary>
public class IndentationPatternConverter : PatternConverter
{
    protected override void Convert(TextWriter writer, object state)
    {
        // do nothing - %indentation is used for indentation, so nothing should be written
    }
}

public class IndentationPatternLayout : PatternLayout
{
    private PatternConverter m_head;

    public override void Format(TextWriter writer, LoggingEvent loggingEvent)
    {
        if (writer == null)
        {
            throw new ArgumentNullException("writer");
        }
        if (loggingEvent == null)
        {
            throw new ArgumentNullException("loggingEvent");
        }

        PatternConverter c = m_head;

        IndentationWriter indentationWriter = new IndentationWriter(writer);
        // loop through the chain of pattern converters
        while (c != null)
        {
            if (c is IndentationPatternConverter)
            {
                indentationWriter.SetIndentation();
            }
            c.Format(indentationWriter, loggingEvent);
            c = c.Next;
        }
        indentationWriter.Finish();
    }

    override public void ActivateOptions()
    {
        PatternParser patternParser = CreatePatternParser(ConversionPattern);

        ConverterInfo converterInfo = new ConverterInfo()
        {
            Name = "indentation",
            Type = typeof(IndentationPatternConverter)
        };

        patternParser.PatternConverters.Add("indentation", converterInfo);
        m_head = patternParser.Parse();

        PatternConverter curConverter = m_head;
        this.IgnoresException = false;
    }
}

public class IndentationWriter : TextWriter
{
    TextWriter writer;
    int indentation = 0;
    List<string> lines = new List<string>();

    public IndentationWriter(TextWriter writer)
    {
        this.writer = writer;
    }
    public override Encoding Encoding
    {
        get { return writer.Encoding; }
    }

    public override void Write(string value)
    {
        string[] values = value.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
        for (int i = 0; i < values.Length; i++)
        {
            if (i > 0) values[i] = Environment.NewLine + values[i];
        }
        lines.AddRange(values);
    }

    public void Finish()
    {
        for (int i = 0; i < lines.Count; i++)
        {
            string line = lines[i];
            if (i < lines.Count - 1) line = lines[i].Replace(Environment.NewLine, Environment.NewLine + new string(' ', indentation));
            writer.Write(line);
        }
        lines.Clear();
    }
    public override void WriteLine(string value)
    {
        this.Write(value + Environment.NewLine);
    }

    public void SetIndentation()
    {
        foreach (string line in lines)
        {
            indentation += line.Length;
        }
    }
}

这篇关于如何在log4net的多行日志条目中添加缩进?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆