【问题标题】:Log4Net in .Net Core application: LoggingEvent not set properly (LocationInformation porperties are set to "?").Net Core 应用程序中的 Log4Net:LoggingEvent 设置不正确(LocationInformation 属性设置为“?”)
【发布时间】:2023-03-06 00:23:01
【问题描述】:

到目前为止,我们一直在针对 .NET 4.6.1 的项目中使用 log4net,它的工作原理非常棒。几个月前,我们开始实施我们的第一个 .NET 核心项目。但是 log4net 似乎在这个框架上存在问题。我们已经编写了自己的附加程序,将所有日志事件推送到我们的日志系统。然而,在核心项目中,LoggingEvent 对象中缺少基本信息。

我已经建立了一个名为Log4NetUnitTest 的最小测试项目来重复该行为。

csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="log4net" Version="2.0.8" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
    <PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
    <PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
  </ItemGroup>

</Project>

单元测试类以编程方式配置记录器(我也通过文件测试了配置,结果相同):

[TestClass]
public class LoggingTests
{
    [TestMethod]
    public void Log()
    {
        var logger = LogManager.GetLogger(typeof(LoggingTests));
        var appender = new MyAppender();

        var loggerLogger = (log4net.Repository.Hierarchy.Logger)logger.Logger;
        loggerLogger.Level = Level.All;
        loggerLogger.AddAppender(appender);
        loggerLogger.Hierarchy.Configured = true;

        try
        {
            throw new Exception("Some exception");
        }
        catch (Exception e)
        {
            logger.Error("Some error text", e);
        }
    }
}

自定义附加程序(简单地将 JSON 格式的事件写入控制台):

public sealed class MyAppender : AppenderSkeleton
{
    private static readonly JsonSerializerSettings _settings = new JsonSerializerSettings
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
        Formatting = Formatting.Indented
    };

    protected override void Append(LoggingEvent loggingEvent)
    {
        var loggingObject = new
        {
            ApplicationName = System.Reflection.Assembly.GetEntryAssembly()?.GetName().Name ?? System.Reflection.Assembly.GetExecutingAssembly().GetName().Name,
            Method = loggingEvent.LocationInformation.MethodName,
            Line = loggingEvent.LocationInformation.LineNumber,
            Class = loggingEvent.LocationInformation.ClassName,
            loggingEvent.LoggerName,
            Environment.MachineName,
            ExceptionMessage = loggingEvent.ExceptionObject?.Message,
            Message = loggingEvent.MessageObject,
            Level = loggingEvent.Level.Name
        };

        string serializedLog = JsonConvert.SerializeObject(loggingObject, _settings);

        Console.WriteLine(serializedLog);
    }
}

当你运行测试时,你会得到如下输出:

{
  "ApplicationName": "testhost",
  "Method": "?",
  "Line": "?",
  "Class": "?",
  "LoggerName": "Log4NetUnitTest.LoggingTests",
  "MachineName": "NBG-ITSD-138",
  "ExceptionMessage": "Some exception",
  "Message": "Some error text",
  "Level": "ERROR"
}

所以MethodLineClass 无法解析。还有一些其他属性(我们没有使用),如 DomainIdentityUserName 只是设置为“不可用”。当您将 TargetFramework 更改为 net461 时,所有属性都已正确设置:

{
  "ApplicationName": "Log4NetUnitTest",
  "Method": "Log",
  "Line": "31",
  "Class": "Log4NetUnitTest.LoggingTests",
  "LoggerName": "Log4NetUnitTest.LoggingTests",
  "MachineName": "NBG-ITSD-138",
  "ExceptionMessage": "Some exception",
  "Message": "Some error text",
  "Level": "ERROR"
}

几年前有人有类似的problem(不是NET core),可以在Append()方法的开头添加loggingEvent.Fix = FixFlags.All;来解决。不过对我没用:-(

我想我需要添加一些配置或附加包,但我不知道出了什么问题。非常感谢任何建议。

【问题讨论】:

  • 你在哪里可以解决这个问题?
  • @JPGarza 好吧,不是单独使用 log4net 包。在我们的 appender 中,我检查 MethodNameLineNumber 等字段是否设置正确。如果没有,我自己解析StackTrace 以提取位置信息。本质上,它是 log4net LocationInfo 类本身的代码,经过一些调整。

标签: c# .net-core log4net


【解决方案1】:

查看LocationInfo.cs 的源代码,似乎很多功能都包含在#if !(NETCF || NETSTANDARD1_3) 块中,这就是为什么在使用.NET Core 时没有设置它的原因。我认为此功能在 .NET Standard 1.3 中不可用。

Apache JIRA 中存在一个问题LOG4NET-606,其中提到更高版本的 .NET Standard 添加了缺失的功能,如果将 log4Net 升级为针对更高的 .NET Standard 版本,则可以恢复这些值。对此问题进行投票和评论可能会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-28
    • 2011-04-13
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 2018-06-23
    • 1970-01-01
    相关资源
    最近更新 更多