PostSharp 日志记录 添加 >>> 和 <<< 到方法 Entry/Exit 日志条目

PostSharp Logging Add >>> and <<< to Method Entry/Exit Log Entries

有人可以告诉我是否可以在方法进入和退出时将 >>> 和 <<< 添加到 PostSharp Logging 创建的日志条目中吗?如果可能的话,有人可以帮助我入门吗?

Google 不是朋友,PostSharp 的文档也没有帮助。我看到我可以在哪里创建自定义格式化程序或后端,但在这些示例中我没有看到如何自定义方法进入和方法退出的日志条目。

带 NLog 的实际 PostSharp 日志输出

2021-10-01 16:29:16.5539|DEBUG|jaslibdss.libddss|    libddss.get_Database()|Starting.
2021-10-01 16:29:16.5539|DEBUG|jaslibdss.libddss|    libddss.get_Database()|Succeeded: returnValue = "master", executionTime = 0.11 ms.

带 NLog 的所需 PostSharp 日志输出

2021-10-01 16:29:16.5539|DEBUG|jaslibdss.libddss|   >>> libddss.get_Database()|Starting.
2021-10-01 16:29:16.5539|DEBUG|jaslibdss.libddss|   <<< libddss.get_Database()|Succeeded: returnValue = "master", executionTime = 0.11 ms.

我正在使用以下内容:

NLog nuget 4.7.11
PostSharp nuget 6.9.9
PostSharp.Patterns.Diagnostics nuget 6.9.9
PostSharp.Patterns.Diagnostics.NLog nuget 6.9.9

我正在使用直接从他们的示例中提取的 NLog 配置:

      // Configure NLog.
      var nlogConfig = new LoggingConfiguration();

      var fileTarget = new FileTarget("file")
      {
        FileName = "nlog.log",
        KeepFileOpen = true,
        ConcurrentWrites = false
      };

      nlogConfig.AddTarget(fileTarget);
      nlogConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, fileTarget));

      var consoleTarget = new ConsoleTarget("console");
      nlogConfig.AddTarget(consoleTarget);
      nlogConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, consoleTarget));



      // Configure PostSharp Logging to use NLog.
      LoggingServices.DefaultBackend = new NLogLoggingBackend(new LogFactory(nlogConfig));

      LogManager.EnableLogging();

我没有任何其他代码可以显示,因为我不知道从哪里开始编写代码。

*** 编辑 ***

    internal class MyBackend : NLogLoggingBackend
    {
        public override MyLogBuilder CreateRecordBuilder()
        {
            return new MyLogBuilder(this);
        }
    }

    internal class MyLogBuilder : NLogLogRecordBuilder
    {
        public MyLogBuilder(NLogLoggingBackend backend) : base(backend)
        {
           
        }

        protected override void Write()
        {

        }
    }

到目前为止已经试过了,但是“protected override void Write()”告诉我没有合适的 Write 方法可以覆盖。但是,我确实看到了 WriteCustomString 方法。你是这个意思吗?

*** 编辑#2 ***

    internal class MyBackend : NLogLoggingBackend
    {
        public MyBackend(LoggingConfiguration config) : base(new LogFactory(config))
        {

        }

        public override MyLogRecordBuilder CreateRecordBuilder()
        {
            return new MyLogRecordBuilder(this);
        }
    }

    internal class MyLogRecordBuilder : NLogLogRecordBuilder
    {
        public MyLogRecordBuilder(NLogLoggingBackend backend) : base(backend)
        {

        }

        public void Write()
        {
            if (this.RecordKind == LogRecordKind.MethodEntry)
            {
                base.Write(new PostSharp.Patterns.Formatters.UnsafeString(">>> Hello, world!"));
            }
            
            if (this.RecordKind == LogRecordKind.MethodSuccess)
            {
                base.Write(new PostSharp.Patterns.Formatters.UnsafeString("<<< Hello, world!"));
            }
        }
    }

然后

            // Configure NLog.
            var nlogConfig = new LoggingConfiguration();

            var fileTarget = new FileTarget("file")
            {
                FileName = "nlog.log",
                KeepFileOpen = true,
                ConcurrentWrites = false,
            };

            nlogConfig.AddTarget(fileTarget);
            nlogConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, fileTarget));

            var consoleTarget = new ConsoleTarget("console");
            nlogConfig.AddTarget(consoleTarget);
            nlogConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, consoleTarget));

            LogManager.EnableLogging();


            // Configure PostSharp Logging to use NLog.
            NLogLoggingBackend b = new MyBackend(nlogConfig);
            //b.Options.IndentSpaces = 0;
            LoggingServices.DefaultBackend = b;

但是,我遇到了堆栈溢出错误。 :/

*** 编辑 3 ***

    public class MyBackend : NLogLoggingBackend
    {
        public MyBackend(LoggingConfiguration config) : base(new LogFactory(config))
        {
            Options.IndentSpaces = 4;
            Options.Delimiter = " - ";
            Options.IncludeType = false;
        }

        public override MyLogRecordBuilder CreateRecordBuilder()
        {
            return new MyLogRecordBuilder(this);
        }
    }

    [Log(AttributeExclude = true)]
    public class MyLogRecordBuilder : NLogLogRecordBuilder
    {
        public MyLogRecordBuilder(NLogLoggingBackend backend) : base(backend)
        {
            System.Console.WriteLine(@"DEBUG---" + backend.Options.Delimiter);
            System.Console.WriteLine(@"DEBUG---" + backend.Options.IndentSpaces);
        }

        protected override void Write(UnsafeString message)
        {
            if (this.RecordKind == LogRecordKind.MethodEntry)
            {
                base.Write(new PostSharp.Patterns.Formatters.UnsafeString(">>> Hello, world!"));
            }

            if (this.RecordKind == LogRecordKind.MethodSuccess)
            {
                base.Write(new PostSharp.Patterns.Formatters.UnsafeString("<<< Hello, world!"));
            }
        }
    }

编辑 #3 是我当前有效的代码。我现在正在日志条目文本中使用 <<< 和 >>> 获取日志输出。但是,我无法申请任何 backend.Options。例如,我坚持使用 | 的默认分隔符而且我根本没有缩进。

注意:在我上面的两个 DEBUG WriteLine 中,我确实看到了“-”的预期选项值和 4 个缩进空格。

问题:当我覆盖 Write 方法时,我是否需要添加任何特殊的东西来使用这些选项,或者应该应用这些选项而我做错了什么?

您必须创建一个派生自 NLogLoggingBackend 的自定义日志记录后端。

  • 创建一个从 NLogLoggingBackend 派生的 class。

  • 创建一个从 NLogLogRecordBuilder 派生的 class。

  • 覆盖 NLogLoggingBackend.CreateRecordBuilder 以便它 returns 您的 NLogLogRecordBuilder.

    的新实例
  • 覆盖 NLogLogRecordBuilder.Write。您可以使用自己的字符串调用基础 NLogLogRecordBuilder.Write 方法。

    • 或者,你也可以直接调用NLog.Logger,你可以从表达式((NLogLoggingTypeSource) this.TypeSource).Logger.
    • 中得到
    • 要确定消息的种类(进入、成功、失败),请使用 LogRecordBuilder.RecordKind
  • 或者您可以覆盖 AppendProlog 并在调用 base.AppendProlog 之前插入 >>><<<(通过将其附加到 this.StringBuilder), 但是你的字符甚至会在缩进之前插入。