Библиотека предприятия RollingFlatFileTraceListenerData Формат файла JsonLogFormatter
Я ищу способ заставить RollingFlatFileTraceListenerData создать действительный документ JSON при использовании JsonLogFormatter. Как и анализатор 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"
]
}
]
2 ответа
Я тоже пытался исправить вывод, но в конце концов сдался и обработал все на стороне потребления. Ниже приведен пример моей программы, которая спамит события, а затем пытается использовать их на основе кода с /questions/14551621/kak-pravilno-ispolzovat-jsonnet-dlya-analiza-potoka-obektov-json/14551624#14551624
Ключевые моменты:
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);
}
}
}
Из коробки слушатели следа просто добавляют к файлу. Вы не сможете открыть файл и изменить его, потому что файл заблокирован. Если вы хотите создать правильно сформированный документ, то вам нужно будет создать собственный прослушиватель трассировки, который создает начальный тег и гарантирует, что закрывающий тег всегда будет в нижней части файла.