Handling the log4net config file like the PortBindings Master file

Topics: General Questions, Server Deployment, Visual Studio Integration
Feb 14, 2013 at 9:04 PM
I am working with a client at the moment who are still using BizTalk 2006 R2 on Win Server 2003 32-bit and have standardised on log4net for diagnostic trace logging.

I am loving the ease of adding log4net to a deployment - one property setting :-), but unfortunately some of the default behaviour isn't quite meeting our needs. So my first question would be, are there any other settings relevant to log4net deployment that I can use to adjust the default behaviour?

In an ideal world I would like the handling of log4net to follow the model established for Binding Files, namely that you have a log4net Master file containing constructs such as:
<!-- ifdef ${_xml_preprocess} -->
<!-- <connectionString value="data source=${OperationalSupportDB};initial catalog=MyCustomer_OperationalSupport;integrated security=true;persist security info=True" /> -->
<!-- else -->
<connectionString value="data source=(local);initial catalog=MyCustomer_OperationalSupport;integrated security=true;persist security info=True" />
<!-- endif -->
The XmlPreprocess functionality would be used to apply the relevant values from the Environment Settings spreadsheet, in this case the server name for the logging database.

This Master log4net file would be checked into TFS and left read-only (unless you were editing it!) in your workspace (so as not to generate unnecessary churn in TFS - or rely on developers to discard the changes) and the actual log4net file would be generated when you ran a deploy.

The deploy itself would need to be sensitive to whether you were doing a deploy from VS.NET, Build Server or on the Target Server (via the generated .msi) as you would need slightly different behaviour along the following lines:

  • You will have the master log4net file on disk (dev workspace) and you will want the log4net config file to be generated using local settings
  • You will want the registry configured to point to the log4net file in your development workspace
Build Server (you will almost certainly need a working log4net infrastructure for your build tests to run successfully)
  • You will have the master log4net file on disk (build workspace) and you will want the log4net config file to be generated using build server settings - only needed for build tests
  • You will want the registry configured to point to the log4net file in your build workspace
  • Only the master log4net config file would be placed in the .msi built for distribution (the actual log4net config file will be generated as part of a server deploy)
Target Server
  • You will have the master log4net file on disk ({Program Files}) and you will want the log4net config file to be generated using the settings for your targeted environment
  • You will want the registry configured to point to the log4net file in your {Program Files} install directory
The other thing that would be really useful is if there was a switch to enable/disable the GACing of the log4net dll's because in our installation the deployment of these assemblies is managed independently of application deployment as these are reusable components used by a number of applications and the rule is 'Apps don't touch them' - so we would want to turn the auto-deployment behaviour off.

I think that's how it would all need to work.

Is this something that you believe could be achieved with existing functionality (and if so how?) or would it require enhancement, indeed would this be desirable functionality for other users?
Feb 15, 2013 at 2:12 AM

You can set this up the same way as your master binding file.
  1. Copy your existing [MyProjectName].log4net file to (for example) master.log4net in the same directory
  2. Edit master.log4net and put in place the usual XmlPreprocess tokens as in your sample above
  3. In your .btdfproj, add a FilesToXmlPreprocess ItemGroup as shown below. Update the LocationPath if necessary.
  4. Add an AdditionalFiles ItemGroup pointing to master.log4net so that it is automatically included in the MSI
    <FilesToXmlPreprocess Include="master.log4net">
master.log4net will now be processed along with the binding file and written out to MyProjectName.log4net.

As far as preventing log4net.dll from being deployed, you'll have to deploy our Serializable log4net assembly, so try this out. Put the following into your .btdfproj before the include of the BTDF targets file:
    <AdditionalAssemblies Include="log4net.Ext.Serializable.dll" />
    <AdditionalAssemblies Include="SSOSettingsFileReader.dll" />
I'm not 100% certain that that will do it, but with any luck that will be sufficient.

Dec 4, 2013 at 8:00 AM
Hi RedDwarf/Tom,

Did this work?

I have virtually the same scenario as RedDwarf and I have followed the above and I can't get it to work although I have done with BTS10 and its related BTDF version.

I end up with the XmlPreProcess statements still in tact in the MyProject.Log4Net file as if it just did a copy of the Master to the output file.

One point the element <OutputFilename> does not appear to valid within the FilesToXmlPreprocess item group.

Jim Mclay
Dec 4, 2013 at 4:00 PM
Hi Jim,

I only used this approach in a BizTalk 2006 R2 environment and unfortunately the project was parked pending review so I never got to see it through to completion, that said, in the local development environment the approach appeared to be working perfectly.

Here is what I had in the BTDF Proj file (names changed to save any blushes):

<FilesToXmlPreprocess Include="Organisation.BTSApp_Master.log4net">

<AdditionalFiles Include="Organisation.BTSApp_Master.log4net">

and here is what was in the Organisation.BTSApp_Master.log4net file:
<!-- ifdef ${_xml_preprocess} --> <!-- <connectionString value="data source=${ApplicationDB};initial catalog=Organisation_BTSApp;integrated security=true;persist security info=True" /> --> <!-- else --> <connectionString value="data source=(local);initial catalog=Organisation_BTSApp;integrated security=true;persist security info=True" />
<!-- endif --> The resulting Organisation.BTSApp.log4net contained my local development machine name rather than (local)…so as far as I can see it had worked, but as I said, I never got to take it onto a test environment via .msi and verify it worked correctly there.

Hope that helps. You've got me number, give me a call in the morning if you need anything further.


Dec 5, 2013 at 4:58 AM
Hi Jim,

Do you have the property RequireXmlPreprocessDirectives set to false in your .btdfproj? The way that you specify the tokens in master.log4net should be identical to the way that you specify them in PortBindingsMaster.xml. If you used ifdef's in master.log4net and you have RequireXmlPreprocessDirectives set to false, then it won't preprocess correctly.

Dec 6, 2013 at 8:13 AM

Thanks for the emails guys.

The client I am working for was using version 5.0.25 of the framework I upgraded to the latest 5.0 version and everything worked as expected.

Once again thanks for your help.