{"id":56,"date":"2014-10-24T18:27:55","date_gmt":"2014-10-24T16:27:55","guid":{"rendered":"http:\/\/www.kopf.com.br\/kaplof\/?p=56"},"modified":"2014-10-29T10:21:14","modified_gmt":"2014-10-29T08:21:14","slug":"using-multiple-configuration-files-with-log4net","status":"publish","type":"post","link":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/","title":{"rendered":"Using multiple configuration files with log4net"},"content":{"rendered":"<p>Although log4net is most likely one of the most powerful logging libraries for .Net, it has some limitations when it comes to spreading the configuration among multiple files.<\/p>\n<p>&nbsp;<\/p>\n<p>The use case for it is very common: a set of services wants to share parts of the same configuration (i.e.: sending e-mail in case of error, writing to the DB) but each service wants to write log entries to its own individual file.<\/p>\n<p>&nbsp;<\/p>\n<p>There are some posts suggesting the implementation, but there is none with a code example. I followed the suggestion from Kid on <a href=\"https:\/\/stackoverflow.com\/questions\/2775386\/log4net-configure-using-multiple-configuration-files\" target=\"_blank\">stackoverflow<\/a>: to build and in-memory XmlDocument appending different files and let log4net do the rest.<\/p>\n<p>&nbsp;<\/p>\n<p>My implementation worked on my test case using log4net 1.2.10. I didn&#8217;t tested it thoroughly. The idea is to introduce a new section in the application configuration file: <em>log4netMulti<\/em>. On this new section you may specify from which files the configuration should be read. Example:<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"brush:xml\">&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\r\n&lt;configuration&gt;\r\n  &lt;configSections&gt;\r\n    &lt;section name=\"log4netMulti\" type=\"log4net.Config.Log4NetConfigurationSectionHandler, log4net\" \/&gt;\r\n    &lt;section name=\"log4net\" type=\"log4net.Config.Log4NetConfigurationSectionHandler, log4net\" \/&gt;\r\n  &lt;\/configSections&gt;\r\n\r\n  &lt;log4netMulti thisConfig=\"true\"&gt;\r\n    &lt;file value=\".\\log4netAdditional.config\" \/&gt;\r\n  &lt;\/log4netMulti&gt;\r\n  &lt;log4net&gt;\r\n    &lt;appender name=\"RollingFile\" type=\"log4net.Appender.RollingFileAppender\"&gt;\r\n      &lt;file value=\"C:\\Temp\\Test.log\"\/&gt;\r\n      &lt;appendToFile value=\"true\"\/&gt;\r\n      &lt;layout type=\"log4net.Layout.PatternLayout\"&gt;\r\n        &lt;conversionPattern value=\"%date\t%-5level\t[%thread]\t%logger\t%message%newline\" \/&gt;\r\n      &lt;\/layout&gt;\r\n    &lt;\/appender&gt;\r\n\r\n    &lt;root&gt;\r\n      &lt;level value=\"DEBUG\" \/&gt;\r\n      &lt;appender-ref ref=\"RollingFile\" \/&gt;\r\n    &lt;\/root&gt;\r\n  &lt;\/log4net&gt;\r\n&lt;\/configuration&gt;<\/pre>\n<p>&nbsp;<\/p>\n<p>The attribute <em>thisConfig <\/em>states if the log4net section should also be retrieved on the current configuration file where the log4netMulti section is found.<\/p>\n<p>&nbsp;<\/p>\n<p>The separate files (in the example log4netAdditional.config) should be regular log4net XML config files.<\/p>\n<p>&nbsp;<\/p>\n<p>The merge is implemented in the XmlConfigurationMerger.cs class. Unfortunately the XML Configuration classes for log4net are not very extensible, so that I had to do a lot of copy-paste to get it working.<\/p>\n<p>&nbsp;<\/p>\n<p>In the application code, instead of calling<\/p>\n<p>&nbsp;<\/p>\n<pre>\u00a0\u00a0\u00a0 XmlConfiguration.Configure()<\/pre>\n<p>&nbsp;<\/p>\n<p>one should call<\/p>\n<p>&nbsp;<\/p>\n<pre>    XmlConfigurationMerger.Configure();<\/pre>\n<p>&nbsp;<\/p>\n<p>That&#8217;s it. The code can be downloaded from here: <a href=\"https:\/\/www.kopf.com.br\/kaplof\/wp-content\/uploads\/2014\/10\/XmlConfigurationMerger.zip\">XmlConfigurationMerger<\/a>. Feel free to enhance it or change it if needed, but keep me posted \ud83d\ude42<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Although log4net is most likely one of the most powerful logging libraries for .Net, it has some limitations when it comes to spreading the configuration among multiple files. &nbsp; The use case for it is very common: a set of services wants to share parts of the same configuration (i.e.: sending e-mail in case of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[19,31,20],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using multiple configuration files with log4net - Kaplof<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using multiple configuration files with log4net - Kaplof\" \/>\n<meta property=\"og:description\" content=\"Although log4net is most likely one of the most powerful logging libraries for .Net, it has some limitations when it comes to spreading the configuration among multiple files. &nbsp; The use case for it is very common: a set of services wants to share parts of the same configuration (i.e.: sending e-mail in case of [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/\" \/>\n<meta property=\"og:site_name\" content=\"Kaplof\" \/>\n<meta property=\"article:published_time\" content=\"2014-10-24T16:27:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-10-29T08:21:14+00:00\" \/>\n<meta name=\"author\" content=\"Bruno Marotta\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bruno Marotta\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/\"},\"author\":{\"name\":\"Bruno Marotta\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/person\/a096a6de30951e12938c6a800eeaa891\"},\"headline\":\"Using multiple configuration files with log4net\",\"datePublished\":\"2014-10-24T16:27:55+00:00\",\"dateModified\":\"2014-10-29T08:21:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/\"},\"wordCount\":293,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#organization\"},\"keywords\":[\"configuration\",\"log4net\",\"xml\"],\"articleSection\":[\"log4net\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/\",\"url\":\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/\",\"name\":\"Using multiple configuration files with log4net - Kaplof\",\"isPartOf\":{\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#website\"},\"datePublished\":\"2014-10-24T16:27:55+00:00\",\"dateModified\":\"2014-10-29T08:21:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.kopf.com.br\/kaplof\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using multiple configuration files with log4net\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#website\",\"url\":\"https:\/\/www.kopf.com.br\/kaplof\/\",\"name\":\"Kaplof\",\"description\":\"Sharing problems and solutions for software development\",\"publisher\":{\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.kopf.com.br\/kaplof\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#organization\",\"name\":\"Kopf\",\"url\":\"https:\/\/www.kopf.com.br\/kaplof\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/i0.wp.com\/www.kopf.com.br\/kaplof\/wp-content\/uploads\/2015\/04\/Logo-grande.png?fit=78%2C76&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/www.kopf.com.br\/kaplof\/wp-content\/uploads\/2015\/04\/Logo-grande.png?fit=78%2C76&ssl=1\",\"width\":78,\"height\":76,\"caption\":\"Kopf\"},\"image\":{\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/person\/a096a6de30951e12938c6a800eeaa891\",\"name\":\"Bruno Marotta\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8e15f82b4b9672c32c601286a40eb46f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8e15f82b4b9672c32c601286a40eb46f?s=96&d=mm&r=g\",\"caption\":\"Bruno Marotta\"},\"url\":\"https:\/\/www.kopf.com.br\/kaplof\/author\/bmarotta\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using multiple configuration files with log4net - Kaplof","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/","og_locale":"en_US","og_type":"article","og_title":"Using multiple configuration files with log4net - Kaplof","og_description":"Although log4net is most likely one of the most powerful logging libraries for .Net, it has some limitations when it comes to spreading the configuration among multiple files. &nbsp; The use case for it is very common: a set of services wants to share parts of the same configuration (i.e.: sending e-mail in case of [&hellip;]","og_url":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/","og_site_name":"Kaplof","article_published_time":"2014-10-24T16:27:55+00:00","article_modified_time":"2014-10-29T08:21:14+00:00","author":"Bruno Marotta","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Bruno Marotta","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/#article","isPartOf":{"@id":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/"},"author":{"name":"Bruno Marotta","@id":"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/person\/a096a6de30951e12938c6a800eeaa891"},"headline":"Using multiple configuration files with log4net","datePublished":"2014-10-24T16:27:55+00:00","dateModified":"2014-10-29T08:21:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/"},"wordCount":293,"commentCount":0,"publisher":{"@id":"https:\/\/www.kopf.com.br\/kaplof\/#organization"},"keywords":["configuration","log4net","xml"],"articleSection":["log4net"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/","url":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/","name":"Using multiple configuration files with log4net - Kaplof","isPartOf":{"@id":"https:\/\/www.kopf.com.br\/kaplof\/#website"},"datePublished":"2014-10-24T16:27:55+00:00","dateModified":"2014-10-29T08:21:14+00:00","breadcrumb":{"@id":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.kopf.com.br\/kaplof\/using-multiple-configuration-files-with-log4net\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.kopf.com.br\/kaplof\/"},{"@type":"ListItem","position":2,"name":"Using multiple configuration files with log4net"}]},{"@type":"WebSite","@id":"https:\/\/www.kopf.com.br\/kaplof\/#website","url":"https:\/\/www.kopf.com.br\/kaplof\/","name":"Kaplof","description":"Sharing problems and solutions for software development","publisher":{"@id":"https:\/\/www.kopf.com.br\/kaplof\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.kopf.com.br\/kaplof\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.kopf.com.br\/kaplof\/#organization","name":"Kopf","url":"https:\/\/www.kopf.com.br\/kaplof\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/www.kopf.com.br\/kaplof\/wp-content\/uploads\/2015\/04\/Logo-grande.png?fit=78%2C76&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.kopf.com.br\/kaplof\/wp-content\/uploads\/2015\/04\/Logo-grande.png?fit=78%2C76&ssl=1","width":78,"height":76,"caption":"Kopf"},"image":{"@id":"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/person\/a096a6de30951e12938c6a800eeaa891","name":"Bruno Marotta","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.kopf.com.br\/kaplof\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8e15f82b4b9672c32c601286a40eb46f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8e15f82b4b9672c32c601286a40eb46f?s=96&d=mm&r=g","caption":"Bruno Marotta"},"url":"https:\/\/www.kopf.com.br\/kaplof\/author\/bmarotta\/"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/posts\/56"}],"collection":[{"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/comments?post=56"}],"version-history":[{"count":10,"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/posts\/56\/revisions"}],"predecessor-version":[{"id":69,"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/posts\/56\/revisions\/69"}],"wp:attachment":[{"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/media?parent=56"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/categories?post=56"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kopf.com.br\/kaplof\/wp-json\/wp\/v2\/tags?post=56"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}