1

JsonLogFormatter を使用するときに、RollingFlatFileTraceListenerData が有効な JSON ドキュメントを作成する方法を探しています。XML パーサーと同様に、RollingFlatFileTraceListenerData はアイテムを追加するだけで、アイテム ヘッダーとフッターを追加するオプションを提供するだけで、より高いレベルのファイル ヘッダー、フッター ヘッダー、およびアイテム セパレーターは追加しません。後でファイルを変更できることはわかっていますが、プロセスを有効な形式でビルドしたいと考えています。アクティブなファイルを外部プロセスで開くと、ファイルを開いて再度ログを記録する必要がある場合にログ プロセスがブロックされる可能性があるため、危険です。

現在の出力:

{
  "Message": "Log entry created using the simplest overload.",
  "Categories": [
    "General"
  ],
  "Priority": -1,
  "EventId": 1,
  "Severity": 8,
  "LoggedSeverity": "Information",
  "Title": "",
  "TimeStamp": "2013-11-07T20:33:38.6537773Z",
  "MachineName": "Acme01",
  "AppDomainName": "Acme.TestDriver.vshost.exe",
  "ProcessId": "10348",
  "ProcessName": "C:\\dev\\Acme.TestDriver\\bin\\Debug\\Acme.TestDriver.vshost.exe",
  "ManagedThreadName": null,
  "Win32ThreadId": "11204",
  "ExtendedProperties": {},
  "TimeStampString": "11/7/2013 8:33:38 PM",
  "ActivityId": "00000000-0000-0000-0000-000000000000",
  "RelatedActivityId": null,
  "ErrorMessages": null,
  "ActivityIdString": "00000000-0000-0000-0000-000000000000",
  "CategoriesStrings": [
    "General"
  ]
}
{
  "Message": "Log entry with a single category.",
  "Categories": [
    "General"
  ],
  "Priority": -1,
  "EventId": 1,
  "Severity": 8,
  "LoggedSeverity": "Information",
  "Title": "",
  "TimeStamp": "2013-11-07T20:33:38.6537773Z",
  "MachineName": "Acme01",
  "AppDomainName": "Acme.TestDriver.vshost.exe",
  "ProcessId": "10348",
  "ProcessName": "C:\\dev\\Acme.TestDriver\\bin\\Debug\\Acme.TestDriver.vshost.exe",
  "ManagedThreadName": null,
  "Win32ThreadId": "11204",
  "ExtendedProperties": {},
  "TimeStampString": "11/7/2013 8:33:38 PM",
  "ActivityId": "00000000-0000-0000-0000-000000000000",
  "RelatedActivityId": null,
  "ErrorMessages": null,
  "ActivityIdString": "00000000-0000-0000-0000-000000000000",
  "CategoriesStrings": [
    "General"
  ]
}

優先:

[
 {
      "Message": "Log entry created using the simplest overload.",
      "Categories": [
        "General"
      ],
      "Priority": -1,
      "EventId": 1,
      "Severity": 8,
      "LoggedSeverity": "Information",
      "Title": "",
      "TimeStamp": "2013-11-07T20:33:38.6537773Z",
      "MachineName": "Acme01",
      "AppDomainName": "Acme.TestDriver.vshost.exe",
      "ProcessId": "10348",
      "ProcessName": "C:\\dev\\Acme.TestDriver\\bin\\Debug\\Acme.TestDriver.vshost.exe",
      "ManagedThreadName": null,
      "Win32ThreadId": "11204",
      "ExtendedProperties": {},
      "TimeStampString": "11/7/2013 8:33:38 PM",
      "ActivityId": "00000000-0000-0000-0000-000000000000",
      "RelatedActivityId": null,
      "ErrorMessages": null,
      "ActivityIdString": "00000000-0000-0000-0000-000000000000",
      "CategoriesStrings": [
        "General"
      ]
    }
,
    {
      "Message": "Log entry with a single category.",
      "Categories": [
        "General"
      ],
      "Priority": -1,
      "EventId": 1,
      "Severity": 8,
      "LoggedSeverity": "Information",
      "Title": "",
      "TimeStamp": "2013-11-07T20:33:38.6537773Z",
      "MachineName": "Acme01",
      "AppDomainName": "Acme.TestDriver.vshost.exe",
      "ProcessId": "10348",
      "ProcessName": "C:\\dev\\Acme.TestDriver\\bin\\Debug\\Acme.TestDriver.vshost.exe",
      "ManagedThreadName": null,
      "Win32ThreadId": "11204",
      "ExtendedProperties": {},
      "TimeStampString": "11/7/2013 8:33:38 PM",
      "ActivityId": "00000000-0000-0000-0000-000000000000",
      "RelatedActivityId": null,
      "ErrorMessages": null,
      "ActivityIdString": "00000000-0000-0000-0000-000000000000",
      "CategoriesStrings": [
        "General"
      ]
    }
]
4

2 に答える 2

0

私も出力を修正しようとしましたが、最終的にあきらめて消費側ですべてを処理しました。以下は、 https://stackoverflow.com/a/26610684/4904200のコードに基づいて、イベントをスパムして消費しようとする私のサンプル プログラムです。

キーポイント:

  • RollingFlatFileTraceListenerヘッダーとフッターは "" に設定されています
  • ログを消費するとき、ストリームが設定されてFileShare.ReadWriteいるため、書き込みに干渉しません
  • JsonReader.SupportMultipleContent = true複数のオブジェクトが別々の行にある限り、ファイル内の複数のオブジェクトを処理できるようにするものです。

これは、Microsoft Enterprise Logging Library v6 と Newtonsoft JSON v8 を使用します。

static void Main(string[] args) {
  Thread producer = new Thread(new ThreadStart(Produce));
  Thread consumer = new Thread(new ThreadStart(Consume));
  producer.Start();
  consumer.Start();
  while (true)
    Thread.Sleep(1000);
}

public static void Produce() {
  RollingFlatFileTraceListener listener = new RollingFlatFileTraceListener(
    fileName: "jsontest",
    formatter: new JsonLogFormatter(),
    header: "",
    footer: "",
    rollSizeKB: 1024);
  LoggingConfiguration configuration = new LoggingConfiguration();
  configuration.Filters.Add(new CategoryFilter("Category Filter", new string[] { "none" }, CategoryFilterMode.AllowAllExceptDenied));
  configuration.AddLogSource("Any", SourceLevels.All, true, listener);
  LogWriter writer = new LogWriter(configuration);

  while (true)
    writer.Write(DateTime.Now);
}

public static void Consume() {
  while (true) {
    try {
      using (var fileStream = File.Open("jsontest", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
        LogEntry latestEntry = ReadJson<LogEntry>(fileStream).OrderBy(x => x.TimeStamp).FirstOrDefault();
        if (latestEntry == null)
          continue;
        Console.WriteLine("Consume\t" + latestEntry.Message);
      }
    } catch (FileNotFoundException) {
      Console.WriteLine("File Not Found");
    } catch (IOException) {
      Console.WriteLine("File Is Probably Busy");
    }
  }
}


public static IEnumerable<TResult> ReadJson<TResult>(Stream stream) {
  var serializer = new JsonSerializer();
  using (var reader = new StreamReader(stream))
  using (var jsonReader = new JsonTextReader(reader)) {
    jsonReader.SupportMultipleContent = true;
    while (jsonReader.Read()) {
      yield return serializer.Deserialize<TResult>(jsonReader);
    }
  }
}
于 2016-01-24T15:08:26.293 に答える
0

デフォルトでは、トレース リスナーはファイルに追加するだけです。ファイルがロックされているため、ファイルを開いて変更することはできません。整形式のドキュメントを作成する場合は、開始タグを作成し、終了タグが常にファイルの最後にあることを確認するカスタム トレース リスナーを作成する必要があります。

于 2013-11-12T01:45:02.910 に答える