diff --git a/Analogy.LogViewer.Serilog.UnitTests/Analogy.LogViewer.Serilog.UnitTests.csproj b/Analogy.LogViewer.Serilog.UnitTests/Analogy.LogViewer.Serilog.UnitTests.csproj index 9e3c692..eb4c5d2 100644 --- a/Analogy.LogViewer.Serilog.UnitTests/Analogy.LogViewer.Serilog.UnitTests.csproj +++ b/Analogy.LogViewer.Serilog.UnitTests/Analogy.LogViewer.Serilog.UnitTests.csproj @@ -16,10 +16,6 @@ - - - - @@ -28,22 +24,25 @@ Always - + + Always + + Always - + Always - + Always - + Always - + Always - + Always diff --git a/Analogy.LogViewer.Serilog.UnitTests/Analogy.Logserver.20200913.log b/Analogy.LogViewer.Serilog.UnitTests/Analogy.Logserver.20200913.log deleted file mode 100644 index 4bb033e..0000000 --- a/Analogy.LogViewer.Serilog.UnitTests/Analogy.Logserver.20200913.log +++ /dev/null @@ -1,125 +0,0 @@ -{"Timestamp":"2020-09-13T17:53:07.1995663+03:00","Level":"Information","MessageTemplate":"Starting Analogy Log Server","Properties":{"MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":1}} -{"Timestamp":"2020-09-13T17:53:07.6402546+03:00","Level":"Information","MessageTemplate":"Now listening on: {address}","Properties":{"address":"http://[::]:6000","SourceContext":"Microsoft.Hosting.Lifetime","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":9}} -{"Timestamp":"2020-09-13T17:53:07.6440926+03:00","Level":"Information","MessageTemplate":"Application started. Hosting environment: {envName}; Content root path: {contentRoot}","Properties":{"envName":"Production","contentRoot":"C:\\Kalpa\\Utils\\Analogy.LogServer\\","SourceContext":"Microsoft.Hosting.Lifetime","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":9}} -{"Timestamp":"2020-09-13T17:53:38.6748466+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH4:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbfd-402ce09a1cba64d4.","TraceId":"1ba1bbfd-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":14}} -{"Timestamp":"2020-09-13T17:53:38.7803080+03:00","Level":"Information","MessageTemplate":"User profile is available. Using 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Local\\ASP.NET\\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:38.9105668+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH5:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbfe-402ce09a1cba64d4.","TraceId":"1ba1bbfe-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":9}} -{"Timestamp":"2020-09-13T17:53:38.9170541+03:00","Level":"Information","MessageTemplate":"Now listening on: http://[::]:5050","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:38.9462057+03:00","Level":"Information","MessageTemplate":"Application started. Hosting environment: Production; Content root path: C:\\Kalpa\\DBStoreService\\","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:39.3171088+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH6:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbff-402ce09a1cba64d4.","TraceId":"1ba1bbff-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T17:53:39.3403059+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:53:39 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:39.3417190+03:00","Level":"Warning","MessageTemplate":"ElectrodeAcqServiceWorker worker is stopping at: 09/13/2020 17:53:39 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:39.5306026+03:00","Level":"Information","MessageTemplate":"User profile is available. Using 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Local\\ASP.NET\\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:39.6818356+03:00","Level":"Information","MessageTemplate":"Now listening on: http://[::]:5060","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:39.6820378+03:00","Level":"Information","MessageTemplate":"Now listening on: http://localhost:5060","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:39.6977864+03:00","Level":"Information","MessageTemplate":"Application started. Hosting environment: Production; Content root path: C:\\Kalpa\\EcgAcquisitionService\\","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:39.9599219+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH7:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc00-402ce09a1cba64d4.","TraceId":"1ba1bc00-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T17:53:40.0180022+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH5:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbfe-402ce09a1cba64d4.","TraceId":"1ba1bbfe-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":14}} -{"Timestamp":"2020-09-13T17:53:40.0186052+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH5:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbfe-402ce09a1cba64d4.","TraceId":"1ba1bbfe-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":14}} -{"Timestamp":"2020-09-13T17:53:40.0359596+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":1126.6294179405431,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HH5:00000001","SpanId":"|1ba1bbfe-402ce09a1cba64d4.","TraceId":"1ba1bbfe-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":14},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"1126.6294"}]}} -{"Timestamp":"2020-09-13T17:53:40.1773019+03:00","Level":"Information","MessageTemplate":"Application is shutting down...","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:40.1828188+03:00","Level":"Information","MessageTemplate":"User profile is available. Using 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Local\\ASP.NET\\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:40.5890268+03:00","Level":"Information","MessageTemplate":"Now listening on: http://[::]:5020","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:40.6045426+03:00","Level":"Information","MessageTemplate":"Application started. Hosting environment: Production; Content root path: C:\\Kalpa\\procedureManagerService\\","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:40.6353745+03:00","Level":"Warning","MessageTemplate":"ServicesHealthCheckMonitorWorker worker is stopping at: 09/13/2020 17:53:40 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:40.6493477+03:00","Level":"Information","MessageTemplate":"Cancellation requested","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:40.6654067+03:00","Level":"Information","MessageTemplate":"Cancellation requested","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:40.6657719+03:00","Level":"Information","MessageTemplate":"Cancellation requested","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:40.7346441+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH7:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc00-402ce09a1cba64d4.","TraceId":"1ba1bc00-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T17:53:40.7350281+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH7:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc00-402ce09a1cba64d4.","TraceId":"1ba1bc00-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T17:53:40.7361367+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":776.784335862911,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HH7:00000001","SpanId":"|1ba1bc00-402ce09a1cba64d4.","TraceId":"1ba1bc00-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"776.7843"}]}} -{"Timestamp":"2020-09-13T17:53:53.3037835+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH8:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc01-402ce09a1cba64d4.","TraceId":"1ba1bc01-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":14}} -{"Timestamp":"2020-09-13T17:53:53.7102845+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:53:53 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:54.5109192+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH9:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc02-402ce09a1cba64d4.","TraceId":"1ba1bc02-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":17}} -{"Timestamp":"2020-09-13T17:53:54.7169480+03:00","Level":"Information","MessageTemplate":"User profile is available. Using 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Local\\ASP.NET\\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:55.1360594+03:00","Level":"Information","MessageTemplate":"Now listening on: http://[::]:5020","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:53:55.1518416+03:00","Level":"Information","MessageTemplate":"Application started. Hosting environment: Production; Content root path: C:\\Kalpa\\procedureManagerService\\","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:00.2461881+03:00","Level":"Information","MessageTemplate":"change in HW check status: connected: True","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:00.8877165+03:00","Level":"Information","MessageTemplate":"PAQConnectionOk:Connection to PAQ restored","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:00.9634074+03:00","Level":"Information","MessageTemplate":"PAQHardwareConnectionOk:Connection to PAQ restored","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:00.9959271+03:00","Level":"Information","MessageTemplate":"System Event: SystemEventType: PAQConnectionOk, EventData: Connection to PAQ restored, IsError: False. TimeStamp: 1600008839882","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:00.9966118+03:00","Level":"Information","MessageTemplate":"System Event: SystemEventType: PAQHardwareConnectionOk, EventData: Connection to PAQ restored, IsError: False. TimeStamp: 1600008840236","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:31.7069384+03:00","Level":"Information","MessageTemplate":"Adding client with message: {message}","Properties":{"message":"client","SourceContext":"Analogy.LogServer.GRPCLogConsumer","RequestId":"0HM2NUJ664HHA:00000001","RequestPath":"/greet.Analogy/SubscribeForConsumeMessages","SpanId":"|1ba1bc03-402ce09a1cba64d4.","TraceId":"1ba1bc03-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T17:54:39.7314852+03:00","Level":"Information","MessageTemplate":"Application is shutting down...","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:39.7621453+03:00","Level":"Warning","MessageTemplate":"ECGAcquisitionService worker is stopping at: 09/13/2020 17:54:39 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:39.8051848+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH6:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbff-402ce09a1cba64d4.","TraceId":"1ba1bbff-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":22}} -{"Timestamp":"2020-09-13T17:54:39.8058126+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH6:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbff-402ce09a1cba64d4.","TraceId":"1ba1bbff-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":22}} -{"Timestamp":"2020-09-13T17:54:39.8073368+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":60489.43756989482,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HH6:00000001","SpanId":"|1ba1bbff-402ce09a1cba64d4.","TraceId":"1ba1bbff-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":22},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"60489.4376"}]}} -{"Timestamp":"2020-09-13T17:54:41.9805161+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHB:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc04-402ce09a1cba64d4.","TraceId":"1ba1bc04-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":10}} -{"Timestamp":"2020-09-13T17:54:42.2038555+03:00","Level":"Information","MessageTemplate":"User profile is available. Using 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Local\\ASP.NET\\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:42.3560105+03:00","Level":"Information","MessageTemplate":"Now listening on: http://[::]:5060","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:42.3717003+03:00","Level":"Information","MessageTemplate":"Now listening on: http://localhost:5060","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:42.3867502+03:00","Level":"Information","MessageTemplate":"Application started. Hosting environment: Production; Content root path: C:\\Kalpa\\EcgAcquisitionService\\","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:54:53.6707194+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:54:53 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:55:53.7014220+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:55:53 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:56:53.7188489+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:56:53 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:17.9856789+03:00","Level":"Warning","MessageTemplate":"ElectrodeAcqServiceWorker worker is stopping at: 09/13/2020 17:57:17 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:18.0436499+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH8:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc01-402ce09a1cba64d4.","TraceId":"1ba1bc01-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":13}} -{"Timestamp":"2020-09-13T17:57:18.0440019+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH8:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc01-402ce09a1cba64d4.","TraceId":"1ba1bc01-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":13}} -{"Timestamp":"2020-09-13T17:57:18.0448841+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":204736.3889263087,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HH8:00000001","SpanId":"|1ba1bc01-402ce09a1cba64d4.","TraceId":"1ba1bc01-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":13},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"204736.3889"}]}} -{"Timestamp":"2020-09-13T17:57:20.0952845+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHC:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc05-402ce09a1cba64d4.","TraceId":"1ba1bc05-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T17:57:20.4887340+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:57:20 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:20.4901740+03:00","Level":"Warning","MessageTemplate":"ElectrodeAcqServiceWorker worker is stopping at: 09/13/2020 17:57:20 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:20.5593288+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHC:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc05-402ce09a1cba64d4.","TraceId":"1ba1bc05-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T17:57:20.5595636+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHC:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc05-402ce09a1cba64d4.","TraceId":"1ba1bc05-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T17:57:20.5601050+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":465.36574100802494,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HHC:00000001","SpanId":"|1ba1bc05-402ce09a1cba64d4.","TraceId":"1ba1bc05-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"465.3657"}]}} -{"Timestamp":"2020-09-13T17:57:22.2388626+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHD:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc06-402ce09a1cba64d4.","TraceId":"1ba1bc06-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":21}} -{"Timestamp":"2020-09-13T17:57:22.5019339+03:00","Level":"Error","MessageTemplate":"HW check failed for http://127.0.0.1:5000/ElectrodeAcqAPI/IsHardwareAlive. Reason: No connection could be made because the target machine actively refused it.","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:22.6725395+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:57:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:23.3442279+03:00","Level":"Information","MessageTemplate":"Application is shutting down...","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:23.3587878+03:00","Level":"Warning","MessageTemplate":"ServicesHealthCheckMonitorWorker worker is stopping at: 09/13/2020 17:57:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:23.3747952+03:00","Level":"Information","MessageTemplate":"Cancellation requested","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:23.3750712+03:00","Level":"Information","MessageTemplate":"Cancellation requested","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:23.3909277+03:00","Level":"Information","MessageTemplate":"Cancellation requested","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:25.1144051+03:00","Level":"Information","MessageTemplate":"Client subscribe for sending messages","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHE:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc07-402ce09a1cba64d4.","TraceId":"1ba1bc07-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":20}} -{"Timestamp":"2020-09-13T17:57:25.3184487+03:00","Level":"Information","MessageTemplate":"User profile is available. Using 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Local\\ASP.NET\\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:25.7346764+03:00","Level":"Information","MessageTemplate":"Now listening on: http://[::]:5020","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:25.7491362+03:00","Level":"Information","MessageTemplate":"Application started. Hosting environment: Production; Content root path: C:\\Kalpa\\procedureManagerService\\","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:30.8440117+03:00","Level":"Information","MessageTemplate":"change in HW check status: connected: True","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:31.4397414+03:00","Level":"Information","MessageTemplate":"System Event: SystemEventType: PAQConnectionOk, EventData: Connection to PAQ restored, IsError: False. TimeStamp: 1600009050481","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:31.4400412+03:00","Level":"Information","MessageTemplate":"System Event: SystemEventType: PAQHardwareConnectionOk, EventData: Connection to PAQ restored, IsError: False. TimeStamp: 1600009050840","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:31.9591055+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH9:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc02-402ce09a1cba64d4.","TraceId":"1ba1bc02-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":20}} -{"Timestamp":"2020-09-13T17:57:31.9593634+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH9:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc02-402ce09a1cba64d4.","TraceId":"1ba1bc02-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":20}} -{"Timestamp":"2020-09-13T17:57:31.9598813+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":217444.03517887727,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HH9:00000001","SpanId":"|1ba1bc02-402ce09a1cba64d4.","TraceId":"1ba1bc02-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":20},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"217444.0352"}]}} -{"Timestamp":"2020-09-13T17:57:40.0632237+03:00","Level":"Information","MessageTemplate":"PAQConnectionOk:Connection to PAQ restored","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:57:40.1713693+03:00","Level":"Information","MessageTemplate":"PAQHardwareConnectionOk:Connection to PAQ restored","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:58:22.6427428+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:58:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T17:59:22.6762891+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 17:59:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:00:22.7107079+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:00:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:01:22.7426555+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:01:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:02:22.7595771+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:02:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:03:22.7775015+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:03:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:04:22.8109108+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:04:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:05:22.8442910+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:05:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:06:22.8607775+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:06:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:07:22.8937813+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:07:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:08:22.9107554+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:08:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:09:22.9266093+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:09:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:10:22.9607018+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:10:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:11:22.9931798+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:11:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:12:23.0110080+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:12:22 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:13:23.0439273+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:13:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:14:23.0624190+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:14:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:15:23.0937823+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:15:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:16:23.1105840+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:16:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:17:23.1436375+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:17:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:18:23.1773589+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:18:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:19:23.2101612+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:19:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:20:23.2263506+03:00","Level":"Information","MessageTemplate":"ElectrodeAcqServiceWorker worker running at: 09/13/2020 18:20:23 +03:00","Properties":{"SourceContext":"Analogy.LogServer.MessagesContainer","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":6}} -{"Timestamp":"2020-09-13T18:21:22.2446789+03:00","Level":"Information","MessageTemplate":"Application is shutting down...","Properties":{"SourceContext":"Microsoft.Hosting.Lifetime","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":21}} -{"Timestamp":"2020-09-13T18:21:22.2518676+03:00","Level":"Information","MessageTemplate":"Cancellation requested","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":18}} -{"Timestamp":"2020-09-13T18:21:23.2694087+03:00","Level":"Error","MessageTemplate":"Error receiving messages: System.InvalidOperationException: The collection has been marked as complete with regards to additions.\r\n at System.Collections.Concurrent.BlockingCollection`1.TryAddWithNoTimeValidation(T item, Int32 millisecondsTimeout, CancellationToken cancellationToken)\r\n at System.Collections.Concurrent.BlockingCollection`1.Add(T item)\r\n at Analogy.LogServer.MessagesContainer.AddMessage(AnalogyLogMessage m) in D:\\Git\\Analogy.LogViewer.gRPC\\Analogy.LogServer\\MessagesContainer.cs:line 45\r\n at Analogy.LogServer.Services.GreeterService.HandleClientActions(IAsyncStreamReader`1 requestStream, CancellationToken token) in D:\\Git\\Analogy.LogViewer.gRPC\\Analogy.LogServer\\Services\\GreeterService.cs:line 84","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHD:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc06-402ce09a1cba64d4.","TraceId":"1ba1bc06-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":71}} -{"Timestamp":"2020-09-13T18:21:27.2478596+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH4:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbfd-402ce09a1cba64d4.","TraceId":"1ba1bbfd-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":71}} -{"Timestamp":"2020-09-13T18:21:27.2478549+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHE:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc07-402ce09a1cba64d4.","TraceId":"1ba1bc07-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T18:21:27.2480268+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HH4:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bbfd-402ce09a1cba64d4.","TraceId":"1ba1bbfd-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":71}} -{"Timestamp":"2020-09-13T18:21:27.2479716+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHB:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc04-402ce09a1cba64d4.","TraceId":"1ba1bc04-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":23}} -{"Timestamp":"2020-09-13T18:21:27.2481162+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHE:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc07-402ce09a1cba64d4.","TraceId":"1ba1bc07-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15}} -{"Timestamp":"2020-09-13T18:21:27.2481328+03:00","Level":"Error","MessageTemplate":"Error: The operation was canceled.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHD:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc06-402ce09a1cba64d4.","TraceId":"1ba1bc06-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":76}} -{"Timestamp":"2020-09-13T18:21:27.2482628+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHB:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc04-402ce09a1cba64d4.","TraceId":"1ba1bc04-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":23}} -{"Timestamp":"2020-09-13T18:21:27.2483406+03:00","Level":"Information","MessageTemplate":"Subscription finished.","Properties":{"SourceContext":"Analogy.LogServer.Services.GreeterService","RequestId":"0HM2NUJ664HHD:00000001","RequestPath":"/greet.Analogy/SubscribeForSendMessages","SpanId":"|1ba1bc06-402ce09a1cba64d4.","TraceId":"1ba1bc06-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":76}} -{"Timestamp":"2020-09-13T18:21:27.2487910+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":1668583.8953785494,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HH4:00000001","SpanId":"|1ba1bbfd-402ce09a1cba64d4.","TraceId":"1ba1bbfd-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":71},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"1668583.8954"}]}} -{"Timestamp":"2020-09-13T18:21:27.2487931+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":1442093.7996480402,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HHE:00000001","SpanId":"|1ba1bc07-402ce09a1cba64d4.","TraceId":"1ba1bc07-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":15},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"1442093.7996"}]}} -{"Timestamp":"2020-09-13T18:21:27.2487931+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":1605223.4427487934,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HHB:00000001","SpanId":"|1ba1bc04-402ce09a1cba64d4.","TraceId":"1ba1bc04-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":23},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"1605223.4427"}]}} -{"Timestamp":"2020-09-13T18:21:27.2487935+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForSendMessages","StatusCode":200,"Elapsed":1444969.2674488472,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HHD:00000001","SpanId":"|1ba1bc06-402ce09a1cba64d4.","TraceId":"1ba1bc06-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":76},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"1444969.2674"}]}} -{"Timestamp":"2020-09-13T18:21:27.2504196+03:00","Level":"Information","MessageTemplate":"HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms","Properties":{"RequestMethod":"POST","RequestPath":"/greet.Analogy/SubscribeForConsumeMessages","StatusCode":200,"Elapsed":1615524.7498754456,"SourceContext":"Serilog.AspNetCore.RequestLoggingMiddleware","RequestId":"0HM2NUJ664HHA:00000001","SpanId":"|1ba1bc03-402ce09a1cba64d4.","TraceId":"1ba1bc03-402ce09a1cba64d4","ParentId":"","MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":70},"Renderings":{"Elapsed":[{"Format":"0.0000","Rendering":"1615524.7499"}]}} -{"Timestamp":"2020-09-13T18:21:27.2564586+03:00","Level":"Fatal","MessageTemplate":"Error during application","Exception":"System.OperationCanceledException: The operation was canceled.\r\n at System.Threading.CancellationToken.ThrowOperationCanceledException()\r\n at Microsoft.Extensions.Hosting.Internal.Host.StopAsync(CancellationToken cancellationToken)\r\n at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.WaitForShutdownAsync(IHost host, CancellationToken token)\r\n at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)\r\n at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)\r\n at Analogy.LogServer.Program.Main() in D:\\Git\\Analogy.LogViewer.gRPC\\Analogy.LogServer\\Program.cs:line 31","Properties":{"MachineName":"DT-KAMA-LAB1","ProcessId":33100,"ThreadId":70}} diff --git a/Analogy.LogViewer.Serilog.UnitTests/ClefTests.cs b/Analogy.LogViewer.Serilog.UnitTests/ClefTests.cs deleted file mode 100644 index 7644654..0000000 --- a/Analogy.LogViewer.Serilog.UnitTests/ClefTests.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.IO; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Analogy.LogViewer.Serilog.UnitTests -{ - [TestClass] - public class ClefTests - { - private string folder { get; } = Environment.CurrentDirectory; - [TestMethod] - public async Task ClefParserTest() - { - ClefParser p = new ClefParser(); - CancellationTokenSource cts = new CancellationTokenSource(); - string fileName = Path.Combine(folder, "log files", "ClefExample1.clef"); - MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); - var messages = await p.Process(fileName, cts.Token, forTesting); - Assert.IsTrue(messages.Count() == 4); - } - - // Test reading the (optional) source context - [TestMethod] - public async Task SourceContextTest() - { - ClefParser p = new ClefParser(); - CancellationTokenSource cts = new CancellationTokenSource(); - string fileName = Path.Combine(folder, "log files", "SourceContextTest.clef"); - MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); - - var messages = (await p.Process(fileName, cts.Token, forTesting)).ToList(); - - Assert.AreEqual(2, messages.Count()); - - // The first event doesn't have a source context - var firstEvent = messages.ElementAt(0); - Assert.AreEqual("Hello, Serilog!", firstEvent.Text); - Assert.AreEqual(string.Empty, firstEvent.Source); - Assert.AreEqual(1, firstEvent.ThreadId); - Assert.IsNotNull(firstEvent.Module); - Assert.IsNotNull(firstEvent.FileName); - Assert.IsNotNull(firstEvent.Category); - Assert.IsNotNull(firstEvent.User); - Assert.IsNotNull(firstEvent.MethodName); - // The second event should have a source context - var secondEvent = messages.ElementAt(1); - Assert.AreEqual("Contextual Log", secondEvent.Text); - Assert.AreEqual("SerilogLogging.Program", secondEvent.Source); - Assert.AreEqual(1, secondEvent.ThreadId); - Assert.IsNotNull(secondEvent.Module); - Assert.IsNotNull(secondEvent.FileName); - Assert.IsNotNull(secondEvent.Category); - Assert.IsNotNull(secondEvent.User); - Assert.IsNotNull(secondEvent.MethodName); - } - } -} \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog.UnitTests/CompactJsonFormatTests.cs b/Analogy.LogViewer.Serilog.UnitTests/CompactJsonFormatTests.cs new file mode 100644 index 0000000..a9da246 --- /dev/null +++ b/Analogy.LogViewer.Serilog.UnitTests/CompactJsonFormatTests.cs @@ -0,0 +1,126 @@ +using Analogy.LogViewer.Serilog.DataTypes; +using Analogy.LogViewer.Serilog.IAnalogy; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Analogy.LogViewer.Serilog.UnitTests +{ + [TestClass] + public class CompactJsonFormatTests + { + private string Folder { get; } = Environment.CurrentDirectory; + [TestMethod] + [DataRow("CompactJsonFormat.clef",4, "2016-10-12T04:46:58.0554314Z")] + [DataRow("CompactJsonFormatSourceContextTest.clef",2, "2020-06-18T18:03:19.2248275Z")] + [DataRow("CompactJsonFormatTestColumns.clef",4, "2020-06-26T14:21:34.7233612Z")] + [DataRow("CompactJsonFormat.gz",4, "2016-10-12T04:46:58.0554314Z")] + public async Task OfflineProviderParserTimestampTest(string fileName,int numberOfMessages,string datetimeToParse) + { + OfflineDataProvider parser = new OfflineDataProvider(); + CancellationTokenSource cts = new CancellationTokenSource(); + string file = Path.Combine(Folder, "log files", fileName); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + var messages = (await parser.Process(file, cts.Token, forTesting)).ToList(); + DateTimeOffset dto = DateTimeOffset.Parse(datetimeToParse); + Assert.IsTrue(messages.Count == numberOfMessages); + Assert.IsTrue(messages[0].Date == dto.DateTime); + } + + + [TestMethod] + [DataRow("CompactJsonFormat.clef")] + [DataRow("CompactJsonFormatSourceContextTest.clef")] + [DataRow("CompactJsonFormatTestColumns.clef")] + [DataRow("CompactJsonFormat.gz")] + public void CompactJsonFormatTestAutomaticDetection(string fileName) + { + string file = Path.Combine(Folder, "log files", fileName); + var type = OfflineDataProvider.TryDetectFormat(file); + Assert.IsTrue(type == FileFormat.CompactJsonFormatPerLine); + + } + + [TestMethod] + public async Task CompactJsonFormatParserTest() + { + CompactJsonFormatParser parser = new CompactJsonFormatParser(); + CancellationTokenSource cts = new CancellationTokenSource(); + string fileName = Path.Combine(Folder, "log files", "CompactJsonFormat.clef"); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + var messages = (await parser.Process(fileName, cts.Token, forTesting)).ToList(); + Assert.IsTrue(messages.Count == 4); + Assert.IsTrue(messages[0].Text == "Hello, { Name: \"nblumhardt\", Id: 101 }"); + } + + // Test reading the (optional) source context + [TestMethod] + public async Task CompactJsonFormatSourceContextTest() + { + CompactJsonFormatParser parser = new CompactJsonFormatParser(); + CancellationTokenSource cts = new CancellationTokenSource(); + string fileName = Path.Combine(Folder, "log files", "CompactJsonFormatSourceContextTest.clef"); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + + var messages = (await parser.Process(fileName, cts.Token, forTesting)).ToList(); + + Assert.AreEqual(2, messages.Count()); + + // The first event doesn't have a source context + var firstEvent = messages.ElementAt(0); + Assert.AreEqual("Hello, Serilog!", firstEvent.Text); + Assert.AreEqual(string.Empty, firstEvent.Source); + Assert.AreEqual(1, firstEvent.ThreadId); + Assert.IsNotNull(firstEvent.Module); + Assert.IsNotNull(firstEvent.FileName); + Assert.IsNotNull(firstEvent.Category); + Assert.IsNotNull(firstEvent.User); + Assert.IsNotNull(firstEvent.MethodName); + // The second event should have a source context + var secondEvent = messages.ElementAt(1); + Assert.AreEqual("Contextual Log", secondEvent.Text); + Assert.AreEqual("SerilogLogging.Program", secondEvent.Source); + Assert.AreEqual(1, secondEvent.ThreadId); + Assert.IsNotNull(secondEvent.Module); + Assert.IsNotNull(secondEvent.FileName); + Assert.IsNotNull(secondEvent.Category); + Assert.IsNotNull(secondEvent.User); + Assert.IsNotNull(secondEvent.MethodName); + } + + + [TestMethod] + public async Task CompactJsonFormatTestColumns() + { + CompactJsonFormatParser parser = new CompactJsonFormatParser(); + CancellationTokenSource cts = new CancellationTokenSource(); + string fileName = Path.Combine(Folder, "log files", "CompactJsonFormatTestColumns.clef"); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + var messages = (await parser.Process(fileName, cts.Token, forTesting)).ToList(); + Assert.AreEqual(4, messages.Count()); + // The first event doesn't have a source context + Assert.IsTrue(messages[0].MachineName == "Test"); + Assert.IsTrue(messages[1].AdditionalInformation["CustomProperty"] == "\"Custom Value\""); + + } + + [TestMethod] + public async Task CompactJsonFormatTestGZFile() + { + CompactJsonFormatParser parser = new CompactJsonFormatParser(); + CancellationTokenSource cts = new CancellationTokenSource(); + string fileName = Path.Combine(Folder, "log files", "CompactJsonFormat.gz"); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + var messages = (await parser.Process(fileName, cts.Token, forTesting)).ToList(); + Assert.AreEqual(4, messages.Count()); + // The first event doesn't have a source context + Assert.IsTrue(messages[2].AdditionalInformation["Tags"] == "[\"test\", \"orange\"]"); + + } + + + } +} \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog.UnitTests/JsonFormatTests.cs b/Analogy.LogViewer.Serilog.UnitTests/JsonFormatTests.cs new file mode 100644 index 0000000..1d4428d --- /dev/null +++ b/Analogy.LogViewer.Serilog.UnitTests/JsonFormatTests.cs @@ -0,0 +1,85 @@ +using Analogy.LogViewer.Serilog.DataTypes; +using Analogy.LogViewer.Serilog.IAnalogy; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Analogy.LogViewer.Serilog.UnitTests +{ + [TestClass] + public class JsonFormatTests + { + private string Folder { get; } = Environment.CurrentDirectory; + + [TestMethod] + public async Task CompactJsonFormatFullFileTest() + { + JsonFileParser parser = new JsonFileParser(new CompactJsonFormatMessageFields()); + CancellationTokenSource cts = new CancellationTokenSource(); + string fileName = Path.Combine(Folder, "log files", "JsonFileCompactFormat.clef"); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + var messages = (await parser.Process(fileName, cts.Token, forTesting)).ToList(); + Assert.IsTrue(messages.Count == 2); + Assert.IsTrue(messages[0].MachineName == "MY-MACHINE"); + Assert.IsTrue(messages[1].Text.StartsWith("An unknown error occurred")); + Assert.IsTrue((messages[1].Module == "My process")); + + } + + [TestMethod] + public async Task JsonFilePerLineTest() + { + var p = new JsonFormatterParser(new JsonFormatMessageFields()); + CancellationTokenSource cts = new CancellationTokenSource(); + string fileName = Path.Combine(Folder, "log files", "JsonFormatPerLine.clef"); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + var messages = (await p.Process(fileName, cts.Token, forTesting)).ToList(); + Assert.IsTrue(messages.Count == 2); + //Assert.IsTrue(messages[0].Text == "Hello, { Name: \"nblumhardt\", Tags: [1, 2, 3] }, 0000007b at 06/07/2016 06:44:57","got"+ messages[0].Text); + Assert.IsTrue(messages[0].User == "{ Name: \"nblumhardt\", Tags: [1, 2, 3] }"); + } + + [TestMethod] + public async Task JsonFilePerFileTest() + { + JsonFileParser parser = new JsonFileParser(new JsonFormatMessageFields()); + CancellationTokenSource cts = new CancellationTokenSource(); + string fileName = Path.Combine(Folder, "log files", "JsonFormatPerFile.clef"); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + var messages = (await parser.Process(fileName, cts.Token, forTesting)).ToList(); + Assert.IsTrue(messages.Count == 2); + //Assert.IsTrue(messages[0].Text == "Hello, { Name: \"nblumhardt\", Tags: [1, 2, 3] }, 0000007b at 06/07/2016 06:44:57","got"+ messages[0].Text); + Assert.IsTrue(messages[0].User == "{ Name: \"nblumhardt\", Tags: [1, 2, 3] }"); + } + + [TestMethod] + [DataRow("JsonFileCompactFormat.clef", FileFormat.CompactJsonFormatPerFile)] + [DataRow("JsonFormatPerLine.clef", FileFormat.JsonFormatPerLine)] + public void CompactJsonFormatTestAutomaticDetection(string fileName, FileFormat format) + { + string file = Path.Combine(Folder, "log files", fileName); + var type = OfflineDataProvider.TryDetectFormat(file); + Assert.IsTrue(type == format); + } + + [TestMethod] + public async Task JsonFilePerLineDateTimeWithOffsetTest() + { + var p = new JsonFormatterParser(new JsonFormatMessageFields()); + CancellationTokenSource cts = new CancellationTokenSource(); + string fileName = Path.Combine(Folder, "log files", "JsonFormatPerLine.clef"); + MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); + var messages = (await p.Process(fileName, cts.Token, forTesting)).ToList(); + Assert.IsTrue(messages.Count == 2); + + Assert.IsTrue(messages[0].User == "{ Name: \"nblumhardt\", Tags: [1, 2, 3] }"); + + DateTimeOffset dto = DateTimeOffset.Parse("2020-06-07T13:44:57.8532799+10:00"); + //Assert.IsTrue(messages[0].Date == dto.DateTime); + //Assert.IsTrue(messages[0].Text == "Hello, { Name: \"nblumhardt\", Tags: [1, 2, 3] }, 0000007b at 06/07/2016 06:44:57", "got" + messages[0].Text); + } + } +} diff --git a/Analogy.LogViewer.Serilog.UnitTests/JsonParserTests.cs b/Analogy.LogViewer.Serilog.UnitTests/JsonParserTests.cs deleted file mode 100644 index 852f29b..0000000 --- a/Analogy.LogViewer.Serilog.UnitTests/JsonParserTests.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.IO; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Analogy.LogViewer.Serilog.UnitTests -{ - [TestClass] - public class JsonParserTests - { - private string folder { get; } = Environment.CurrentDirectory; - - [TestMethod] - public async Task ClefJsonParserTest() - { - var p = new ClefParser(); - CancellationTokenSource cts = new CancellationTokenSource(); - string fileName = Path.Combine(folder, "log files", "SourceContextTest.clef"); - MessageHandlerForTesting forTesting = new MessageHandlerForTesting(); - var messages = await p.Process(fileName, cts.Token, forTesting); - Assert.IsTrue(messages.Count() == 2); - } - } -} diff --git a/Analogy.LogViewer.Serilog.UnitTests/log files/ClefExample1.clef b/Analogy.LogViewer.Serilog.UnitTests/log files/CompactJsonFormat.clef similarity index 100% rename from Analogy.LogViewer.Serilog.UnitTests/log files/ClefExample1.clef rename to Analogy.LogViewer.Serilog.UnitTests/log files/CompactJsonFormat.clef diff --git a/Analogy.LogViewer.Serilog.UnitTests/log files/ClefExample1.clef.gz b/Analogy.LogViewer.Serilog.UnitTests/log files/CompactJsonFormat.gz similarity index 100% rename from Analogy.LogViewer.Serilog.UnitTests/log files/ClefExample1.clef.gz rename to Analogy.LogViewer.Serilog.UnitTests/log files/CompactJsonFormat.gz diff --git a/Analogy.LogViewer.Serilog.UnitTests/log files/SourceContextTest.clef b/Analogy.LogViewer.Serilog.UnitTests/log files/CompactJsonFormatSourceContextTest.clef similarity index 100% rename from Analogy.LogViewer.Serilog.UnitTests/log files/SourceContextTest.clef rename to Analogy.LogViewer.Serilog.UnitTests/log files/CompactJsonFormatSourceContextTest.clef diff --git a/Analogy.LogViewer.Serilog.UnitTests/log files/TestColumns.clef b/Analogy.LogViewer.Serilog.UnitTests/log files/CompactJsonFormatTestColumns.clef similarity index 100% rename from Analogy.LogViewer.Serilog.UnitTests/log files/TestColumns.clef rename to Analogy.LogViewer.Serilog.UnitTests/log files/CompactJsonFormatTestColumns.clef diff --git a/Analogy.LogViewer.Serilog.UnitTests/log files/testJson.clef b/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFileCompactFormat.clef similarity index 100% rename from Analogy.LogViewer.Serilog.UnitTests/log files/testJson.clef rename to Analogy.LogViewer.Serilog.UnitTests/log files/JsonFileCompactFormat.clef diff --git a/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatPerFile.clef b/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatPerFile.clef new file mode 100644 index 0000000..438ad1a --- /dev/null +++ b/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatPerFile.clef @@ -0,0 +1,44 @@ +[ + { + "Timestamp": "2020-06-07T13:44:57.8532799+10:00", + "Level": "Information", + "MessageTemplate": "Hello, {@User}, {N:x8} at {Now}", + "Properties": { + "User": { + "Name": "nblumhardt", + "Tags": [ 1, 2, 3 ] + }, + "N": 123, + "Now": "2016-06-07T13:44:57.8532799+10:00" + }, + "Renderings": { + "N": [ + { + "Format": "x8", + "Rendering": "0000007b" + } + ] + } + }, + { + "Timestamp": "2016-06-07T13:44:57.8532799+10:00", + "Level": "Information", + "MessageTemplate": "Hello, {@User}, {N:x8} at {Now}", + "Properties": { + "User": { + "Name": "Lior", + "Tags": [ 1, 2, 3 ] + }, + "N": 123, + "Now": "2016-06-07T13:44:57.8532799+10:00" + }, + "Renderings": { + "N": [ + { + "Format": "x8", + "Rendering": "0000007b" + } + ] + } + } +] \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatPerLine.clef b/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatPerLine.clef new file mode 100644 index 0000000..a0d8344 --- /dev/null +++ b/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatPerLine.clef @@ -0,0 +1,2 @@ +{"Timestamp":"2020-06-07T13:44:57.8532799+10:00","Level":"Information","MessageTemplate":"Hello, {@User}, {N:x8} at {Now}","Properties":{"User":{"Name":"nblumhardt","Tags":[1,2,3]},"N":123,"Now":"2016-06-07T13:44:57.8532799+10:00"},"Renderings":{"N":[{"Format":"x8","Rendering":"0000007b"}]}} +{"Timestamp":"2016-06-07T13:44:57.8532799+10:00","Level":"Information","MessageTemplate":"Hello, {@User}, {N:x8} at {Now}","Properties":{"User":{"Name":"Lior","Tags":[1,2,3]},"N":123,"Now":"2016-06-07T13:44:57.8532799+10:00"},"Renderings":{"N":[{"Format":"x8","Rendering":"0000007b"}]}} \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatter.clef b/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatter.clef deleted file mode 100644 index 14256c3..0000000 --- a/Analogy.LogViewer.Serilog.UnitTests/log files/JsonFormatter.clef +++ /dev/null @@ -1 +0,0 @@ -{"Timestamp":"2016-06-07T13:44:57.8532799+10:00","Level":"Information","MessageTemplate":"Hello, {@User}, {N:x8} at {Now}","Properties":{"User":{"Name":"nblumhardt","Tags":[1,2,3]},"N":123,"Now":"2016-06-07T13:44:57.8532799+10:00"},"Renderings":{"N":[{"Format":"x8","Rendering":"0000007b"}]}} \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog/Analogy.LogViewer.Serilog.csproj b/Analogy.LogViewer.Serilog/Analogy.LogViewer.Serilog.csproj index 8fdf943..196e573 100644 --- a/Analogy.LogViewer.Serilog/Analogy.LogViewer.Serilog.csproj +++ b/Analogy.LogViewer.Serilog/Analogy.LogViewer.Serilog.csproj @@ -20,7 +20,7 @@ AnalogySerilog.png true - 1.3.6 + 2.0.0 Analogy.LogViewer true diff --git a/Analogy.LogViewer.Serilog/ChangeLogList.cs b/Analogy.LogViewer.Serilog/ChangeLogList.cs index 419bd89..fd15065 100644 --- a/Analogy.LogViewer.Serilog/ChangeLogList.cs +++ b/Analogy.LogViewer.Serilog/ChangeLogList.cs @@ -6,12 +6,17 @@ namespace Analogy.LogViewer.Serilog { public static class ChangeLogList { - public static IEnumerable GetChangeLog() + public static IEnumerable GetChangeLog()=> + new List() { - yield return new AnalogyChangeLog("Support for reading compressed files. #45", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 07, 22)); - yield return new AnalogyChangeLog("Duplicated/Extra columns with the dynamic columns feature. #44", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 07, 10)); - yield return new AnalogyChangeLog("Add dynamic columns per file properties. #43", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 07, 03)); - yield return new AnalogyChangeLog("Initial version", AnalogChangeLogType.None, "Lior Banai", new DateTime(2019, 12, 14)); - } + new AnalogyChangeLog("[V2.0.0] - Add Raw message data property and Json Viewer when relevant #109", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 09, 26)), + new AnalogyChangeLog("[V2.0.0] - Remove Regex parser from Serilog parser #112", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 09, 26)), + new AnalogyChangeLog("[V2.0.0] - Add Auto detect formatter used in log file so user won't need to define the formatter in the user settings #61", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 09, 26)), + new AnalogyChangeLog("[V2.0.0] - Add Additional Text Formatters (CompactJsonFormatter,JsonFormatter ) #6", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 09, 26)), + new AnalogyChangeLog("Support for reading compressed files. #45", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 07, 22)), + new AnalogyChangeLog("Duplicated/Extra columns with the dynamic columns feature. #44", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 07, 10)), + new AnalogyChangeLog("Add dynamic columns per file properties. #43", AnalogChangeLogType.Improvement, "Lior Banai", new DateTime(2020, 07, 03)), + new AnalogyChangeLog("Initial version", AnalogChangeLogType.None, "Lior Banai", new DateTime(2019, 12, 14)) + }; } } diff --git a/Analogy.LogViewer.Serilog/CompactClef/ClefFields.cs b/Analogy.LogViewer.Serilog/CompactClef/ClefFields.cs deleted file mode 100644 index 79ab253..0000000 --- a/Analogy.LogViewer.Serilog/CompactClef/ClefFields.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013-2015 Serilog Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System.Linq; - -namespace Analogy.LogViewer.Serilog.CompactClef -{ - static class ClefFields - { - public const string Timestamp = "@t"; - public const string MessageTemplate = "@mt"; - public const string Level = "@l"; - public const string Exception = "@x"; - public const string Renderings = "@r"; - public const string EventId = "@i"; - public const string Message = "@m"; - - public static readonly string[] All = { Timestamp, MessageTemplate, Level, Exception, Renderings, EventId, Message }; - - const string Prefix = "@"; - const string EscapedInitialAt = "@@"; - - public static string Unescape(string name) - { - if (name.StartsWith(EscapedInitialAt)) - return name.Substring(1); - - return name; - } - - public static bool IsUnrecognized(string name) - { - return !name.StartsWith(EscapedInitialAt) && - name.StartsWith(Prefix) && - !All.Contains(name); - } - } - -} diff --git a/Analogy.LogViewer.Serilog/CompactClef/Rendering.cs b/Analogy.LogViewer.Serilog/CompactClef/Rendering.cs deleted file mode 100644 index 3e9e3b0..0000000 --- a/Analogy.LogViewer.Serilog/CompactClef/Rendering.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013-2015 Serilog Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Analogy.LogViewer.Serilog.CompactClef -{ - class Rendering - { - public string Name { get; } - public string Format { get; } - public string Rendered { get; } - - public Rendering(string name, string format, string rendered) - { - Name = name; - Format = format; - Rendered = rendered; - } - } -} \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog/DataTypes/Enums.cs b/Analogy.LogViewer.Serilog/DataTypes/Enums.cs index 3cea8d1..d216513 100644 --- a/Analogy.LogViewer.Serilog/DataTypes/Enums.cs +++ b/Analogy.LogViewer.Serilog/DataTypes/Enums.cs @@ -1,15 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Analogy.LogViewer.Serilog.DataTypes +namespace Analogy.LogViewer.Serilog.DataTypes { - public enum LogFormat + public enum FileFormat { - Clef, - + Unknown, + CompactJsonFormatPerLine, + JsonFormatPerLine, + CompactJsonFormatPerFile, + JsonFormatFile, } + public enum FileFormatDetection + { + Automatic, + Manual + } } diff --git a/Analogy.LogViewer.Serilog/CompactClef/LogEventReader.cs b/Analogy.LogViewer.Serilog/DataTypes/LogEventReader.cs similarity index 62% rename from Analogy.LogViewer.Serilog/CompactClef/LogEventReader.cs rename to Analogy.LogViewer.Serilog/DataTypes/LogEventReader.cs index 4602efd..5329290 100644 --- a/Analogy.LogViewer.Serilog/CompactClef/LogEventReader.cs +++ b/Analogy.LogViewer.Serilog/DataTypes/LogEventReader.cs @@ -1,28 +1,15 @@ -// Copyright 2013-2015 Serilog Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Serilog.Events; using Serilog.Parsing; using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; -namespace Analogy.LogViewer.Serilog.CompactClef +namespace Analogy.LogViewer.Serilog.DataTypes { /// /// Reads files produced by Serilog.Formatting.Compact.CompactJsonFormatter. Events @@ -33,16 +20,18 @@ public class LogEventReader : IDisposable static readonly MessageTemplateParser Parser = new MessageTemplateParser(); readonly TextReader _text; readonly JsonSerializer _serializer; - + private readonly IMessageFields _messageFields; int _lineNumber; /// /// Construct a . /// /// Text to read from. + /// /// If specified, a JSON serializer used when converting event documents. - public LogEventReader(TextReader text, JsonSerializer serializer = null) + public LogEventReader(TextReader text, IMessageFields messageFields, JsonSerializer serializer = null) { + _messageFields = messageFields; _text = text ?? throw new ArgumentNullException(nameof(text)); _serializer = serializer ?? CreateSerializer(); } @@ -75,11 +64,10 @@ public bool TryRead(out LogEvent evt) } var data = _serializer.Deserialize(new JsonTextReader(new StringReader(line))); - var fields = data as JObject; - if (fields == null) + if (!(data is JObject fields)) throw new InvalidDataException($"The data on line {_lineNumber} is not a complete JSON object."); - evt = ReadFromJObject(_lineNumber, fields); + evt = ReadFromJObject(_lineNumber, fields,_messageFields); return true; } @@ -89,13 +77,13 @@ public bool TryRead(out LogEvent evt) /// The event in compact-JSON. /// If specified, a JSON serializer used when converting event documents. /// The log event. - public static LogEvent ReadFromString(string document, JsonSerializer serializer = null) + public LogEvent ReadFromString(string document, JsonSerializer serializer = null) { if (document == null) throw new ArgumentNullException(nameof(document)); serializer = serializer ?? CreateSerializer(); var jObject = serializer.Deserialize(new JsonTextReader(new StringReader(document))); - return ReadFromJObject(jObject); + return ReadFromJObject(jObject,_messageFields); } @@ -104,44 +92,45 @@ public static LogEvent ReadFromString(string document, JsonSerializer serializer /// /// The deserialized compact-JSON event. /// The log event. - public static LogEvent ReadFromJObject(JObject jObject) + public static LogEvent ReadFromJObject(JObject jObject, IMessageFields messageFields) { if (jObject == null) throw new ArgumentNullException(nameof(jObject)); - return ReadFromJObject(1, jObject); + return ReadFromJObject(1, jObject,messageFields); } - static LogEvent ReadFromJObject(int lineNumber, JObject jObject) + private static LogEvent ReadFromJObject(int lineNumber, JObject jObject,IMessageFields messageFields) { - var timestamp = GetRequiredTimestampField(lineNumber, jObject, ClefFields.Timestamp); + var timestamp = GetRequiredTimestampField(lineNumber, jObject, messageFields.Timestamp); string messageTemplate; - if (TryGetOptionalField(lineNumber, jObject, ClefFields.MessageTemplate, out var mt)) + if (TryGetOptionalField(lineNumber, jObject, messageFields.MessageTemplate, out var mt)) messageTemplate = mt; - else if (TryGetOptionalField(lineNumber, jObject, ClefFields.Message, out var m)) + else if (TryGetOptionalField(lineNumber, jObject, messageFields.Message, out var m)) messageTemplate = MessageTemplateSyntax.Escape(m); else messageTemplate = null; var level = LogEventLevel.Information; - if (TryGetOptionalField(lineNumber, jObject, ClefFields.Level, out string l)) + if (TryGetOptionalField(lineNumber, jObject, messageFields.Level, out string l)) level = (LogEventLevel)Enum.Parse(typeof(LogEventLevel), l); Exception exception = null; - if (TryGetOptionalField(lineNumber, jObject, ClefFields.Exception, out string ex)) + if (TryGetOptionalField(lineNumber, jObject, messageFields.Exception, out string ex)) { exception = TryPopulateException(ex, exception, jObject); } - var parsedTemplate = messageTemplate == null ? - new MessageTemplate(Enumerable.Empty()) : - Parser.Parse(messageTemplate); + var parsedTemplate = messageTemplate == null + ? new MessageTemplate(Enumerable.Empty()) + : Parser.Parse(messageTemplate); var renderings = Enumerable.Empty(); - if (jObject.TryGetValue(ClefFields.Renderings, out JToken r)) + if (jObject.TryGetValue(messageFields.Renderings, out JToken r)) { var renderedByIndex = r as JArray; if (renderedByIndex == null) - throw new InvalidDataException($"The `{ClefFields.Renderings}` value on line {lineNumber} is not an array as expected."); + throw new InvalidDataException( + $"The `{messageFields.Renderings}` value on line {lineNumber} is not an array as expected."); renderings = parsedTemplate.Tokens .OfType() @@ -150,23 +139,37 @@ static LogEvent ReadFromJObject(int lineNumber, JObject jObject) .ToArray(); } - var properties = jObject - .Properties() - .Where(f => !ClefFields.All.Contains(f.Name)) - .Select(f => - { - var name = ClefFields.Unescape(f.Name); - var renderingsByFormat = renderings.Where(rd => rd.Name == name); - return PropertyFactory.CreateProperty(name, f.Value, renderingsByFormat); - }) - .ToList(); - - string eventId; - if (TryGetOptionalField(lineNumber, jObject, ClefFields.EventId, out eventId)) // TODO; should support numeric ids. + List properties; + if (jObject.ContainsKey("Properties") && jObject["Properties"] is JObject props) + { + properties = props.Properties() + .Where(f => !messageFields.All.Contains(f.Name)) + .Select(f => + { + var name = messageFields.Unescape(f.Name); + var renderingsByFormat = renderings.Where(rd => rd.Name == name).ToList(); + return PropertyFactory.CreateProperty(name, f.Value, renderingsByFormat); + }) + .ToList(); + } + else + { + properties = jObject + .Properties() + .Where(f => !messageFields.All.Contains(f.Name)) + .Select(f => + { + var name = messageFields.Unescape(f.Name); + var renderingsByFormat = renderings.Where(rd => rd.Name == name).ToList(); + return PropertyFactory.CreateProperty(name, f.Value, renderingsByFormat); + }) + .ToList(); + } + if (TryGetOptionalField(lineNumber, jObject, messageFields.EventId, out var eventId)) // TODO; should support numeric ids. { properties.Add(new LogEventProperty("@i", new ScalarValue(eventId))); } - + properties.Add(new LogEventProperty("Raw Data",new ScalarValue(jObject.ToString()))); return new LogEvent(timestamp, level, exception, parsedTemplate, properties); } @@ -184,7 +187,7 @@ private static Exception TryPopulateException(string header, Exception exception return new TextException(header); } - static bool TryGetOptionalField(int lineNumber, JObject data, string field, out string value) + private static bool TryGetOptionalField(int lineNumber, JObject data, string field, out string value) { JToken token; if (!data.TryGetValue(field, out token) || token.Type == JTokenType.Null) @@ -200,17 +203,16 @@ static bool TryGetOptionalField(int lineNumber, JObject data, string field, out return true; } - static DateTimeOffset GetRequiredTimestampField(int lineNumber, JObject data, string field) + private static DateTimeOffset GetRequiredTimestampField(int lineNumber, JObject data, string field) { - JToken token; - if (!data.TryGetValue(field, out token) || token.Type == JTokenType.Null) + if (!data.TryGetValue(field, out var token) || token.Type == JTokenType.Null) throw new InvalidDataException($"The data on line {lineNumber} does not include the required `{field}` field."); if (token.Type == JTokenType.Date) { var dt = token.Value().Value; - if (dt is DateTimeOffset) - return (DateTimeOffset)dt; + if (dt is DateTimeOffset offset) + return offset; return (DateTime)dt; } @@ -222,7 +224,7 @@ static DateTimeOffset GetRequiredTimestampField(int lineNumber, JObject data, st return DateTimeOffset.Parse(text); } - static JsonSerializer CreateSerializer() + private static JsonSerializer CreateSerializer() { return JsonSerializer.Create(new JsonSerializerSettings { diff --git a/Analogy.LogViewer.Serilog/DataTypes/MessageFields.cs b/Analogy.LogViewer.Serilog/DataTypes/MessageFields.cs index dc17d18..e4d4829 100644 --- a/Analogy.LogViewer.Serilog/DataTypes/MessageFields.cs +++ b/Analogy.LogViewer.Serilog/DataTypes/MessageFields.cs @@ -1,12 +1,113 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Analogy.LogViewer.Serilog.DataTypes { - public class MessageFields + public interface IMessageFields { + string Timestamp { get; } + string MessageTemplate { get; } + string Level { get; } + string Exception { get; } + string Renderings { get; } + string EventId { get; } + string Message { get; } + string[] All { get; } + string[] Required { get; } + string Unescape(string name); + bool IsUnrecognized(string name); } + + public class CompactJsonFormatMessageFields : IMessageFields + { + public string Timestamp { get; } + public string MessageTemplate { get; } + public string Level { get; } + public string Exception { get; } + public string Renderings { get; } + public string EventId { get; } + public string Message { get; } + public string[] Required { get; } + public string[] All { get; } + string Prefix = "@"; + string EscapedInitialAt = "@@"; + + public CompactJsonFormatMessageFields() + { + Timestamp = "@t"; + MessageTemplate = "@mt"; + Level = "@l"; + Exception = "@x"; + Renderings = "@r"; + EventId = "@i"; + Message = "@m"; + Prefix = "@"; + EscapedInitialAt = "@@"; + All = new[] { Timestamp, MessageTemplate, Level, Exception, Renderings, EventId, Message }; + Required = new[] { Timestamp, MessageTemplate, Level, Exception, Renderings }; + + } + public string Unescape(string name) + { + if (name.StartsWith(EscapedInitialAt)) + return name.Substring(1); + + return name; + } + + public bool IsUnrecognized(string name) + { + return !name.StartsWith(EscapedInitialAt) && + name.StartsWith(Prefix) && + !All.Contains(name); + } + } + + + public class JsonFormatMessageFields : IMessageFields + { + public string Timestamp { get; } + public string MessageTemplate { get; } + public string Level { get; } + public string Exception { get; } + public string Renderings { get; } + public string EventId { get; } + public string Message { get; } + + public string[] All { get; } + public string[] Required { get; } + string Prefix = "@"; + string EscapedInitialAt = "@@"; + + public JsonFormatMessageFields() + { + Timestamp = "Timestamp"; + MessageTemplate = "MessageTemplate"; + Level = "Level"; + Exception = "Exception"; + Renderings = "RenderedMessage"; + EventId = "@i"; + Message = "@m"; + All = new[] { Timestamp, MessageTemplate, Level, Exception, Renderings, EventId, Message }; + Required = new[] { Timestamp, MessageTemplate, Level, Exception, Renderings }; + + } + public string Unescape(string name) + { + if (name.StartsWith(EscapedInitialAt)) + return name.Substring(1); + + return name; + } + + public bool IsUnrecognized(string name) + { + return !name.StartsWith(EscapedInitialAt) && + name.StartsWith(Prefix) && + !All.Contains(name); + } + } + + } + diff --git a/Analogy.LogViewer.Serilog/CompactClef/MessageTemplateSyntax.cs b/Analogy.LogViewer.Serilog/DataTypes/MessageTemplateSyntax.cs similarity index 85% rename from Analogy.LogViewer.Serilog/CompactClef/MessageTemplateSyntax.cs rename to Analogy.LogViewer.Serilog/DataTypes/MessageTemplateSyntax.cs index c9e5746..7ed2e8c 100644 --- a/Analogy.LogViewer.Serilog/CompactClef/MessageTemplateSyntax.cs +++ b/Analogy.LogViewer.Serilog/DataTypes/MessageTemplateSyntax.cs @@ -1,6 +1,6 @@ using System; -namespace Analogy.LogViewer.Serilog.CompactClef +namespace Analogy.LogViewer.Serilog.DataTypes { static class MessageTemplateSyntax { diff --git a/Analogy.LogViewer.Serilog/CompactClef/PropertyFactory.cs b/Analogy.LogViewer.Serilog/DataTypes/PropertyFactory.cs similarity index 93% rename from Analogy.LogViewer.Serilog/CompactClef/PropertyFactory.cs rename to Analogy.LogViewer.Serilog/DataTypes/PropertyFactory.cs index 281e599..c4d97ff 100644 --- a/Analogy.LogViewer.Serilog/CompactClef/PropertyFactory.cs +++ b/Analogy.LogViewer.Serilog/DataTypes/PropertyFactory.cs @@ -12,23 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Newtonsoft.Json.Linq; -using Serilog.Events; using System.Collections.Generic; using System.Linq; +using Newtonsoft.Json.Linq; +using Serilog.Events; -namespace Analogy.LogViewer.Serilog.CompactClef +namespace Analogy.LogViewer.Serilog.DataTypes { static class PropertyFactory { const string TypeTagPropertyName = "$type"; - public static LogEventProperty CreateProperty(string name, JToken value, IEnumerable renderings) + public static LogEventProperty CreateProperty(string name, JToken value, List renderings) { return new LogEventProperty(name, CreatePropertyValue(value, renderings)); } - static LogEventPropertyValue CreatePropertyValue(JToken value, IEnumerable renderings) + static LogEventPropertyValue CreatePropertyValue(JToken value, List renderings) { if (value.Type == JTokenType.Null) return new ScalarValue(null); diff --git a/Analogy.LogViewer.Serilog/CompactClef/RenderableScalarValue.cs b/Analogy.LogViewer.Serilog/DataTypes/RenderableScalarValue.cs similarity index 52% rename from Analogy.LogViewer.Serilog/CompactClef/RenderableScalarValue.cs rename to Analogy.LogViewer.Serilog/DataTypes/RenderableScalarValue.cs index 4bd7039..079126a 100644 --- a/Analogy.LogViewer.Serilog/CompactClef/RenderableScalarValue.cs +++ b/Analogy.LogViewer.Serilog/DataTypes/RenderableScalarValue.cs @@ -1,29 +1,15 @@ -// Copyright 2013-2015 Serilog Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Serilog.Events; -using System; +using System; using System.Collections.Generic; using System.IO; +using Serilog.Events; -namespace Analogy.LogViewer.Serilog.CompactClef +namespace Analogy.LogViewer.Serilog.DataTypes { class RenderableScalarValue : ScalarValue { readonly Dictionary _renderings = new Dictionary(); - public RenderableScalarValue(object value, IEnumerable renderings) + public RenderableScalarValue(object value, List renderings) : base(value) { if (renderings == null) throw new ArgumentNullException(nameof(renderings)); diff --git a/Analogy.LogViewer.Serilog/DataTypes/Rendering.cs b/Analogy.LogViewer.Serilog/DataTypes/Rendering.cs new file mode 100644 index 0000000..1652ece --- /dev/null +++ b/Analogy.LogViewer.Serilog/DataTypes/Rendering.cs @@ -0,0 +1,17 @@ + +namespace Analogy.LogViewer.Serilog.DataTypes +{ + class Rendering + { + public string Name { get; } + public string Format { get; } + public string Rendered { get; } + + public Rendering(string name, string format, string rendered) + { + Name = name; + Format = format; + Rendered = rendered; + } + } +} \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog/CompactClef/TextException.cs b/Analogy.LogViewer.Serilog/DataTypes/TextException.cs similarity index 95% rename from Analogy.LogViewer.Serilog/CompactClef/TextException.cs rename to Analogy.LogViewer.Serilog/DataTypes/TextException.cs index 8ce81d8..7b853ac 100644 --- a/Analogy.LogViewer.Serilog/CompactClef/TextException.cs +++ b/Analogy.LogViewer.Serilog/DataTypes/TextException.cs @@ -14,7 +14,7 @@ using System; -namespace Analogy.LogViewer.Serilog.CompactClef +namespace Analogy.LogViewer.Serilog.DataTypes { class TextException : Exception { diff --git a/Analogy.LogViewer.Serilog/IAnalogy/DataProvidersFactory.cs b/Analogy.LogViewer.Serilog/IAnalogy/DataProvidersFactory.cs index f650dd5..91bac30 100644 --- a/Analogy.LogViewer.Serilog/IAnalogy/DataProvidersFactory.cs +++ b/Analogy.LogViewer.Serilog/IAnalogy/DataProvidersFactory.cs @@ -1,10 +1,9 @@ -using Analogy.Interfaces; -using Analogy.Interfaces.Factories; -using Analogy.LogViewer.Serilog.IAnalogy; -using System; +using System; using System.Collections.Generic; +using Analogy.Interfaces; +using Analogy.Interfaces.Factories; -namespace Analogy.LogViewer.Serilog +namespace Analogy.LogViewer.Serilog.IAnalogy { public class DataProvidersFactory : IAnalogyDataProvidersFactory { diff --git a/Analogy.LogViewer.Serilog/IAnalogy/OfflineDataProvider.cs b/Analogy.LogViewer.Serilog/IAnalogy/OfflineDataProvider.cs index 4903f24..4014d47 100644 --- a/Analogy.LogViewer.Serilog/IAnalogy/OfflineDataProvider.cs +++ b/Analogy.LogViewer.Serilog/IAnalogy/OfflineDataProvider.cs @@ -1,11 +1,14 @@ using Analogy.Interfaces; +using Analogy.LogViewer.Serilog.DataTypes; using Analogy.LogViewer.Serilog.Managers; -using Analogy.LogViewer.Serilog.Regex; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Drawing; using System.IO; +using System.IO.Compression; using System.Linq; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -29,10 +32,10 @@ public class OfflineDataProvider : IAnalogyOfflineDataProvider Directory.Exists(UserSettingsManager.UserSettings.Settings.Directory)) ? UserSettingsManager.UserSettings.Settings.Directory : Environment.CurrentDirectory; - private ClefParser ClefParser { get; } + private CompactJsonFormatParser CompactFormatPerLineParser { get; } + private JsonFormatterParser JsonPerLineParser { get; } + private JsonFileParser CompactJsonFileParser { get; } private JsonFileParser JsonFileParser { get; } - private JsonFormatterParser JsonFormatterParser { get; } - private Regex.RegexParser RegexParser { get; set; } public bool UseCustomColors { get; set; } = false; public IEnumerable<(string originalHeader, string replacementHeader)> GetReplacementHeaders() @@ -42,33 +45,99 @@ public class OfflineDataProvider : IAnalogyOfflineDataProvider => (Color.Empty, Color.Empty); public OfflineDataProvider() { - ClefParser = new ClefParser(); - JsonFileParser = new JsonFileParser(); - JsonFormatterParser=new JsonFormatterParser(); - RegexParser = new Regex.RegexParser(UserSettingsManager.UserSettings.Settings.RegexPatterns, false, - LogManager.Instance); + CompactFormatPerLineParser = new CompactJsonFormatParser(); + CompactJsonFileParser = new JsonFileParser(new CompactJsonFormatMessageFields()); + + JsonPerLineParser = new JsonFormatterParser(new JsonFormatMessageFields()); + JsonFileParser = new JsonFileParser(new JsonFormatMessageFields()); } public async Task> Process(string fileName, CancellationToken token, ILogMessageCreatedHandler messagesHandler) { if (CanOpenFile(fileName)) { + if (UserSettingsManager.UserSettings.Settings.FileFormatDetection==FileFormatDetection.Automatic || + UserSettingsManager.UserSettings.Settings.Format == FileFormat.Unknown) + UserSettingsManager.UserSettings.Settings.Format = TryDetectFormat(fileName); + switch (UserSettingsManager.UserSettings.Settings.Format) { - case SerilogFileFormat.CLEF: - return await ClefParser.Process(fileName, token, messagesHandler); - case SerilogFileFormat.JSONFile: + case FileFormat.CompactJsonFormatPerLine: + return await CompactFormatPerLineParser.Process(fileName, token, messagesHandler); + case FileFormat.CompactJsonFormatPerFile: + return await CompactJsonFileParser.Process(fileName, token, messagesHandler); + case FileFormat.JsonFormatFile: return await JsonFileParser.Process(fileName, token, messagesHandler); - case SerilogFileFormat.JSONPerLine: - return await JsonFormatterParser.Process(fileName, token, messagesHandler); - case SerilogFileFormat.REGEX: - RegexParser.SetRegexPatterns(UserSettingsManager.UserSettings.Settings.RegexPatterns); - return await RegexParser.ParseLog(fileName, token, messagesHandler); + case FileFormat.JsonFormatPerLine: + return await JsonPerLineParser.Process(fileName, token, messagesHandler); } } + LogManager.Instance.LogError($"Unsupported File {fileName}", nameof(OfflineDataProvider)); return new List(0); } + public static FileFormat TryDetectFormat(string fileName) + { + string jsonData = string.Empty; + if (fileName.EndsWith(".gz", StringComparison.InvariantCultureIgnoreCase)) + { + using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + using (var gzStream = new GZipStream(fileStream, CompressionMode.Decompress)) + { + using (var streamReader = new StreamReader(gzStream, encoding: Encoding.UTF8)) + { + jsonData = streamReader.ReadToEnd(); + } + } + } + } + + if (string.IsNullOrEmpty(jsonData)) + jsonData = File.ReadAllText(fileName); + var format = TryParseAsFile(jsonData); + if (format == FileFormat.Unknown) + format = TryParsePerLine(jsonData); + return format; + } + + private static FileFormat TryParsePerLine(string jsonData) + { + try + { + IMessageFields fields = new JsonFormatMessageFields(); + if (jsonData.Contains(fields.Timestamp) && jsonData.Contains(fields.MessageTemplate)) + return FileFormat.JsonFormatPerLine; + fields = new CompactJsonFormatMessageFields(); + if (jsonData.Contains(fields.Timestamp) && jsonData.Contains(fields.MessageTemplate)) + return FileFormat.CompactJsonFormatPerLine; + return FileFormat.Unknown; + } + catch (Exception) + { + return FileFormat.Unknown; + } + } + + private static FileFormat TryParseAsFile(string jsonData) + { + try + { + var jsonObject = JsonConvert.DeserializeObject(jsonData); + IMessageFields fields = new JsonFormatMessageFields(); + if (jsonData.Contains(fields.Timestamp) && jsonData.Contains(fields.MessageTemplate)) + return FileFormat.JsonFormatFile; + fields = new CompactJsonFormatMessageFields(); + if (jsonData.Contains(fields.Timestamp) && jsonData.Contains(fields.MessageTemplate)) + return FileFormat.CompactJsonFormatPerFile; + return FileFormat.Unknown; + } + catch (Exception) + { + return FileFormat.Unknown; + } + } + public IEnumerable GetSupportedFiles(DirectoryInfo dirInfo, bool recursiveLoad) => GetSupportedFilesInternal(dirInfo, recursiveLoad); diff --git a/Analogy.LogViewer.Serilog/JsonFormatterParser.cs b/Analogy.LogViewer.Serilog/JsonFormatterParser.cs deleted file mode 100644 index 20ae12c..0000000 --- a/Analogy.LogViewer.Serilog/JsonFormatterParser.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Analogy.Interfaces; -using Analogy.LogViewer.Serilog.CompactClef; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Serilog; -using Serilog.Formatting.Json; - -namespace Analogy.LogViewer.Serilog -{ - public class JsonFormatterParser - { - public async Task> Process(string fileName, CancellationToken token, - ILogMessageCreatedHandler messagesHandler) - { - var formatter = new JsonFormatter(); - List parsedMessages = new List(); - try - { - using (var analogy = new LoggerConfiguration().WriteTo.Analogy(formatter) - .CreateLogger()) - { - using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) - { - var json = await streamReader.ReadLineAsync().ConfigureAwait(false); - var data = JsonConvert.DeserializeObject(json); - if (data is JObject jo) - { - var m = ParserJObject(jo, analogy); - parsedMessages.Add(m); - } - else if (data is JArray arr) - { - foreach (var obj in arr.ToList()) - { - if (obj is JObject j) - { - - var m = ParserJObject(j, analogy); - parsedMessages.Add(m); - } - } - } - } - } - - messagesHandler.AppendMessages(parsedMessages, fileName); - return parsedMessages; - } - - catch (Exception e) - { - AnalogyLogMessage empty = new AnalogyLogMessage($"Error reading file {fileName}: Error: {e.Message}", AnalogyLogLevel.Error, AnalogyLogClass.General, "Analogy", "None"); - empty.Source = nameof(ClefParser); - empty.Module = "Analogy.LogViewer.Serilog"; - parsedMessages.Add(empty); - messagesHandler.AppendMessages(parsedMessages, fileName); - return parsedMessages; - } - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private AnalogyLogMessage ParserJObject(JObject jo, ILogger analogy) - { - var evt = LogEventReader.ReadFromJObject(jo); - { - analogy.Write(evt); - return CommonParser.ParseLogEventProperties(evt); - - } - - } - - } -} \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog/CommonParser.cs b/Analogy.LogViewer.Serilog/Parsers/CommonParser.cs similarity index 98% rename from Analogy.LogViewer.Serilog/CommonParser.cs rename to Analogy.LogViewer.Serilog/Parsers/CommonParser.cs index db86406..eea68bd 100644 --- a/Analogy.LogViewer.Serilog/CommonParser.cs +++ b/Analogy.LogViewer.Serilog/Parsers/CommonParser.cs @@ -41,7 +41,7 @@ public static AnalogyLogMessage ParseLogEventProperties(LogEvent evt) } m.Date = evt.Timestamp.DateTime; - m.Text = AnalogySink.output; + m.Text = AnalogySink.output;// evt.MessageTemplate.Text; if (evt.Properties.TryGetValue(Constants.ProcessName, out var processName)) { if (processName is ScalarValue scalarValue && diff --git a/Analogy.LogViewer.Serilog/ClefParser.cs b/Analogy.LogViewer.Serilog/Parsers/CompactJsonFormatParser.cs similarity index 70% rename from Analogy.LogViewer.Serilog/ClefParser.cs rename to Analogy.LogViewer.Serilog/Parsers/CompactJsonFormatParser.cs index 53ba43d..68eea72 100644 --- a/Analogy.LogViewer.Serilog/ClefParser.cs +++ b/Analogy.LogViewer.Serilog/Parsers/CompactJsonFormatParser.cs @@ -1,5 +1,5 @@ using Analogy.Interfaces; -using Analogy.LogViewer.Serilog.CompactClef; +using Analogy.LogViewer.Serilog.DataTypes; using Serilog; using System; using System.Collections.Generic; @@ -11,8 +11,14 @@ namespace Analogy.LogViewer.Serilog { - public class ClefParser + public class CompactJsonFormatParser { + private static IMessageFields messageFields; + + static CompactJsonFormatParser() + { + messageFields = new CompactJsonFormatMessageFields(); + } public async Task> Process(string fileName, CancellationToken token, ILogMessageCreatedHandler messagesHandler) { var messages = await Task>.Factory.StartNew(() => @@ -30,10 +36,10 @@ public async Task> Process(string fileName, Cance { using (var gzStream = new GZipStream(fileStream, CompressionMode.Decompress)) { - using (var clef = new StreamReader(gzStream, encoding: Encoding.UTF8)) + using (var streamReader = new StreamReader(gzStream, encoding: Encoding.UTF8)) { - var reader = new LogEventReader(clef); - while (reader.TryRead(out var evt)) + var reader = new LogEventReader(streamReader, messageFields); + while (reader.TryRead(out var evt) && !token.IsCancellationRequested) { analogy.Write(evt); AnalogyLogMessage m = CommonParser.ParseLogEventProperties(evt); @@ -45,21 +51,19 @@ public async Task> Process(string fileName, Cance } } } - else + + using (var streamReader = new StreamReader(fileStream, encoding: Encoding.UTF8)) { - using (var clef = new StreamReader(fileStream, encoding: Encoding.UTF8)) + var reader = new LogEventReader(streamReader, messageFields); + while (reader.TryRead(out var evt)) { - var reader = new LogEventReader(clef); - while (reader.TryRead(out var evt)) - { - analogy.Write(evt); - AnalogyLogMessage m = CommonParser.ParseLogEventProperties(evt); - parsedMessages.Add(m); - } - - messagesHandler.AppendMessages(parsedMessages, fileName); - return parsedMessages; + analogy.Write(evt); + AnalogyLogMessage m = CommonParser.ParseLogEventProperties(evt); + parsedMessages.Add(m); } + + messagesHandler.AppendMessages(parsedMessages, fileName); + return parsedMessages; } } } @@ -69,7 +73,7 @@ public async Task> Process(string fileName, Cance { AnalogyLogMessage empty = new AnalogyLogMessage($"Error reading file {fileName}: Error: {e.Message}", AnalogyLogLevel.Error, AnalogyLogClass.General, "Analogy", "None"); - empty.Source = nameof(ClefParser); + empty.Source = nameof(CompactJsonFormatParser); empty.Module = "Analogy.LogViewer.Serilog"; parsedMessages.Add(empty); messagesHandler.AppendMessages(parsedMessages, fileName); diff --git a/Analogy.LogViewer.Serilog/JsonFileParser.cs b/Analogy.LogViewer.Serilog/Parsers/JsonFileParser.cs similarity index 59% rename from Analogy.LogViewer.Serilog/JsonFileParser.cs rename to Analogy.LogViewer.Serilog/Parsers/JsonFileParser.cs index 0b4b801..480a371 100644 --- a/Analogy.LogViewer.Serilog/JsonFileParser.cs +++ b/Analogy.LogViewer.Serilog/Parsers/JsonFileParser.cs @@ -1,14 +1,13 @@ using Analogy.Interfaces; -using Analogy.LogViewer.Serilog.CompactClef; +using Analogy.LogViewer.Serilog.DataTypes; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Serilog; -using Serilog.Formatting; using System; using System.Collections.Generic; using System.IO; +using System.IO.Compression; using System.Linq; -using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -17,7 +16,12 @@ namespace Analogy.LogViewer.Serilog { public class JsonFileParser { - public static ITextFormatter textFormatter; + private IMessageFields messageFields; + + public JsonFileParser(IMessageFields messageFields) + { + this.messageFields = messageFields; + } public async Task> Process(string fileName, CancellationToken token, ILogMessageCreatedHandler messagesHandler) { var messages = await Task>.Factory.StartNew(() => @@ -30,14 +34,34 @@ public async Task> Process(string fileName, Cance .CreateLogger()) { using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) { - var json = streamReader.ReadToEnd(); - var data = JsonConvert.DeserializeObject(json); + string jsonData; + if (fileName.EndsWith(".gz", StringComparison.InvariantCultureIgnoreCase)) + { + using (var gzStream = new GZipStream(fileStream, CompressionMode.Decompress)) + { + using (var streamReader = new StreamReader(gzStream, encoding: Encoding.UTF8)) + { + jsonData = streamReader.ReadToEnd(); + + } + } + } + else + using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) + { + jsonData = streamReader.ReadToEnd(); + } + + + var data = JsonConvert.DeserializeObject(jsonData); if (data is JObject jo) { - var m = ParserJObject(jo, analogy); + var evt = LogEventReader.ReadFromJObject(jo, messageFields); + analogy.Write(evt); + AnalogyLogMessage m = CommonParser.ParseLogEventProperties(evt); parsedMessages.Add(m); + } else if (data is JArray arr) { @@ -45,8 +69,11 @@ public async Task> Process(string fileName, Cance { if (obj is JObject j) { - var m = ParserJObject(j, analogy); + var evt = LogEventReader.ReadFromJObject(j, messageFields); + analogy.Write(evt); + AnalogyLogMessage m = CommonParser.ParseLogEventProperties(evt); parsedMessages.Add(m); + } } } @@ -61,7 +88,7 @@ public async Task> Process(string fileName, Cance { AnalogyLogMessage empty = new AnalogyLogMessage($"Error reading file {fileName}: Error: {e.Message}", AnalogyLogLevel.Error, AnalogyLogClass.General, "Analogy", "None"); - empty.Source = nameof(ClefParser); + empty.Source = nameof(CompactJsonFormatParser); empty.Module = "Analogy.LogViewer.Serilog"; parsedMessages.Add(empty); messagesHandler.AppendMessages(parsedMessages, fileName); @@ -70,17 +97,5 @@ public async Task> Process(string fileName, Cance }); return messages; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private AnalogyLogMessage ParserJObject(JObject jo, ILogger analogy) - { - var evt = LogEventReader.ReadFromJObject(jo); - { - analogy.Write(evt); - return CommonParser.ParseLogEventProperties(evt); - - } - - } - } } diff --git a/Analogy.LogViewer.Serilog/Parsers/JsonFormatterParser.cs b/Analogy.LogViewer.Serilog/Parsers/JsonFormatterParser.cs new file mode 100644 index 0000000..cdea2ad --- /dev/null +++ b/Analogy.LogViewer.Serilog/Parsers/JsonFormatterParser.cs @@ -0,0 +1,104 @@ +using Analogy.Interfaces; +using Analogy.LogViewer.Serilog.DataTypes; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Serilog; +using Serilog.Formatting.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Analogy.LogViewer.Serilog +{ + public class JsonFormatterParser + { + private IMessageFields messageFields; + private JsonSerializerSettings JsonSerializerSettings; + + public JsonFormatterParser(IMessageFields messageFields) + { + this.messageFields = messageFields; + JsonSerializerSettings = new JsonSerializerSettings + { + DateParseHandling=DateParseHandling.DateTimeOffset, + DateFormatHandling = DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = DateTimeZoneHandling.Utc, + }; + + } + public async Task> Process(string fileName, CancellationToken token, + ILogMessageCreatedHandler messagesHandler) + { + //var formatter = new JsonFormatter(); + List parsedMessages = new List(); + try + { + using (var analogy = new LoggerConfiguration().WriteTo.Analogy() + .CreateLogger()) + { + using (var fileStream = + new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + + if (fileName.EndsWith(".gz", StringComparison.InvariantCultureIgnoreCase)) + { + using (var gzStream = new GZipStream(fileStream, CompressionMode.Decompress)) + { + using (var streamReader = new StreamReader(gzStream, encoding: Encoding.UTF8)) + { + string json; + while ((json = await streamReader.ReadLineAsync()) != null) + { + + var data = JsonConvert.DeserializeObject(json, JsonSerializerSettings); + var evt = LogEventReader.ReadFromJObject(data as JObject, messageFields); + { + analogy.Write(evt); + AnalogyLogMessage m = CommonParser.ParseLogEventProperties(evt); + parsedMessages.Add(m); + } + } + + } + } + } + + + using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) + { + string json; + while ((json = await streamReader.ReadLineAsync()) != null) + { + var data = JsonConvert.DeserializeObject(json); + var evt = LogEventReader.ReadFromJObject(data as JObject, messageFields); + { + analogy.Write(evt); + AnalogyLogMessage m = CommonParser.ParseLogEventProperties(evt); + parsedMessages.Add(m); + } + } + } + + } + + messagesHandler.AppendMessages(parsedMessages, fileName); + return parsedMessages; + } + } + catch (Exception e) + { + AnalogyLogMessage empty = new AnalogyLogMessage($"Error reading file {fileName}: Error: {e.Message}", + AnalogyLogLevel.Error, AnalogyLogClass.General, "Analogy", "None"); + empty.Source = nameof(CompactJsonFormatParser); + empty.Module = "Analogy.LogViewer.Serilog"; + parsedMessages.Add(empty); + messagesHandler.AppendMessages(parsedMessages, fileName); + return parsedMessages; + } + } + } +} \ No newline at end of file diff --git a/Analogy.LogViewer.Serilog/Properties/Resources.Designer.cs b/Analogy.LogViewer.Serilog/Properties/Resources.Designer.cs index d285231..097f4cd 100644 --- a/Analogy.LogViewer.Serilog/Properties/Resources.Designer.cs +++ b/Analogy.LogViewer.Serilog/Properties/Resources.Designer.cs @@ -90,6 +90,88 @@ internal static System.Drawing.Bitmap AnalogySerilog32x32 { } } + /// + /// Looks up a localized string similar to [ + /// { + /// "@t": "2019-12-10T13:33:23.0970926Z", + /// "@mt": "An unknown error occurred", + /// "@l": "Error", + /// "@x": "Exception stack trace", + /// "SourceContext": "MySourceContext", + /// "Scope": [ + /// "FirstScope", + /// 1850562557, + /// "198441851" + /// ], + /// "MachineName": "MY-MACHINE", + /// "EnvironmentUserName": "WORKGROUP\\SYSTEM", + /// "ExceptionDetail": { + /// "HResult": -2146233087, + /// "Message": "Internal Error", + /// "Source": "System.ServiceModel", + /// "Action": null, + /// [rest of string was truncated]";. + /// + internal static string CompactJsonFormatPerFile { + get { + return ResourceManager.GetString("CompactJsonFormatPerFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {"@t":"2016-10-12T04:46:58.0554314Z","@mt":"Hello, {@User}","User":{"Name":"nblumhardt","Id":101}} + ///{"@t":"2016-10-12T04:46:58.0684369Z","@mt":"Number {N:x8}","@r":["0000002a"],"N":42} + ///{"@t":"2016-10-12T04:46:58.0724384Z","@mt":"Tags are {Tags}","@l":"Warning","Tags":["test","orange"]} + ///{"@t":"2016-10-12T04:46:58.0904378Z","@mt":"Something failed","@l":"Error", "@x":"System.DivideByZer...<snip>"}. + /// + internal static string CompactJsonFormatPerLine { + get { + return ResourceManager.GetString("CompactJsonFormatPerLine", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to [ + /// { + /// "Timestamp": "2020-06-07T13:44:57.8532799+10:00", + /// "Level": "Information", + /// "MessageTemplate": "Hello, {@User}, {N:x8} at {Now}", + /// "Properties": { + /// "User": { + /// "Name": "nblumhardt", + /// "Tags": [ 1, 2, 3 ] + /// }, + /// "N": 123, + /// "Now": "2016-06-07T13:44:57.8532799+10:00" + /// }, + /// "Renderings": { + /// "N": [ + /// { + /// "Format": "x8", + /// "Rendering": "0000007b" + /// } + /// ] + /// } + /// }, + /// { + /// "Timestamp": "2016-06-07T13: [rest of string was truncated]";. + /// + internal static string JsonFormatFile { + get { + return ResourceManager.GetString("JsonFormatFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {"Timestamp":"2020-06-07T13:44:57.8532799+10:00","Level":"Information","MessageTemplate":"Hello, {@User}, {N:x8} at {Now}","Properties":{"User":{"Name":"nblumhardt","Tags":[1,2,3]},"N":123,"Now":"2016-06-07T13:44:57.8532799+10:00"},"Renderings":{"N":[{"Format":"x8","Rendering":"0000007b"}]}} + ///{"Timestamp":"2016-06-07T13:44:57.8532799+10:00","Level":"Information","MessageTemplate":"Hello, {@User}, {N:x8} at {Now}","Properties":{"User":{"Name":"Lior","Tags":[1,2,3]},"N":123,"Now":"2016-06-07T13:44:57.8532799+ [rest of string was truncated]";. + /// + internal static string JsonFormatPerLine { + get { + return ResourceManager.GetString("JsonFormatPerLine", resourceCulture); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/Analogy.LogViewer.Serilog/Properties/Resources.resx b/Analogy.LogViewer.Serilog/Properties/Resources.resx index e785147..d091ea6 100644 --- a/Analogy.LogViewer.Serilog/Properties/Resources.resx +++ b/Analogy.LogViewer.Serilog/Properties/Resources.resx @@ -127,6 +127,145 @@ ..\Resources\AnalogySerilog32x32.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + [ + { + "@t": "2019-12-10T13:33:23.0970926Z", + "@mt": "An unknown error occurred", + "@l": "Error", + "@x": "Exception stack trace", + "SourceContext": "MySourceContext", + "Scope": [ + "FirstScope", + 1850562557, + "198441851" + ], + "MachineName": "MY-MACHINE", + "EnvironmentUserName": "WORKGROUP\\SYSTEM", + "ExceptionDetail": { + "HResult": -2146233087, + "Message": "Internal Error", + "Source": "System.ServiceModel", + "Action": null, + "Code": { + "IsPredefinedFault": true, + "IsSenderFault": true, + "IsReceiverFault": false, + "Namespace": "http://schemas.xmlsoap.org/soap/envelope/", + "Name": "Client", + "SubCode": null + }, + "Reason": { + "Translations": [ + { + "XmlLang": "", + "Text": "Internal Error" + } + ] + }, + "Type": "System.ServiceModel.FaultException" + }, + "AssemblyVersion": "2.1.0.1017" + }, + { + "@t": "2019-12-10T13:33:23.0970926Z", + "@mt": "An unknown error occurred", + "@l": "Error", + "@x": "Exception stack trace", + "SourceContext": "MySourceContext", + "Scope": [ + "FirstScope", + 1850562557, + "198441851" + ], + "MachineName": "MY-MACHINE", + "ProcessId": 11, + "ProcessName": "My process", + "ThreadId": 1, + "EnvironmentUserName": "WORKGROUP\\SYSTEM", + "ExceptionDetail": { + "HResult": -2146233087, + "Message": "Internal Error", + "Source": "System.ServiceModel", + "Action": null, + "Code": { + "IsPredefinedFault": true, + "IsSenderFault": true, + "IsReceiverFault": false, + "Namespace": "http://schemas.xmlsoap.org/soap/envelope/", + "Name": "Client", + "SubCode": null + }, + "Reason": { + "Translations": [ + { + "XmlLang": "", + "Text": "Internal Error" + } + ] + }, + "Type": "System.ServiceModel.FaultException" + }, + "AssemblyVersion": "2.1.0.1017" + } +] + + + {"@t":"2016-10-12T04:46:58.0554314Z","@mt":"Hello, {@User}","User":{"Name":"nblumhardt","Id":101}} +{"@t":"2016-10-12T04:46:58.0684369Z","@mt":"Number {N:x8}","@r":["0000002a"],"N":42} +{"@t":"2016-10-12T04:46:58.0724384Z","@mt":"Tags are {Tags}","@l":"Warning","Tags":["test","orange"]} +{"@t":"2016-10-12T04:46:58.0904378Z","@mt":"Something failed","@l":"Error", "@x":"System.DivideByZer...<snip>"} + + + [ + { + "Timestamp": "2020-06-07T13:44:57.8532799+10:00", + "Level": "Information", + "MessageTemplate": "Hello, {@User}, {N:x8} at {Now}", + "Properties": { + "User": { + "Name": "nblumhardt", + "Tags": [ 1, 2, 3 ] + }, + "N": 123, + "Now": "2016-06-07T13:44:57.8532799+10:00" + }, + "Renderings": { + "N": [ + { + "Format": "x8", + "Rendering": "0000007b" + } + ] + } + }, + { + "Timestamp": "2016-06-07T13:44:57.8532799+10:00", + "Level": "Information", + "MessageTemplate": "Hello, {@User}, {N:x8} at {Now}", + "Properties": { + "User": { + "Name": "Lior", + "Tags": [ 1, 2, 3 ] + }, + "N": 123, + "Now": "2016-06-07T13:44:57.8532799+10:00" + }, + "Renderings": { + "N": [ + { + "Format": "x8", + "Rendering": "0000007b" + } + ] + } + } +] + + + {"Timestamp":"2020-06-07T13:44:57.8532799+10:00","Level":"Information","MessageTemplate":"Hello, {@User}, {N:x8} at {Now}","Properties":{"User":{"Name":"nblumhardt","Tags":[1,2,3]},"N":123,"Now":"2016-06-07T13:44:57.8532799+10:00"},"Renderings":{"N":[{"Format":"x8","Rendering":"0000007b"}]}} +{"Timestamp":"2016-06-07T13:44:57.8532799+10:00","Level":"Information","MessageTemplate":"Hello, {@User}, {N:x8} at {Now}","Properties":{"User":{"Name":"Lior","Tags":[1,2,3]},"N":123,"Now":"2016-06-07T13:44:57.8532799+10:00"},"Renderings":{"N":[{"Format":"x8","Rendering":"0000007b"}]}} + ..\Resources\Serilog_icon.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/Analogy.LogViewer.Serilog/Regex/RegexParser.cs b/Analogy.LogViewer.Serilog/Regex/RegexParser.cs deleted file mode 100644 index ff0745a..0000000 --- a/Analogy.LogViewer.Serilog/Regex/RegexParser.cs +++ /dev/null @@ -1,405 +0,0 @@ -using Analogy.Interfaces; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; - -namespace Analogy.LogViewer.Serilog.Regex -{ - public class RegexParser - { - private AnalogyLogMessage _current; - private RegexPattern _lastUsedPattern; - private readonly List _messages = new List(); - private List _logPatterns; - private readonly bool updateUIAfterEachParsedLine; - private IAnalogyLogger Logger { get; } - - private IEnumerable LogPatterns - { - get - { - if (_lastUsedPattern != null) - yield return _lastUsedPattern; - var oldLastUsedPattern = _lastUsedPattern; - foreach (var logPattern in _logPatterns) - { - //skip last used pattern (returned first) - if (oldLastUsedPattern == logPattern) continue; - _lastUsedPattern = logPattern; - yield return _lastUsedPattern; - } - } - } - - public static IEnumerable RegexMembers { get; } - private static Dictionary regexMapper; - - static RegexParser() - { - var names = Enum.GetNames(typeof(AnalogyLogMessagePropertyName)); - RegexMembers = names; - regexMapper = new Dictionary(names.Length); - foreach (var name in names) - { - var enumValue = (AnalogyLogMessagePropertyName)Enum.Parse(typeof(AnalogyLogMessagePropertyName), name); - regexMapper.Add(name, enumValue); - } - } - - public RegexParser(List logPatterns, bool updateUIAfterEachLine, IAnalogyLogger logger) - { - _logPatterns = logPatterns; - Logger = logger; - updateUIAfterEachParsedLine = updateUIAfterEachLine; - - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryParse(string line, RegexPattern regex, out AnalogyLogMessage message) - { - try - { - Match match = System.Text.RegularExpressions.Regex.Match(line, regex.Pattern, - RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace); - if (match.Success) - { - var m = new AnalogyLogMessage(); - foreach (var regexMember in regexMapper) - { - string value = match.Groups[regexMember.Key].Success - ? match.Groups[regexMember.Key].Value - : string.Empty; - switch (regexMember.Value) - { - case AnalogyLogMessagePropertyName.Date: - if (!string.IsNullOrEmpty(value) && - DateTime.TryParseExact(value, regex.DateTimeFormat, CultureInfo.InvariantCulture, - DateTimeStyles.None, out var date)) - { - m.Date = date; - } - - continue; - case AnalogyLogMessagePropertyName.Id: - if (!string.IsNullOrEmpty(value) && - Guid.TryParseExact(value, regex.GuidFormat, out var guidValue)) - { - m.Id = guidValue; - } - - continue; - case AnalogyLogMessagePropertyName.Text: - m.Text = value; - continue; - case AnalogyLogMessagePropertyName.Category: - m.Category = value; - continue; - case AnalogyLogMessagePropertyName.Source: - m.Source = value; - continue; - case AnalogyLogMessagePropertyName.MachineName: - m.MachineName = value; - continue; - case AnalogyLogMessagePropertyName.Module: - m.Module = value; - continue; - case AnalogyLogMessagePropertyName.MethodName: - m.MethodName = value; - continue; - case AnalogyLogMessagePropertyName.FileName: - m.FileName = value; - continue; - case AnalogyLogMessagePropertyName.User: - m.User = value; - continue; - case AnalogyLogMessagePropertyName.LineNumber: - if (!string.IsNullOrEmpty(value) && - int.TryParse(value, out var lineNum)) - { - m.LineNumber = lineNum; - } - - continue; - case AnalogyLogMessagePropertyName.ProcessId: - if (!string.IsNullOrEmpty(value) && - int.TryParse(value, out var processNum)) - { - m.ProcessId = processNum; - } - - continue; - case AnalogyLogMessagePropertyName.ThreadId: - if (!string.IsNullOrEmpty(value) && - int.TryParse(value, out var threadNum)) - { - m.ThreadId = threadNum; - } - - continue; - case AnalogyLogMessagePropertyName.Level: - switch (value) - { - case "OFF": - m.Level = AnalogyLogLevel.None; - break; - case "TRACE": - m.Level = AnalogyLogLevel.Trace; - break; - case "DEBUG": - m.Level = AnalogyLogLevel.Debug; - break; - case "INFO": - m.Level = AnalogyLogLevel.Information; - break; - case "WARN": - m.Level = AnalogyLogLevel.Warning; - break; - case "ERROR": - m.Level = AnalogyLogLevel.Error; - break; - case "FATAL": - m.Level = AnalogyLogLevel.Critical; - break; - default: - m.Level = AnalogyLogLevel.Unknown; - break; - } - - continue; - case AnalogyLogMessagePropertyName.Class: - if (string.IsNullOrEmpty(value)) - m.Class = AnalogyLogClass.General; - else - { - m.Class = Enum.TryParse(value, true, out AnalogyLogClass cls) && - Enum.IsDefined(typeof(AnalogyLogClass), cls) - ? cls - : AnalogyLogClass.General; - - } - - continue; - default: - throw new ArgumentOutOfRangeException(); - } - } - - message = m; - return true; - } - - message = null; - return false; - } - catch (Exception e) - { - string error = $"Error parsing line: {e.Message}"; - Logger?.LogException(error,e, nameof(RegexParser)); - message = new AnalogyLogMessage(error, AnalogyLogLevel.Error, AnalogyLogClass.General, - nameof(RegexParser)); - return false; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool CheckRegex(string line, RegexPattern regex, out AnalogyLogMessage message) - { - try - { - Match match = System.Text.RegularExpressions.Regex.Match(line, regex.Pattern, - RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace); - if (match.Success) - { - var m = new AnalogyLogMessage(); - foreach (var regexMember in regexMapper) - { - string value = match.Groups[regexMember.Key].Success - ? match.Groups[regexMember.Key].Value - : string.Empty; - switch (regexMember.Value) - { - case AnalogyLogMessagePropertyName.Date: - if (!string.IsNullOrEmpty(value) && - DateTime.TryParseExact(value, regex.DateTimeFormat, CultureInfo.InvariantCulture, - DateTimeStyles.None, out var date)) - { - m.Date = date; - } - - break; - case AnalogyLogMessagePropertyName.Id: - if (!string.IsNullOrEmpty(value) && - Guid.TryParseExact(value, regex.GuidFormat, out var guidValue)) - { - m.Id = guidValue; - } - - break; - case AnalogyLogMessagePropertyName.Text: - m.Text = value; - break; - case AnalogyLogMessagePropertyName.Category: - m.Category = value; - break; - case AnalogyLogMessagePropertyName.Source: - m.Source = value; - break; - case AnalogyLogMessagePropertyName.Module: - m.Module = value; - break; - case AnalogyLogMessagePropertyName.MethodName: - m.MethodName = value; - break; - case AnalogyLogMessagePropertyName.FileName: - m.FileName = value; - break; - case AnalogyLogMessagePropertyName.User: - m.User = value; - break; - case AnalogyLogMessagePropertyName.LineNumber: - if (!string.IsNullOrEmpty(value) && - int.TryParse(value, out var lineNum)) - { - m.LineNumber = lineNum; - } - - break; - case AnalogyLogMessagePropertyName.ProcessId: - if (!string.IsNullOrEmpty(value) && - int.TryParse(value, out var processNum)) - { - m.ProcessId = processNum; - } - - break; - case AnalogyLogMessagePropertyName.ThreadId: - if (!string.IsNullOrEmpty(value) && - int.TryParse(value, out var threadNum)) - { - m.ThreadId = threadNum; - } - - break; - case AnalogyLogMessagePropertyName.Level: - switch (value) - { - case "OFF": - m.Level = AnalogyLogLevel.None; - break; - case "TRACE": - m.Level = AnalogyLogLevel.Trace; - break; - case "DEBUG": - m.Level = AnalogyLogLevel.Debug; - break; - case "INFO": - m.Level = AnalogyLogLevel.Information; - break; - case "WARN": - m.Level = AnalogyLogLevel.Warning; - break; - case "ERROR": - m.Level = AnalogyLogLevel.Error; - break; - case "FATAL": - m.Level = AnalogyLogLevel.Critical; - break; - default: - m.Level = AnalogyLogLevel.Unknown; - break; - } - - break; - case AnalogyLogMessagePropertyName.Class: - if (string.IsNullOrEmpty(value)) - m.Class = AnalogyLogClass.General; - else - { - m.Class = Enum.TryParse(value, true, out AnalogyLogClass cls) && - Enum.IsDefined(typeof(AnalogyLogClass), cls) - ? cls - : AnalogyLogClass.General; - - } - - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - message = m; - return true; - } - - message = null; - return false; - } - catch (Exception e) - { - string error = $"Error parsing line: {e.Message}"; - message = new AnalogyLogMessage(error, AnalogyLogLevel.Error, AnalogyLogClass.General, - nameof(RegexParser)); - return false; - } - } - - public async Task> ParseLog(string fileName, CancellationToken token, - ILogMessageCreatedHandler messagesHandler) - { - _messages.Clear(); - using (StreamReader reader = File.OpenText(fileName)) - { - string line; - while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null) - { - AnalogyLogMessage entry = null; - foreach (var logPattern in LogPatterns) - { - if (TryParse(line, logPattern, out entry)) - { - break; - } - } - - if (entry != null) - { - if (updateUIAfterEachParsedLine) - messagesHandler.AppendMessage(entry, fileName); - _current = entry; - _messages.Add(_current); - } - else - { - if (_current == null) - { - _current = new AnalogyLogMessage { Text = line }; - } - else - { - _current.Text += Environment.NewLine + line; - } - } - - if (token.IsCancellationRequested) - { - messagesHandler.AppendMessages(_messages, fileName); - return _messages; - } - } - } - - if (!updateUIAfterEachParsedLine) //update only at the end - messagesHandler.AppendMessages(_messages, fileName); - return _messages; - } - - public void SetRegexPatterns(List patterns) => _logPatterns = patterns; - } -} diff --git a/Analogy.LogViewer.Serilog/Regex/RegexPattern.cs b/Analogy.LogViewer.Serilog/Regex/RegexPattern.cs deleted file mode 100644 index 7c807d2..0000000 --- a/Analogy.LogViewer.Serilog/Regex/RegexPattern.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace Analogy.LogViewer.Serilog.Regex -{ - [Serializable] - public class RegexPattern - { - public string Pattern { get; set; } - public string DateTimeFormat { get; set; } - public string GuidFormat { get; set; } - public bool IsSet => !string.IsNullOrEmpty(Pattern) && !string.IsNullOrEmpty(DateTimeFormat); - public RegexPattern() - { - Pattern = string.Empty; - DateTimeFormat = "yyyy-MM-dd HH:mm:ss,fff"; - GuidFormat = string.Empty; - - } - public RegexPattern(string pattern, string dateTimeFormat, string guidFormat) - { - Pattern = pattern; - DateTimeFormat = dateTimeFormat; - GuidFormat = guidFormat; - } - - public override string ToString() => $"Pattern: {Pattern}, DateTimeFormat: {DateTimeFormat}, GuidFormat: {GuidFormat}"; - } -} diff --git a/Analogy.LogViewer.Serilog/SerilogSettings.cs b/Analogy.LogViewer.Serilog/SerilogSettings.cs index f16502a..33b3893 100644 --- a/Analogy.LogViewer.Serilog/SerilogSettings.cs +++ b/Analogy.LogViewer.Serilog/SerilogSettings.cs @@ -1,15 +1,10 @@ -using Analogy.LogViewer.Serilog.Regex; +using Analogy.LogViewer.RegexParser; +using Analogy.LogViewer.Serilog.DataTypes; using System.Collections.Generic; namespace Analogy.LogViewer.Serilog { - public enum SerilogFileFormat - { - CLEF, - JSONPerLine, - JSONFile, - REGEX - } + public class SerilogSettings { public string FileOpenDialogFilters { get; set; } @@ -17,18 +12,20 @@ public class SerilogSettings public List SupportFormats { get; set; } public List RegexPatterns { get; set; } public string Directory { get; set; } - public SerilogFileFormat Format { get; set; } + public FileFormat Format { get; set; } + public FileFormatDetection FileFormatDetection { get; set; } public List IgnoredAttributes { get; set; } public SerilogSettings() { - Format = SerilogFileFormat.CLEF; + FileFormatDetection = FileFormatDetection.Automatic; + Format = FileFormat.Unknown; Directory = string.Empty; IgnoredAttributes = new List() { "N" }; FileOpenDialogFilters = "All Supported formats (*.Clef;*.log;*.gz)|*.clef;*.log;*.gz|Clef format (*.clef)|*.clef|Plain log text file (*.log)|*.log|GZIP file (*.gz)|*.gz"; SupportFormats = new List { "*.Clef", "*.log", "*.gz" }; RegexPatterns = new List(); - RegexPatterns.Add(new RegexPattern(@"\$(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2},\d{3})+\|+(?\d+)+\|(?\w+)+\|+(?.*)\|(?.*)", "yyyy-MM-dd HH:mm:ss,fff", "")); + // RegexPatterns.Add(new RegexPattern(@"\$(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2},\d{3})+\|+(?\d+)+\|(?\w+)+\|+(?.*)\|(?.*)", "yyyy-MM-dd HH:mm:ss,fff", "")); } diff --git a/Analogy.LogViewer.Serilog/SerilogUCSettings.Designer.cs b/Analogy.LogViewer.Serilog/SerilogUCSettings.Designer.cs index 3cebf22..13d1f6b 100644 --- a/Analogy.LogViewer.Serilog/SerilogUCSettings.Designer.cs +++ b/Analogy.LogViewer.Serilog/SerilogUCSettings.Designer.cs @@ -30,7 +30,6 @@ private void InitializeComponent() { this.btnSave = new System.Windows.Forms.Button(); this.btnExportSettings = new System.Windows.Forms.Button(); - this.lblLayout = new System.Windows.Forms.Label(); this.txtbSupportedFiles = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.btnImport = new System.Windows.Forms.Button(); @@ -38,30 +37,19 @@ private void InitializeComponent() this.label3 = new System.Windows.Forms.Label(); this.btnOpenFolder = new System.Windows.Forms.Button(); this.rbtnCLEF = new System.Windows.Forms.RadioButton(); - this.rbJson = new System.Windows.Forms.RadioButton(); - this.rbRegexFile = new System.Windows.Forms.RadioButton(); - this.tcSetttings = new System.Windows.Forms.TabControl(); - this.tabPage2 = new System.Windows.Forms.TabPage(); - this.txtbGuidFormat = new System.Windows.Forms.TextBox(); - this.label1 = new System.Windows.Forms.Label(); - this.btnDelete = new System.Windows.Forms.Button(); - this.btnAdd = new System.Windows.Forms.Button(); - this.lstbRegularExpressions = new System.Windows.Forms.ListBox(); - this.gbresult = new System.Windows.Forms.GroupBox(); - this.lblResultMessage = new System.Windows.Forms.Label(); - this.lblResult = new System.Windows.Forms.Label(); - this.txtbTest = new System.Windows.Forms.TextBox(); - this.lblLogTest = new System.Windows.Forms.Label(); - this.txtbDateTimeFormat = new System.Windows.Forms.TextBox(); - this.txtbRegEx = new System.Windows.Forms.TextBox(); - this.lblDateTimeFormat = new System.Windows.Forms.Label(); - this.lblRegex = new System.Windows.Forms.Label(); - this.btnTest = new System.Windows.Forms.Button(); + this.rbtnJsonPerLine = new System.Windows.Forms.RadioButton(); this.txtbOpenFileFilters = new System.Windows.Forms.TextBox(); this.lblOpenfilesFilters = new System.Windows.Forms.Label(); this.btnTestFilter = new System.Windows.Forms.Button(); this.tabControlMain = new System.Windows.Forms.TabControl(); this.tabPage1 = new System.Windows.Forms.TabPage(); + this.rbDetectionModeManual = new System.Windows.Forms.RadioButton(); + this.rbDetectionModeAutomatic = new System.Windows.Forms.RadioButton(); + this.label1 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rbtnJsonFile = new System.Windows.Forms.RadioButton(); + this.rtxtExample = new System.Windows.Forms.RichTextBox(); + this.rbtnCompactJsonFile = new System.Windows.Forms.RadioButton(); this.tabPage3 = new System.Windows.Forms.TabPage(); this.txtbIgnoreColumn = new System.Windows.Forms.TextBox(); this.label4 = new System.Windows.Forms.Label(); @@ -69,12 +57,10 @@ private void InitializeComponent() this.btnIgnoreColumn = new System.Windows.Forms.Button(); this.lstbIgnoreColumn = new System.Windows.Forms.ListBox(); this.panel1 = new System.Windows.Forms.Panel(); - this.rbJsonFile = new System.Windows.Forms.RadioButton(); - this.tcSetttings.SuspendLayout(); - this.tabPage2.SuspendLayout(); - this.gbresult.SuspendLayout(); + this.rbtnReset = new System.Windows.Forms.RadioButton(); this.tabControlMain.SuspendLayout(); this.tabPage1.SuspendLayout(); + this.groupBox1.SuspendLayout(); this.tabPage3.SuspendLayout(); this.panel1.SuspendLayout(); this.SuspendLayout(); @@ -101,31 +87,22 @@ private void InitializeComponent() this.btnExportSettings.UseVisualStyleBackColor = true; this.btnExportSettings.Click += new System.EventHandler(this.btnExportSettings_Click); // - // lblLayout - // - this.lblLayout.AutoSize = true; - this.lblLayout.Location = new System.Drawing.Point(9, 12); - this.lblLayout.Name = "lblLayout"; - this.lblLayout.Size = new System.Drawing.Size(60, 18); - this.lblLayout.TabIndex = 3; - this.lblLayout.Text = "Format:"; - // // txtbSupportedFiles // this.txtbSupportedFiles.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.txtbSupportedFiles.Location = new System.Drawing.Point(198, 183); + this.txtbSupportedFiles.Location = new System.Drawing.Point(276, 75); this.txtbSupportedFiles.Name = "txtbSupportedFiles"; - this.txtbSupportedFiles.Size = new System.Drawing.Size(515, 26); + this.txtbSupportedFiles.Size = new System.Drawing.Size(437, 26); this.txtbSupportedFiles.TabIndex = 9; this.txtbSupportedFiles.Text = "*.Clef"; // // label2 // this.label2.AutoEllipsis = true; - this.label2.Location = new System.Drawing.Point(9, 182); + this.label2.Location = new System.Drawing.Point(9, 75); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(188, 50); + this.label2.Size = new System.Drawing.Size(261, 50); this.label2.TabIndex = 8; this.label2.Text = "Supported Log Formats (use ; as separator):"; // @@ -144,15 +121,15 @@ private void InitializeComponent() // this.txtbDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.txtbDirectory.Location = new System.Drawing.Point(198, 128); + this.txtbDirectory.Location = new System.Drawing.Point(276, 11); this.txtbDirectory.Name = "txtbDirectory"; - this.txtbDirectory.Size = new System.Drawing.Size(454, 26); + this.txtbDirectory.Size = new System.Drawing.Size(376, 26); this.txtbDirectory.TabIndex = 12; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(9, 128); + this.label3.Location = new System.Drawing.Point(9, 15); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(152, 18); this.label3.TabIndex = 11; @@ -161,9 +138,9 @@ private void InitializeComponent() // btnOpenFolder // this.btnOpenFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnOpenFolder.Location = new System.Drawing.Point(666, 128); + this.btnOpenFolder.Location = new System.Drawing.Point(666, 6); this.btnOpenFolder.Name = "btnOpenFolder"; - this.btnOpenFolder.Size = new System.Drawing.Size(47, 22); + this.btnOpenFolder.Size = new System.Drawing.Size(47, 31); this.btnOpenFolder.TabIndex = 13; this.btnOpenFolder.Text = "..."; this.btnOpenFolder.UseVisualStyleBackColor = true; @@ -173,244 +150,45 @@ private void InitializeComponent() // this.rbtnCLEF.AutoSize = true; this.rbtnCLEF.Checked = true; - this.rbtnCLEF.Location = new System.Drawing.Point(93, 9); + this.rbtnCLEF.Location = new System.Drawing.Point(6, 25); this.rbtnCLEF.Name = "rbtnCLEF"; - this.rbtnCLEF.Size = new System.Drawing.Size(231, 22); + this.rbtnCLEF.Size = new System.Drawing.Size(219, 22); this.rbtnCLEF.TabIndex = 14; - this.rbtnCLEF.TabStop = true; - this.rbtnCLEF.Text = "Compact Log Event File (CLEF)"; + this.rbtnCLEF.Text = "Compact Format Per line/row"; this.rbtnCLEF.UseVisualStyleBackColor = true; // - // rbJson - // - this.rbJson.AutoSize = true; - this.rbJson.Location = new System.Drawing.Point(93, 57); - this.rbJson.Name = "rbJson"; - this.rbJson.Size = new System.Drawing.Size(252, 22); - this.rbJson.TabIndex = 15; - this.rbJson.Text = "Json Log Event File (Json Per Life)"; - this.rbJson.UseVisualStyleBackColor = true; - // - // rbRegexFile - // - this.rbRegexFile.AutoSize = true; - this.rbRegexFile.Location = new System.Drawing.Point(93, 33); - this.rbRegexFile.Name = "rbRegexFile"; - this.rbRegexFile.Size = new System.Drawing.Size(289, 22); - this.rbRegexFile.TabIndex = 16; - this.rbRegexFile.Text = "Text file - use regular expression parser"; - this.rbRegexFile.UseVisualStyleBackColor = true; - // - // tcSetttings - // - this.tcSetttings.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.tcSetttings.Controls.Add(this.tabPage2); - this.tcSetttings.Location = new System.Drawing.Point(11, 223); - this.tcSetttings.Name = "tcSetttings"; - this.tcSetttings.SelectedIndex = 0; - this.tcSetttings.Size = new System.Drawing.Size(696, 319); - this.tcSetttings.TabIndex = 45; - // - // tabPage2 - // - this.tabPage2.Controls.Add(this.txtbGuidFormat); - this.tabPage2.Controls.Add(this.label1); - this.tabPage2.Controls.Add(this.btnDelete); - this.tabPage2.Controls.Add(this.btnAdd); - this.tabPage2.Controls.Add(this.lstbRegularExpressions); - this.tabPage2.Controls.Add(this.gbresult); - this.tabPage2.Controls.Add(this.txtbTest); - this.tabPage2.Controls.Add(this.lblLogTest); - this.tabPage2.Controls.Add(this.txtbDateTimeFormat); - this.tabPage2.Controls.Add(this.txtbRegEx); - this.tabPage2.Controls.Add(this.lblDateTimeFormat); - this.tabPage2.Controls.Add(this.lblRegex); - this.tabPage2.Controls.Add(this.btnTest); - this.tabPage2.Location = new System.Drawing.Point(4, 27); - this.tabPage2.Name = "tabPage2"; - this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(688, 288); - this.tabPage2.TabIndex = 1; - this.tabPage2.Text = "Text file - Regular Expression Parser"; - this.tabPage2.UseVisualStyleBackColor = true; - // - // txtbGuidFormat - // - this.txtbGuidFormat.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.txtbGuidFormat.Location = new System.Drawing.Point(258, 58); - this.txtbGuidFormat.Name = "txtbGuidFormat"; - this.txtbGuidFormat.Size = new System.Drawing.Size(360, 26); - this.txtbGuidFormat.TabIndex = 58; - // - // label1 - // - this.label1.AccessibleDescription = ""; - this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.label1.AutoEllipsis = true; - this.label1.Location = new System.Drawing.Point(6, 58); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(236, 47); - this.label1.TabIndex = 57; - this.label1.Text = "Guid Format (The format parameter can be \"N\", \"D\", \"B\", \"P\", or \"X\". If format is" + - " null or an empty string (\"\"), \"D\" is used):"; - // - // btnDelete - // - this.btnDelete.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnDelete.Location = new System.Drawing.Point(592, 167); - this.btnDelete.Name = "btnDelete"; - this.btnDelete.Size = new System.Drawing.Size(93, 25); - this.btnDelete.TabIndex = 56; - this.btnDelete.Text = "Delete"; - this.btnDelete.UseVisualStyleBackColor = true; - this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click); - // - // btnAdd - // - this.btnAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnAdd.Location = new System.Drawing.Point(635, 56); - this.btnAdd.Name = "btnAdd"; - this.btnAdd.Size = new System.Drawing.Size(47, 25); - this.btnAdd.TabIndex = 55; - this.btnAdd.Text = "Add"; - this.btnAdd.UseVisualStyleBackColor = true; - this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); - // - // lstbRegularExpressions - // - this.lstbRegularExpressions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.lstbRegularExpressions.FormattingEnabled = true; - this.lstbRegularExpressions.ItemHeight = 18; - this.lstbRegularExpressions.Location = new System.Drawing.Point(9, 113); - this.lstbRegularExpressions.Name = "lstbRegularExpressions"; - this.lstbRegularExpressions.Size = new System.Drawing.Size(571, 130); - this.lstbRegularExpressions.TabIndex = 54; - // - // gbresult - // - this.gbresult.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.gbresult.Controls.Add(this.lblResultMessage); - this.gbresult.Controls.Add(this.lblResult); - this.gbresult.Location = new System.Drawing.Point(9, 294); - this.gbresult.Name = "gbresult"; - this.gbresult.Size = new System.Drawing.Size(571, 4); - this.gbresult.TabIndex = 52; - this.gbresult.TabStop = false; - this.gbresult.Text = "Result"; - // - // lblResultMessage - // - this.lblResultMessage.Dock = System.Windows.Forms.DockStyle.Fill; - this.lblResultMessage.Location = new System.Drawing.Point(3, 41); - this.lblResultMessage.Name = "lblResultMessage"; - this.lblResultMessage.Size = new System.Drawing.Size(565, 0); - this.lblResultMessage.TabIndex = 31; - // - // lblResult - // - this.lblResult.Dock = System.Windows.Forms.DockStyle.Top; - this.lblResult.Location = new System.Drawing.Point(3, 22); - this.lblResult.Name = "lblResult"; - this.lblResult.Size = new System.Drawing.Size(565, 19); - this.lblResult.TabIndex = 30; - // - // txtbTest - // - this.txtbTest.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.txtbTest.Location = new System.Drawing.Point(119, 266); - this.txtbTest.Name = "txtbTest"; - this.txtbTest.Size = new System.Drawing.Size(461, 26); - this.txtbTest.TabIndex = 51; - // - // lblLogTest + // rbtnJsonPerLine // - this.lblLogTest.AccessibleDescription = ""; - this.lblLogTest.AutoSize = true; - this.lblLogTest.Location = new System.Drawing.Point(6, 269); - this.lblLogTest.Name = "lblLogTest"; - this.lblLogTest.Size = new System.Drawing.Size(109, 18); - this.lblLogTest.TabIndex = 50; - this.lblLogTest.Text = "Log line to test:"; - // - // txtbDateTimeFormat - // - this.txtbDateTimeFormat.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.txtbDateTimeFormat.Location = new System.Drawing.Point(188, 29); - this.txtbDateTimeFormat.Name = "txtbDateTimeFormat"; - this.txtbDateTimeFormat.Size = new System.Drawing.Size(494, 26); - this.txtbDateTimeFormat.TabIndex = 48; - this.txtbDateTimeFormat.Text = "yyyy-MM-dd HH:mm:ss,fff"; - // - // txtbRegEx - // - this.txtbRegEx.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.txtbRegEx.Location = new System.Drawing.Point(188, 6); - this.txtbRegEx.Name = "txtbRegEx"; - this.txtbRegEx.Size = new System.Drawing.Size(494, 26); - this.txtbRegEx.TabIndex = 49; - // - // lblDateTimeFormat - // - this.lblDateTimeFormat.AccessibleDescription = ""; - this.lblDateTimeFormat.AutoSize = true; - this.lblDateTimeFormat.Location = new System.Drawing.Point(6, 37); - this.lblDateTimeFormat.Name = "lblDateTimeFormat"; - this.lblDateTimeFormat.Size = new System.Drawing.Size(149, 18); - this.lblDateTimeFormat.TabIndex = 46; - this.lblDateTimeFormat.Text = "DateTime log format:"; - // - // lblRegex - // - this.lblRegex.AccessibleDescription = ""; - this.lblRegex.AutoSize = true; - this.lblRegex.Location = new System.Drawing.Point(6, 10); - this.lblRegex.Name = "lblRegex"; - this.lblRegex.Size = new System.Drawing.Size(163, 18); - this.lblRegex.TabIndex = 47; - this.lblRegex.Text = "Log Regular Expression:"; - // - // btnTest - // - this.btnTest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnTest.Location = new System.Drawing.Point(635, 266); - this.btnTest.Name = "btnTest"; - this.btnTest.Size = new System.Drawing.Size(47, 25); - this.btnTest.TabIndex = 44; - this.btnTest.Text = "Test"; - this.btnTest.UseVisualStyleBackColor = true; - this.btnTest.Click += new System.EventHandler(this.btnTest_Click); + this.rbtnJsonPerLine.AutoSize = true; + this.rbtnJsonPerLine.Location = new System.Drawing.Point(6, 50); + this.rbtnJsonPerLine.Name = "rbtnJsonPerLine"; + this.rbtnJsonPerLine.Size = new System.Drawing.Size(250, 22); + this.rbtnJsonPerLine.TabIndex = 15; + this.rbtnJsonPerLine.Text = "Standard Json format per line/row"; + this.rbtnJsonPerLine.UseVisualStyleBackColor = true; // // txtbOpenFileFilters // this.txtbOpenFileFilters.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.txtbOpenFileFilters.Location = new System.Drawing.Point(198, 155); + this.txtbOpenFileFilters.Location = new System.Drawing.Point(276, 43); this.txtbOpenFileFilters.Name = "txtbOpenFileFilters"; - this.txtbOpenFileFilters.Size = new System.Drawing.Size(454, 26); + this.txtbOpenFileFilters.Size = new System.Drawing.Size(376, 26); this.txtbOpenFileFilters.TabIndex = 47; // // lblOpenfilesFilters // this.lblOpenfilesFilters.AutoEllipsis = true; - this.lblOpenfilesFilters.Location = new System.Drawing.Point(13, 153); + this.lblOpenfilesFilters.Location = new System.Drawing.Point(13, 43); this.lblOpenfilesFilters.Name = "lblOpenfilesFilters"; - this.lblOpenfilesFilters.Size = new System.Drawing.Size(184, 22); + this.lblOpenfilesFilters.Size = new System.Drawing.Size(148, 22); this.lblOpenfilesFilters.TabIndex = 46; this.lblOpenfilesFilters.Text = "Open file Filter:"; // // btnTestFilter // this.btnTestFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnTestFilter.Location = new System.Drawing.Point(666, 155); + this.btnTestFilter.Location = new System.Drawing.Point(666, 43); this.btnTestFilter.Name = "btnTestFilter"; this.btnTestFilter.Size = new System.Drawing.Size(47, 25); this.btnTestFilter.TabIndex = 48; @@ -431,18 +209,16 @@ private void InitializeComponent() // // tabPage1 // - this.tabPage1.Controls.Add(this.rbJsonFile); - this.tabPage1.Controls.Add(this.lblLayout); + this.tabPage1.Controls.Add(this.rbDetectionModeManual); + this.tabPage1.Controls.Add(this.rbDetectionModeAutomatic); + this.tabPage1.Controls.Add(this.label1); + this.tabPage1.Controls.Add(this.groupBox1); this.tabPage1.Controls.Add(this.btnTestFilter); - this.tabPage1.Controls.Add(this.rbtnCLEF); this.tabPage1.Controls.Add(this.txtbOpenFileFilters); - this.tabPage1.Controls.Add(this.rbJson); this.tabPage1.Controls.Add(this.btnOpenFolder); this.tabPage1.Controls.Add(this.lblOpenfilesFilters); this.tabPage1.Controls.Add(this.txtbDirectory); - this.tabPage1.Controls.Add(this.rbRegexFile); this.tabPage1.Controls.Add(this.txtbSupportedFiles); - this.tabPage1.Controls.Add(this.tcSetttings); this.tabPage1.Controls.Add(this.label2); this.tabPage1.Controls.Add(this.label3); this.tabPage1.Location = new System.Drawing.Point(4, 27); @@ -453,6 +229,88 @@ private void InitializeComponent() this.tabPage1.Text = "Settings"; this.tabPage1.UseVisualStyleBackColor = true; // + // rbDetectionModeManual + // + this.rbDetectionModeManual.AutoSize = true; + this.rbDetectionModeManual.Location = new System.Drawing.Point(447, 128); + this.rbDetectionModeManual.Name = "rbDetectionModeManual"; + this.rbDetectionModeManual.Size = new System.Drawing.Size(75, 22); + this.rbDetectionModeManual.TabIndex = 53; + this.rbDetectionModeManual.Text = "Manual"; + this.rbDetectionModeManual.UseVisualStyleBackColor = true; + // + // rbDetectionModeAutomatic + // + this.rbDetectionModeAutomatic.AutoSize = true; + this.rbDetectionModeAutomatic.Checked = true; + this.rbDetectionModeAutomatic.Location = new System.Drawing.Point(276, 128); + this.rbDetectionModeAutomatic.Name = "rbDetectionModeAutomatic"; + this.rbDetectionModeAutomatic.Size = new System.Drawing.Size(94, 22); + this.rbDetectionModeAutomatic.TabIndex = 52; + this.rbDetectionModeAutomatic.TabStop = true; + this.rbDetectionModeAutomatic.Text = "Automatic"; + this.rbDetectionModeAutomatic.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.AutoEllipsis = true; + this.label1.Location = new System.Drawing.Point(13, 128); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(148, 22); + this.label1.TabIndex = 51; + this.label1.Text = "File Detection Mode:"; + // + // groupBox1 + // + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Controls.Add(this.rbtnReset); + this.groupBox1.Controls.Add(this.rbtnJsonFile); + this.groupBox1.Controls.Add(this.rtxtExample); + this.groupBox1.Controls.Add(this.rbtnCLEF); + this.groupBox1.Controls.Add(this.rbtnCompactJsonFile); + this.groupBox1.Controls.Add(this.rbtnJsonPerLine); + this.groupBox1.Location = new System.Drawing.Point(13, 170); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(695, 377); + this.groupBox1.TabIndex = 50; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Format:"; + // + // rbtnJsonFile + // + this.rbtnJsonFile.AutoSize = true; + this.rbtnJsonFile.Location = new System.Drawing.Point(6, 106); + this.rbtnJsonFile.Name = "rbtnJsonFile"; + this.rbtnJsonFile.Size = new System.Drawing.Size(214, 22); + this.rbtnJsonFile.TabIndex = 51; + this.rbtnJsonFile.Text = "Standard format full Json file"; + this.rbtnJsonFile.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.rbtnJsonFile.UseVisualStyleBackColor = true; + // + // rtxtExample + // + this.rtxtExample.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.rtxtExample.Location = new System.Drawing.Point(6, 147); + this.rtxtExample.Name = "rtxtExample"; + this.rtxtExample.Size = new System.Drawing.Size(683, 223); + this.rtxtExample.TabIndex = 50; + this.rtxtExample.Text = ""; + // + // rbtnCompactJsonFile + // + this.rbtnCompactJsonFile.AutoSize = true; + this.rbtnCompactJsonFile.Location = new System.Drawing.Point(6, 78); + this.rbtnCompactJsonFile.Name = "rbtnCompactJsonFile"; + this.rbtnCompactJsonFile.Size = new System.Drawing.Size(214, 22); + this.rbtnCompactJsonFile.TabIndex = 49; + this.rbtnCompactJsonFile.Text = "Compact format full Json file"; + this.rbtnCompactJsonFile.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.rbtnCompactJsonFile.UseVisualStyleBackColor = true; + // // tabPage3 // this.tabPage3.Controls.Add(this.txtbIgnoreColumn); @@ -532,15 +390,16 @@ private void InitializeComponent() this.panel1.Size = new System.Drawing.Size(725, 56); this.panel1.TabIndex = 50; // - // rbJsonFile + // rbtnReset // - this.rbJsonFile.AutoSize = true; - this.rbJsonFile.Location = new System.Drawing.Point(93, 85); - this.rbJsonFile.Name = "rbJsonFile"; - this.rbJsonFile.Size = new System.Drawing.Size(213, 22); - this.rbJsonFile.TabIndex = 49; - this.rbJsonFile.Text = "Json File (Single json object)"; - this.rbJsonFile.UseVisualStyleBackColor = true; + this.rbtnReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.rbtnReset.AutoSize = true; + this.rbtnReset.Location = new System.Drawing.Point(523, 25); + this.rbtnReset.Name = "rbtnReset"; + this.rbtnReset.Size = new System.Drawing.Size(148, 22); + this.rbtnReset.TabIndex = 52; + this.rbtnReset.Text = "Reset to Unknown"; + this.rbtnReset.UseVisualStyleBackColor = true; // // SerilogUCSettings // @@ -552,13 +411,11 @@ private void InitializeComponent() this.Name = "SerilogUCSettings"; this.Size = new System.Drawing.Size(725, 640); this.Load += new System.EventHandler(this.NLogSettings_Load); - this.tcSetttings.ResumeLayout(false); - this.tabPage2.ResumeLayout(false); - this.tabPage2.PerformLayout(); - this.gbresult.ResumeLayout(false); this.tabControlMain.ResumeLayout(false); this.tabPage1.ResumeLayout(false); this.tabPage1.PerformLayout(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); this.tabPage3.ResumeLayout(false); this.tabPage3.PerformLayout(); this.panel1.ResumeLayout(false); @@ -569,7 +426,6 @@ private void InitializeComponent() #endregion private System.Windows.Forms.Button btnSave; private System.Windows.Forms.Button btnExportSettings; - private System.Windows.Forms.Label lblLayout; private System.Windows.Forms.TextBox txtbSupportedFiles; private System.Windows.Forms.Label label2; private System.Windows.Forms.Button btnImport; @@ -577,25 +433,7 @@ private void InitializeComponent() private System.Windows.Forms.Label label3; private System.Windows.Forms.Button btnOpenFolder; private System.Windows.Forms.RadioButton rbtnCLEF; - private System.Windows.Forms.RadioButton rbJson; - private System.Windows.Forms.RadioButton rbRegexFile; - private System.Windows.Forms.TabControl tcSetttings; - private System.Windows.Forms.TabPage tabPage2; - private System.Windows.Forms.TextBox txtbGuidFormat; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Button btnDelete; - private System.Windows.Forms.Button btnAdd; - private System.Windows.Forms.ListBox lstbRegularExpressions; - private System.Windows.Forms.GroupBox gbresult; - private System.Windows.Forms.Label lblResultMessage; - private System.Windows.Forms.Label lblResult; - private System.Windows.Forms.TextBox txtbTest; - private System.Windows.Forms.Label lblLogTest; - private System.Windows.Forms.TextBox txtbDateTimeFormat; - private System.Windows.Forms.TextBox txtbRegEx; - private System.Windows.Forms.Label lblDateTimeFormat; - private System.Windows.Forms.Label lblRegex; - private System.Windows.Forms.Button btnTest; + private System.Windows.Forms.RadioButton rbtnJsonPerLine; private System.Windows.Forms.TextBox txtbOpenFileFilters; private System.Windows.Forms.Label lblOpenfilesFilters; private System.Windows.Forms.Button btnTestFilter; @@ -608,6 +446,13 @@ private void InitializeComponent() private System.Windows.Forms.Button btnDeleteIgnoreColumn; private System.Windows.Forms.Button btnIgnoreColumn; private System.Windows.Forms.ListBox lstbIgnoreColumn; - private System.Windows.Forms.RadioButton rbJsonFile; + private System.Windows.Forms.RadioButton rbtnCompactJsonFile; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RichTextBox rtxtExample; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.RadioButton rbDetectionModeAutomatic; + private System.Windows.Forms.RadioButton rbDetectionModeManual; + private System.Windows.Forms.RadioButton rbtnJsonFile; + private System.Windows.Forms.RadioButton rbtnReset; } } diff --git a/Analogy.LogViewer.Serilog/SerilogUCSettings.cs b/Analogy.LogViewer.Serilog/SerilogUCSettings.cs index e3d9c9d..93f27b3 100644 --- a/Analogy.LogViewer.Serilog/SerilogUCSettings.cs +++ b/Analogy.LogViewer.Serilog/SerilogUCSettings.cs @@ -1,10 +1,9 @@ -using Analogy.Interfaces; +using Analogy.LogViewer.Serilog.DataTypes; using Analogy.LogViewer.Serilog.Managers; -using Analogy.LogViewer.Serilog.Regex; +using Analogy.LogViewer.Serilog.Properties; using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms; @@ -34,16 +33,35 @@ public void SaveSettings() Settings.Directory = txtbDirectory.Text; Settings.FileOpenDialogFilters = txtbOpenFileFilters.Text; Settings.SupportFormats = txtbSupportedFiles.Text.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList(); - Settings.RegexPatterns = lstbRegularExpressions.Items.Count > 0 ? lstbRegularExpressions.Items.Cast().ToList() : new List(); Settings.IgnoredAttributes = lstbIgnoreColumn.Items.Count > 0 ? lstbIgnoreColumn.Items.Cast().ToList() : new List(); - if (rbtnCLEF.Checked) - Settings.Format = SerilogFileFormat.CLEF; - else if (rbJson.Checked) - Settings.Format = SerilogFileFormat.JSONPerLine; - else if (rbRegexFile.Checked) - Settings.Format = SerilogFileFormat.REGEX; - else if (rbJsonFile.Checked) - Settings.Format = SerilogFileFormat.JSONFile; + Settings.FileFormatDetection = rbDetectionModeAutomatic.Checked + ? FileFormatDetection.Automatic + : FileFormatDetection.Manual; + if (rbtnReset.Checked) + { + Settings.Format = FileFormat.Unknown; + rtxtExample.Text = ""; + } + else if (rbtnCLEF.Checked) + { + Settings.Format = FileFormat.CompactJsonFormatPerLine; + rtxtExample.Text = Resources.CompactJsonFormatPerLine; + } + else if (rbtnJsonPerLine.Checked) + { + Settings.Format = FileFormat.JsonFormatPerLine; + rtxtExample.Text = Resources.JsonFormatPerLine; + } + else if (rbtnCompactJsonFile.Checked) + { + Settings.Format = FileFormat.CompactJsonFormatPerFile; + rtxtExample.Text = Resources.CompactJsonFormatPerFile; + } + else if (rbtnJsonFile.Checked) + { + Settings.Format = FileFormat.JsonFormatFile; + rtxtExample.Text = Resources.JsonFormatFile; + } UserSettingsManager.UserSettings.Save(); } @@ -102,14 +120,15 @@ private void LoadSettings(SerilogSettings logSettings) txtbDirectory.Text = logSettings.Directory; txtbOpenFileFilters.Text = logSettings.FileOpenDialogFilters; txtbSupportedFiles.Text = string.Join(";", logSettings.SupportFormats.ToList()); - lstbRegularExpressions.Items.Clear(); - lstbRegularExpressions.Items.AddRange(logSettings.RegexPatterns.ToArray()); lstbIgnoreColumn.Items.Clear(); lstbIgnoreColumn.Items.AddRange(logSettings.IgnoredAttributes.ToArray()); - rbtnCLEF.Checked = logSettings.Format == SerilogFileFormat.CLEF; - rbRegexFile.Checked = logSettings.Format == SerilogFileFormat.REGEX; - rbJson.Checked = logSettings.Format == SerilogFileFormat.JSONPerLine; - rbJsonFile.Checked = logSettings.Format == SerilogFileFormat.JSONFile; + rbtnCLEF.Checked = Settings.Format == FileFormat.CompactJsonFormatPerLine; + rbtnJsonPerLine.Checked = Settings.Format == FileFormat.JsonFormatPerLine; + rbtnCompactJsonFile.Checked = Settings.Format == FileFormat.CompactJsonFormatPerFile; + rbtnJsonFile.Checked = Settings.Format == FileFormat.JsonFormatFile; + rbtnReset.Checked = Settings.Format == FileFormat.Unknown; + rbDetectionModeAutomatic.Checked = Settings.FileFormatDetection == FileFormatDetection.Automatic; + rbDetectionModeManual.Checked = Settings.FileFormatDetection == FileFormatDetection.Manual; } private void btnOpenFolder_Click(object sender, EventArgs e) @@ -130,38 +149,6 @@ private void NLogSettings_Load(object sender, EventArgs e) LoadSettings(UserSettingsManager.UserSettings.Settings); } - private void btnAdd_Click(object sender, EventArgs e) - { - if (string.IsNullOrEmpty(txtbRegEx.Text)) return; - var rp = new RegexPattern(txtbRegEx.Text, txtbDateTimeFormat.Text, txtbGuidFormat.Text); - lstbRegularExpressions.Items.Add(rp); - } - - private void btnDelete_Click(object sender, EventArgs e) - { - if (lstbRegularExpressions.SelectedItem is RegexPattern regexPattern) - { - lstbRegularExpressions.Items.Remove(lstbRegularExpressions.SelectedItem); - } - } - - private void btnTest_Click(object sender, EventArgs e) - { - RegexPattern p = new RegexPattern(txtbRegEx.Text, txtbDateTimeFormat.Text, ""); - bool valid = Regex.RegexParser.CheckRegex(txtbTest.Text, p, out AnalogyLogMessage m); - if (valid) - { - lblResult.Text = "Valid Regular Expression"; - lblResult.BackColor = Color.GreenYellow; - lblResultMessage.Text = m.ToString(); - } - else - { - lblResult.Text = "Non Valid Regular Expression"; - lblResult.BackColor = Color.OrangeRed; - } - } - private void btnTestFilter_Click(object sender, EventArgs e) { try