我正在寻找方法使RollingFlatFileTraceListenerData在使用JsonLogFormatter时创建一个有效的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"
]
}
]
答案 0 :(得分:0)
开箱即用的跟踪侦听器只是附加到文件中。您将无法打开该文件并对其进行修改,因为该文件已被锁定。如果要创建格式良好的文档,则必须创建自定义跟踪侦听器,以创建开始标记并确保结束标记始终位于文件的底部。
答案 1 :(得分: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);
}
}
}