How to escape newline characters in the message?

丶灬走出姿态 提交于 2020-01-02 03:55:06

问题


I'm using log4net with FileAppender. The layout pattern is "%utcdate %message%newline", so every message takes 1 line.
However, there is an issue with messages containing new line chars; is it possible to escape new lines before writing to the file?


回答1:


You can create a custom PatternConverter which escapes the newline characters.

This provides a more flexible solution than the other answer because you can use it with any appender.

I followed these articles to implement a custom PatternConverter that replaces the newline characters with spaces:

https://dejanfajfar.wordpress.com/2011/04/14/log4net-custom-layoutpattern/

http://www.hanselman.com/blog/CreatingYourOwnCustomPatternLayoutPatternParserAndPatternConvertorWithLog4net.aspx

The code for the custom PatternConverter looks like this:

using System.IO;
using log4net.Util;

public class EncodedMessagePatternConvertor : PatternConverter
{
    protected override void Convert(TextWriter writer, object state)
    {
        var loggingEvent = state as log4net.Core.LoggingEvent;

        if (loggingEvent == null)
            return;

        // Replace newline characters with spaces
        var encodedMessage = loggingEvent.RenderedMessage.Replace("\r", " ").Replace("\n", " ");

        writer.Write(encodedMessage);
    }
}

The code for the custom PatternLayout looks like this:

using log4net.Layout;
using log4net.Util;    

public class CustomPatternLayout : PatternLayout
{
    public CustomPatternLayout()
    {
        AddConverter(new ConverterInfo { Name = "encodedmessage", Type = typeof(EncodedMessagePatternConvertor) });
    }
}

The appender configuration should look something like this:

<appender name="SomeAppender" type"...">
    ...
    <layout type="YourNamespace.CustomPatternLayout, YourAssemblyName">
      <conversionPattern value="%date %-5level %logger %encodedmessage %newline" />
    </layout>
</appender>

I chose "encodedmessage" for the pattern name, but you can name it whatever you like by changing it in the AddConverter call and the configuration.

This solution should work for other encoding requirements by changing the code in the Convert method to suit your needs.




回答2:


My solution so far is to use a custom file appender:

class MyFileAppender : FileAppender
{
    protected override void Append(LoggingEvent loggingEvent)
    {
        var val = Convert(loggingEvent);
        base.Append(val);
    }

    protected override void Append(LoggingEvent[] loggingEvents)
    {
        var vals = loggingEvents.Select(Convert).ToArray();
        base.Append(vals);
    }

    private static LoggingEvent Convert(LoggingEvent loggingEvent)
    {
        var eventData = loggingEvent.GetLoggingEventData();
        eventData.ExceptionString = Convert(eventData.ExceptionString);
        eventData.Message = Convert(eventData.Message);
        var val = new LoggingEvent(eventData);
        return val;
    }

    static string Convert(object val)
    {
        var res = val.ToString().Replace("\r", "\\r").Replace("\n", "\\n");
        return res;
    }
}



回答3:


The solution suggested by Avalanchis works. However, I came to this thread for finding the solution for attaching the exception message and the stack trace in a single line. So, I changed the Convert method to something like this:

        protected override void Convert(TextWriter writer, object state)
        {
            var loggingEvent = state as log4net.Core.LoggingEvent;
            string encodedMessage = string.Empty;

            if (loggingEvent == null)
            {
                return;
            }

            // Replace newline characters with <space>
            if (loggingEvent.ExceptionObject == null)
            {
                encodedMessage = loggingEvent.RenderedMessage.Replace("\r\n", " ");
            }
            else
            {
                encodedMessage = loggingEvent.GetExceptionString().Replace("\r\n", " ");
            }

            writer.Write(encodedMessage);
        }

Also, I had to set IgnoresException property to false in the layout tag in log4net configuration:

  <layout type="{Namespace}.CustomPatternLayout">
    <IgnoresException value="False" />
    <conversionPattern value="%date %-5level %logger - %encodedmessage%newline" />
  </layout>

This specifies not to include the exception data as we have already included the same in the encoded message.



来源:https://stackoverflow.com/questions/19993416/how-to-escape-newline-characters-in-the-message

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!