Запись в файл RTF с использованием NLog - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь записать файл RTF, используя NLog. Мы хотим иметь один файл RTF в день, а не на сеанс.

В настоящее время я пытаюсь записать информацию заголовка моего файла RTF (наиболее важно таблицу цветов), используя атрибут Header объекта FileTarget. , В моем сообщении Template я ставлю соответствующие маркеры (ie \par и \cr1} в зависимости от уровня журнала и цвета, который я хочу, чтобы журналы были. Затем я записываю закрывающую скобку в * Атрибут 1007 *. Вы можете увидеть это в моем коде здесь:

        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 с помощью программы чтения простого текста.

Я пытался найти других, работающих над записью RTF с использованием NLog, но я ничего не нашел.

Обходной путь, и вместо этого мы можем go просто использовать функцию SaveFile() журнала RichTextBox для записи содержимого нашего log_richTextBox в файл. Однако, если возможно, я бы хотел, чтобы это работало с NLog.

У кого-нибудь есть идеи, как решить эту проблему?

Спасибо!

1 Ответ

0 голосов
/ 27 марта 2020

В этом случае я думаю, что проще написать собственную цель.

Например,

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 - Как написать собственную цель

...