C# log4net可以输出Json吗?

C# log4net可以输出Json吗?,c#,json,wpf,log4net,C#,Json,Wpf,Log4net,我已经看到了log4net的几个扩展,它们声称可以为日志文件创建json,但是格式从来都不是有效的json,这意味着集合不在数组中,也不分开。是我用错了,还是根本没有办法将log4net与json一起使用 <appender name="SessionFileAppender" type="log4net.Appender.FileAppender"> <file value="Session.log" /> <appendToFile value="fal

我已经看到了log4net的几个扩展,它们声称可以为日志文件创建json,但是格式从来都不是有效的json,这意味着集合不在数组中,也不分开。是我用错了,还是根本没有办法将log4net与json一起使用

<appender name="SessionFileAppender" type="log4net.Appender.FileAppender">
  <file value="Session.log" />
  <appendToFile value="false" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type='log4net.Layout.SerializedLayout, log4net.Ext.Json'>
    <decorator type='log4net.Layout.Decorators.StandardTypesDecorator, log4net.Ext.Json' />
    <default />
    <remove value='message' />
    <member value='message:messageobject' />
  </layout>
</appender>

这很接近,但不是真正有效的json。

它将每一行作为单独的json记录输出,就像它对一行日志所做的那样。
你可以一行一行地解析,也可以在每个}之后添加你周围的[]和一个逗号,这样就可以了。

解决方案足够基本,我编写了自己的
Appender
,将数据存储在一个集合中,然后根据需要用Json.net序列化该集合。这也让我能够在应用程序中查看日志并绑定到它,因此增加了额外的好处

public class CollectionAppender : AppenderSkeleton
{
    public static ObservableCollection<LogItem> logData = new ObservableCollection<LogItem>();
    protected override void Append(LoggingEvent loggingEvent)
    {
        logData.Add(new LogItem(loggingEvent));
    }
}

public class LogItem
{
    public string Logger { get; private set; }
    public string Level { get; private set; }
    public string Message { get; private set; }
    public DateTime Timestamp { get; private set; }
    public Exception ExceptionData { get; private set; }

    public bool ShouldSerializeExceptionData() //This keeps things tidy when using Json.net for non exemption entries.
    {
        return ExceptionData != null;
    }

    public LogItem(LoggingEvent data)
    {
        Logger = data.LoggerName;
        Level = data.Level.DisplayName;
        Message = data.RenderedMessage;
        Timestamp = data.TimeStamp;
        ExceptionData = data.ExceptionObject;
    }
}
公共类集合出现者:AppenderSkeleton
{
公共静态ObservableCollection logData=新ObservableCollection();
受保护的覆盖无效附加(LoggingEvent LoggingEvent)
{
添加(新登录项(loggingEvent));
}
}
公共类登录
{
公共字符串记录器{get;private set;}
公共字符串级别{get;private set;}
公共字符串消息{get;private set;}
公共日期时间时间戳{get;private set;}
公共异常例外数据{get;private set;}
public bool shouldSerializedExceptionData()//在使用Json.net处理非豁免条目时,这可以保持整洁。
{
返回ExceptionData!=null;
}
公共登录项(记录事件数据)
{
Logger=data.LoggerName;
级别=data.Level.DisplayName;
Message=data.renderMessage;
Timestamp=data.Timestamp;
ExceptionData=data.ExceptionObject;
}
}
下载

将以下配置设置添加到app.config/web.config文件

<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
  <file value="logs\log-file-name.json" />
  <rollingStyle value="Date" />
  <datePattern value="yyyy-MM-dd" />
  <PreserveLogFileNameExtension value="true" />
  <staticLogFileName value="false" />
  <appendToFile value="true" />
  <maxSizeRollBackups value="10" />
  <dateTimeStrategy 
  type="log4net.Appender.RollingFileAppender+UniversalDateTime" />

  <!--text formatted log4net logging-->
  <!--<layout type="log4net.Layout.PatternLayout">
    --><!--check conversion patterns from 
   https://logging.apache.org/log4net/--><!--
    --><!--<conversionPattern value="%utcdate{ABSOLUTE} UTC %c{1} - %m%n" 
  />--><!--
    <conversionPattern value="%date [%thread] %-5level %logger - 
  %message%newline" />
  </layout>-->

  <!--json formatted log4net logging-->
  <layout type="log4net.Layout.SerializedLayout, log4net.Ext.Json">
    <decorator type="log4net.Layout.Decorators.StandardTypesDecorator, 
  log4net.Ext.Json" />
    <member value="date:date" />
    <member value="level:level" />
    <member value="logger:logger" />
    <member value="message:messageObject" />
    <member value="exception:exception" />
  </layout>
</appender>
<root>
  <!--Options are "ALL", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" and 
"OFF".-->
  <level value="DEBUG" />
  <appender-ref ref="RollingFile" />
</root>
</log4net>

这是ninject的一个示例调用

Kernel = new StandardKernel(); 
Kernel.Bind<ILog>().ToMethod(c => 
LogManager.GetLogger(typeof(YourClassName))).InSingletonScope();
var log = Kernel.Get<ILog>();
log.debug("testing log4net json");
Kernel=新的标准内核();
Kernel.Bind().ToMethod(c=>
LogManager.GetLogger(typeof(YourClassName)).InSingletonScope();
var log=Kernel.Get();
调试(“测试log4net json”);

如果我仍然必须迭代并重新解析一个文件,那么它就有点达不到目的。你是对的@Wobbles,但这对他们来说也有点困难,因为日志打开写关闭流,所以我认为维护json格式会很棘手,除非文件在内存中,并且在每次写入记录时都被重写。不考虑,我想知道是否有一种方法直接序列化ILOG集合,然后作为NeeDeIf如果您没有找到一个解决方案,并且使用它,因为它是在C或JS中,那么我建议您添加(和)并用(})替换所有(})。它只需要一次解析就可以了,虽然很重,但也可以做到这一点@摆动可以在appender水平仪上实现。log4net.Ext.Json用作单个日志事件的布局。如果按照@MoustafaS的建议进行字符串替换,请将coma放在每一新行之前,而不是
}
,因为图形可以嵌套,或者数据可能包含
}
,而新行在默认情况下会转义。这是一个很好的解决方案!log4net是否仍在积极维护中,如果它在那里就好了——也许是一个contrib?我在测试场景中使用这种方法。如果这就是您所需要的,那么就足够简单了。您的输出看起来像是有效的JSON行格式:
Kernel = new StandardKernel(); 
Kernel.Bind<ILog>().ToMethod(c => 
LogManager.GetLogger(typeof(YourClassName))).InSingletonScope();
var log = Kernel.Get<ILog>();
log.debug("testing log4net json");