{"id":4115,"date":"2016-07-09T19:16:08","date_gmt":"2016-07-09T19:16:08","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=4115"},"modified":"2016-07-09T19:16:08","modified_gmt":"2016-07-09T19:16:08","slug":"structured-logging-with-the-semantic-logging-block","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/structured-logging-with-the-semantic-logging-block\/","title":{"rendered":"Structured logging with the Semantic Logging Block"},"content":{"rendered":"<p>In another post I looked at Serilog and what structured logging capabilities can bring to an application, here I&#8217;m going to investigate the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/dn440729(v=pandp.60).aspx\" target=\"_blank\">Patterns &#038; Practices Semantic Logging Application Block<\/a>.<\/p>\n<p>So we&#8217;re looking at a means of logging more than just a &#8220;simple&#8221; string representing our state or failure (or whatever) from our application. Most likely we&#8217;re wanting to output log entries which can be analysed later in a more programmatic manner, i.e. querying or grouping log data.<\/p>\n<p><strong>Getting started<\/strong><\/p>\n<p>Let&#8217;s just get some simple code up and running to see how things fit together.<\/p>\n<ul>\n<li>Create a console application<\/li>\n<li>Using Nuget, add the following EnterpriseLibrary.SemanticLogging package<\/li>\n<li>Add a new class named whatever you want, mine&#8217;s called MyEventSource<\/li>\n<\/ul>\n<p>The MyEventSource class looks like this<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n&#x5B;EventSource(Name = &quot;MyEventSource&quot;)]\r\npublic class MyEventSource : EventSource\r\n{\r\n   public static MyEventSource Log { get; } = new MyEventSource();\r\n\r\n   &#x5B;Event(1, Message = &quot;Application Failure: {0}&quot;, \r\n    Level = EventLevel.Informational,\r\n    Keywords = EventKeywords.None)]\r\n   public void Information(string message)\r\n   {\r\n      WriteEvent(1, message);\r\n   }\r\n}\r\n<\/pre>\n<p>Next up, let&#8217;s implement some simple logging code in our Main method<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar eventSource = MyEventSource.Log;\r\nvar listener = ConsoleLog.CreateListener(\r\n   new JsonEventTextFormatter(EventTextFormatting.Indented));\r\n\r\nlistener.EnableEvents(eventSource, \r\n   EventLevel.LogAlways, \r\n   EventKeywords.All);\r\n\r\neventSource.Information(&quot;Application Started&quot;);\r\n\r\n\/\/ do something worthwhile \r\n\r\neventSource.Information(&quot;Existing Application&quot;);\r\n<\/pre>\n<p>In the example code we&#8217;re logging to the console and using the JsonEventTextFormatter, so the output looks like this<\/p>\n<p>{<br \/>\n  &quot;ProviderId&quot;: &quot;8983a2e6-c5d2-5a1f-691f-db243cb1f681&quot;,<br \/>\n  &quot;EventId&quot;: 1,<br \/>\n  &quot;Keywords&quot;: 0,<br \/>\n  &quot;Level&quot;: 4,<br \/>\n  &quot;Message&quot;: &quot;Application Failure: Application Started&quot;,<br \/>\n  &quot;Opcode&quot;: 0,<br \/>\n  &quot;Task&quot;: 65533,<br \/>\n  &quot;Version&quot;: 0,<br \/>\n  &quot;Payload&quot;: {<br \/>\n    &quot;message&quot;: &quot;Application Started&quot;<br \/>\n  },<br \/>\n  &quot;EventName&quot;: &quot;InformationInfo&quot;,<br \/>\n  &quot;Timestamp&quot;: &quot;2016-07-08T10:19:22.8698814Z&quot;,<br \/>\n  &quot;ProcessId&quot;: 20136,<br \/>\n  &quot;ThreadId&quot;: 19128<br \/>\n},<br \/>\n{<br \/>\n  &quot;ProviderId&quot;: &quot;8983a2e6-c5d2-5a1f-691f-db243cb1f681&quot;,<br \/>\n  &quot;EventId&quot;: 1,<br \/>\n  &quot;Keywords&quot;: 0,<br \/>\n  &quot;Level&quot;: 4,<br \/>\n  &quot;Message&quot;: &quot;Application Failure: Existing Application&quot;,<br \/>\n  &quot;Opcode&quot;: 0,<br \/>\n  &quot;Task&quot;: 65533,<br \/>\n  &quot;Version&quot;: 0,<br \/>\n  &quot;Payload&quot;: {<br \/>\n    &quot;message&quot;: &quot;Existing Application&quot;<br \/>\n  },<br \/>\n  &quot;EventName&quot;: &quot;InformationInfo&quot;,<br \/>\n  &quot;Timestamp&quot;: &quot;2016-07-08T10:19:22.9648909Z&quot;,<br \/>\n  &quot;ProcessId&quot;: 20136,<br \/>\n  &quot;ThreadId&quot;: 19128<br \/>\n},<\/p>\n<p>Let&#8217;s now add a rolling file listener to our Main method<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar rollingFileListener =\r\n   RollingFlatFileLog.CreateListener(\r\n      &quot;logs\\\\semantic.txt&quot;, 1073741824,\r\n      &quot;yyyy.MM.dd&quot;,\r\n      RollFileExistsBehavior.Increment, \r\n      RollInterval.Day,\r\n      new JsonEventTextFormatter(EventTextFormatting.Indented));\r\n\r\nrollingFileListener.EnableEvents(\r\n   eventSource, \r\n   EventLevel.LogAlways, \r\n   EventKeywords.All);\r\n<\/pre>\n<p>So we simply attach another listener to our event source and now we are logging to both the console and a file (ofcourse in a non-sample application we would not be creating multiple JsoEventTextFormatters etc. but you get the idea).<\/p>\n<p>That&#8217;s basically it &#8211; we&#8217;re up and running.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In another post I looked at Serilog and what structured logging capabilities can bring to an application, here I&#8217;m going to investigate the Patterns &#038; Practices Semantic Logging Application Block. So we&#8217;re looking at a means of logging more than just a &#8220;simple&#8221; string representing our state or failure (or whatever) from our application. Most [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[126,127],"tags":[],"class_list":["post-4115","post","type-post","status-publish","format-standard","hentry","category-logging","category-semantic-logging"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=4115"}],"version-history":[{"count":9,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4115\/revisions"}],"predecessor-version":[{"id":4135,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/4115\/revisions\/4135"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=4115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=4115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=4115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}