{"componentChunkName":"component---src-templates-blog-post-js","path":"/2011/08/08/customizing-log4net-log-entries-on-azure/","result":{"data":{"site":{"siteMetadata":{"title":"Vidar's musings"}},"markdownRemark":{"id":"d48e027d-b3bf-55b9-b8ca-e9b21aee4260","excerpt":"I have earlier blogged about how to use Log4Net on Azure compute. With this solution the log files from the various running instances gets transferred to a…","html":"<p>I have earlier <a href=\"/2011/08/03/using-log4net-in-azure-compute/\">blogged about how to use Log4Net on Azure compute</a>. With this solution the log files from the various running instances gets transferred to a common container on Azure blob store. When I mine the log data, I usually merge all the log files together an run text utils like grep or sed on them.</p>\n<p>One challenge when merging the log files together is that we then lose the information about which instance the different log entries came from. In order to fix this, we can customize the log entries to that we keep this information.</p>\n<p>The first we need to do, is to create a new layout class that inherits from PatternLayout:</p>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre class=\"language-csharp\"><code class=\"language-csharp\"><span class=\"token keyword\">using</span> <span class=\"token namespace\">log4net<span class=\"token punctuation\">.</span>Layout</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">namespace</span> <span class=\"token namespace\">Demo<span class=\"token punctuation\">.</span>Log4Net<span class=\"token punctuation\">.</span>Azure</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">AzurePatternLayout</span> <span class=\"token punctuation\">:</span> <span class=\"token type-list\"><span class=\"token class-name\">PatternLayout</span></span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">public</span> <span class=\"token function\">AzurePatternLayout</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n             <span class=\"token comment\">// TODO: add converters</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Next, we need to register this class in the log4net configuration:</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>log4net</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>appender</span> <span class=\"token attr-name\">...</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>layout</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Demo.Log4Net.Azure.AzurePatternLayout, Demo.Log4Net.Azure<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>conversionPattern</span> <span class=\"token attr-name\">...</span> <span class=\"token punctuation\">/></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>layout</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>appender</span><span class=\"token punctuation\">></span></span>\n  ...\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>log4net</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>So now that we have a new <code class=\"language-text\">PatternLayout</code> class, we can add some logic into it for adding Azure-specific log information into the entries. To do so, we first need a new <code class=\"language-text\">Converter</code> class:</p>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre class=\"language-csharp\"><code class=\"language-csharp\"><span class=\"token keyword\">using</span> <span class=\"token namespace\">System<span class=\"token punctuation\">.</span>IO</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">using</span> <span class=\"token namespace\">log4net<span class=\"token punctuation\">.</span>Util</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">using</span> <span class=\"token namespace\">Microsoft<span class=\"token punctuation\">.</span>WindowsAzure<span class=\"token punctuation\">.</span>ServiceRuntime</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">namespace</span> <span class=\"token namespace\">Demo<span class=\"token punctuation\">.</span>Log4Net<span class=\"token punctuation\">.</span>Azure</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">internal</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">AzureInstanceIdPatternConverter</span> <span class=\"token punctuation\">:</span> <span class=\"token type-list\"><span class=\"token class-name\">PatternConverter</span></span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">protected</span> <span class=\"token keyword\">override</span> <span class=\"token return-type class-name\"><span class=\"token keyword\">void</span></span> <span class=\"token function\">Convert</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">TextWriter</span> writer<span class=\"token punctuation\">,</span> <span class=\"token class-name\"><span class=\"token keyword\">object</span></span> state<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n            writer<span class=\"token punctuation\">.</span><span class=\"token function\">Write</span><span class=\"token punctuation\">(</span>RoleEnvironment<span class=\"token punctuation\">.</span>CurrentRoleInstance<span class=\"token punctuation\">.</span>Id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Now, we register the new <code class=\"language-text\">AzureInstanceIdPatternConverter</code> in the constructor of <code class=\"language-text\">AzurePatternLayout</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"csharp\"><pre class=\"language-csharp\"><code class=\"language-csharp\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">AzurePatternLayout</span> <span class=\"token punctuation\">:</span> <span class=\"token type-list\"><span class=\"token class-name\">PatternLayout</span></span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">public</span> <span class=\"token function\">AzurePatternLayout</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">AddConverter</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"roleinstance\"</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">typeof</span><span class=\"token punctuation\">(</span><span class=\"token type-expression class-name\">AzureInstanceIdPatternConverter</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Then we can change the <code class=\"language-text\">conversionPattern</code> element of the Log4Net configuration to use the new Azure environment information:</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>layout</span> <span class=\"token attr-name\">type</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Demo.Log4Net.Azure.AzurePatternLayout, Demo.Log4Net.Azure<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>conversionPattern</span> <span class=\"token attr-name\">value</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>%date [%roleinstance] [%thread] %-5level %logger [%appdomain] - %message%newline<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>layout</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>….which will make the log entries look something like this:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/5db96026e89e7b6153bddb6d17d4ec25/bcb8c/Skjermbilde-2011-08-01-kl.-09.11.48.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 12.658227848101264%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAwElEQVQI1x2K206DQABE+f9PMTFNaRpjSIUKFcp2BXaXvbQEjT5rq/X9SHk4mZmTieJUcJfseZAja/nG2l1Y9D/cqy9W/o/l1GP7S+xuXGe36C/E/srSnIn198zq5vSZqGp66tZR60B3aFGbFJPlqDTDPBfY1w516LCVoJ92k2yQj8n8O5qAOX3ghk+ECujwTmRdj/MWf3RY07HPM5SokFUxZclQbvH5E7Z+QdclTbVDlgXtxBgcPnjGcUBIgfeOfzqCzVIi+kJmAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Custom log entries\"\n        title=\"Custom log entries\"\n        src=\"/static/5db96026e89e7b6153bddb6d17d4ec25/f058b/Skjermbilde-2011-08-01-kl.-09.11.48.png\"\n        srcset=\"/static/5db96026e89e7b6153bddb6d17d4ec25/c26ae/Skjermbilde-2011-08-01-kl.-09.11.48.png 158w,\n/static/5db96026e89e7b6153bddb6d17d4ec25/6bdcf/Skjermbilde-2011-08-01-kl.-09.11.48.png 315w,\n/static/5db96026e89e7b6153bddb6d17d4ec25/f058b/Skjermbilde-2011-08-01-kl.-09.11.48.png 630w,\n/static/5db96026e89e7b6153bddb6d17d4ec25/bcb8c/Skjermbilde-2011-08-01-kl.-09.11.48.png 879w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>(The screenshot shows instance ids generated by DevFabric, not an instance in the cloud).</p>","frontmatter":{"title":"Customizing Log4net log entries on Azure","date":"August 08, 2011","description":null}},"previous":{"fields":{"slug":"/2011/08/03/using-log4net-in-azure-compute/"},"frontmatter":{"title":"Using Log4Net in Azure Compute"}},"next":{"fields":{"slug":"/2011/08/15/log4net-writing-log-entries-to-azure-table-storage/"},"frontmatter":{"title":"Log4Net: writing log entries to Azure Table Storage"}}},"pageContext":{"id":"d48e027d-b3bf-55b9-b8ca-e9b21aee4260","previousPostId":"a7b51755-30bc-51bb-859a-898509965a36","nextPostId":"f4a540d9-6f60-5670-abea-72ad5e0a53c5"}},"staticQueryHashes":["2841359383","3257411868"]}