【问题标题】:Writing To RTF File Using NLog使用 NLog 写入 RTF 文件
【发布时间】:2020-03-28 03:30:39
【问题描述】:

我正在尝试使用 NLog 写出一个 RTF 文件。我们希望每天有一个 RTF 文件,而不是每个会话。

目前,我正在尝试使用 FileTarget 的 Header 属性写出我的 RTF 文件的标题信息(最重要的是颜色表)。在我的消息Template 中,我根据日志级别和我希望日志的颜色输入了正确的标记(即\par\cr1}。然后我在Footer 中写出右括号属性。你可以在我的代码中看到这个:

        string rtf_logMessageLayout =
            "${when:when=(level==LogLevel.Trace):inner=\\cf5}" +
            "${when:when=(level==LogLevel.Debug):inner=\\cf4}" +
            "${when:when=(level==LogLevel.Info):inner=\\cf1}" +
            "${when:when=(level==LogLevel.Error):inner=\\cf3}" +
            "[${date:format=yyyy-MM-dd HH\\:MM\\:ss}]" +
            "${message}" +
            //add a ': ' if there is an exception and if ': ' isn't already at the end of the message string
            @"${when:when=length('${exception}')>0 and not ends-with('${message}', ': '):inner=\: }" +
            "${exception:format=message}\\par";

        string rtf_logFileHeader =
            @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}{\f1\fnil Microsoft Sans Serif;}}{\colortbl;\red0\green0\blue255;\red240\green240\blue240;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue0;}" +
            "===============================\\par\n" +
            "LOG FOR ${date:format=yyyy-MM-dd HH\\:MM\\:ss}\\par\n" +
            "===============================\\par\n";

        string rtf_logFileFooter = "\\cf5///////////////////\\par\n" +
             "SESSION ENDED\\par\n" +
             "///////////////////\\par\\par\\par\n" +
             "}";

        _rtfLogFileTarget = new FileTarget()
        {
            Name = "RTFLogFile",
            Header = rtf_logFileHeader,
            Footer = rtf_logFileFooter,
            Layout = rtf_logMessageLayout,
            ArchiveEvery = FileArchivePeriod.Day,
            ArchiveNumbering = ArchiveNumberingMode.Date,
            ArchiveFileName = Path.Combine(logsDirectoryPath, archiveDirectoryName, "CubbyLogFor_${#}.rtf"),
            ArchiveDateFormat = "yyyy-MM-dd",
            FileName = Path.Combine(logsDirectoryPath, "RTFLog_${date:format=yyyy-MM-dd}.rtf"),
            KeepFileOpen = true,
            ConcurrentWrites = false,
            OpenFileCacheTimeout = 30,
            EnableArchiveFileCompression = true,
        };
        LogManager.Configuration.AddTarget(_rtfLogFileTarget);
        _rtfLogFileRule = new LoggingRule("*", LogLevel.Trace, _rtfLogFileTarget);
        LogManager.Configuration.LoggingRules.Add(_rtfLogFileRule);

此系统适用于单次写入,并发写入仍会将数据写入 RTF 文件。但是有两个问题。

  1. 首先,在第一次写入完成之前,RTF 渲染器无法打开该文件,因为文件中没有右花括号,因此 RTF 渲染器认为该文件已损坏。

  2. 其次,由于在第一次写入后添加了右花括号,RTF 渲染器认为文件在第一次写入后结束,因此此后写入的任何数据都不会显示给用户,除非他们打开使用纯文本阅读器的 RTF 文件。

我试图找到其他人正在使用 NLog 编写 RTF,但我一无所获。

一种解决方法,也是我们可能会采用的方法,就是使用 RichTextBox 日志的 SaveFile() 函数将我们的 log_richTextBox 的内容写到文件中。不过,如果可能的话,我希望它能够与 NLog 一起使用。

有人对如何解决这个问题有任何想法吗?

谢谢!

【问题讨论】:

标签: c# nlog


【解决方案1】:

对于这种情况,我认为编写自定义目标更容易。

例如

public sealed class MyRtfTarget: TargetWithLayout 
{ 
    [RequiredParameter] 
    public layout FileName { get; set; }

    protected override void Write(LogEventInfo logEvent) 
    { 
        string filename = this.FileName.Render(logEvent); 

        // write to your RTF file. 
    } 

} 

在你的程序开始时(例如主程序),

Target.Register<MyRtfTarget>("MyRtfTarget"); 

NLog - How to write a custom target

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 2010-09-22
    相关资源
    最近更新 更多