Introduction

Often is the requirement in software development that the developer traces the flow of the developed application to track any bugs or issues that are raised during the testing or production run. At other times the requirement can be that the developer wants to track some mission-critical data to files or to a custom database for future use or simply they are required to audit the request responses processed by the application. The solution to that is using a good logging framework to track the data. One such well-known logging framework is log4net which helps the developers to log well-formatted events to various sinks like text files, databases etc.

What is log4net?

log4net is the MicroSoft .Net framework port of the Apache log4j framework which is used as a logging utility for Java applications. log4net allows developers to log the events to various targets like files, database stores etc.(see References section for the link to the documentation).

↑Back To Top


Scope

This article discusses the use of the log4net framework for the tracking of events in the BizTalk application. log4net can be used to track the steps of flow of the orchestration in the BizTalk application by using intelligent logging milestones in expression shapes which will let the developers know where the control is at a given point of time. These events can be logged to a text file which can be tailed using any tailing application to view the logging in the real time. This serves as an addendum to the already present debugging feature like Orchestration Debugger. log4net can be used to save the messages processed by BizTalk orchestration to an audit database if that is the business requirement(not covered in current scope as it is not an ideal way to audit messages). The sample discussed in this article will use the BizTalk Deployment Framework to accommodate and automate the deployment of the log4net configuration components as a part of the deployment process.

What is BTDF? 

BTDF is an open source deployment framework used for deploying BizTalk applications on local dev boxes as well as different environments. It provides many facilities that can be used to club together the task that require being performed pre and post-deployment of the BizTalk deployment e.g restarting of the concerned Host Instances, IIS reset etc. Another advantage of BTDF is that it is very flexible and can be configured to do a lot of tasks before, during and after the deployment of BizTalk application. All these tasks can be packaged up as a single MSI file and can be installed in the target environment. It also provides facility to define the variables related to different environments in a spreadsheet which simplifies the task of manually maintaining the binding files for the BizTalk application for multiple environments. These are some of the features of BTDF. BTDF has proven to be a very reliable tool for creating buildMSIi for BizTalk. It is a necessary weapon in the arsenal of a professional working on BizTalk platform. 
This article uses the latest version 5.7 that is released. To learn more about the installation of the btdf and step by step guide for configuring the BTDF, refer following link. The link discusses the steps taken for BizTalk 2016 and Visual Studio 2015 , but same can be followed for other versions of BizTalk.
Step by Step Guide For Installation and Configuration of BTDF for BizTalk 2016 and Visual Studio 2015  

↑Back To Top


Implementation

Following are various steps that are involved in setting up complete logging utility for a BizTalk application using log4net and BTDF.

Creating log4net  Configuration File 

In order to define what sinks that will be used to log the details from the orchestrations/helper classes/ pipeline components, the first task is to create the configuration file for the log4net . In order to use it with the BTDF framework, the file is named as <BizTalk ApplicationName>.log4net and should be placed in the  visual studio solution folder for the same application. It can be included in the solution Items using the solution folder as shown in sample screen shot below.

Following is a sample configuration file that is shown in the above screenshot. The comments in the config file explain the important concepts.

<log4net debug="true">
  <root>
    <level value="*" />
    <appender-ref ref="EventLogAppender" />
  </root>
  <!-- Logger which will call the Rolling File appender and Create the Log file
  Minimum Logging Level is DEBUG-->
  <logger name="BTDFTestProject">
    <level value="DEBUG" />
    <appender-ref ref="RollingFileAppender"/>
  </logger>
  <!--Rolling File Appender deined below will create a log file by Name BTDFTestLroject.log at the location configured in file
  node. appendToFile allows to add multiple log entries to the same file. maximumFileSize governs the maximum size of log file after which
  the appender will archive the current log file and create a new log file of same name-->
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
    <file value="E:\logstore\BTDFTestProject.Log" />
    <appendToFile value="true" />
    <DatePattern value="dd-MM-yyyy" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="1MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <!--Governs the pattern in which the data will be written. The OrchestrationInstanceiD helps to correlat the
      messages in the DTA database-->
      <conversionPattern value="%date [%thread] %-5level OrchestrationInstanceId: %property{InstanceId} %logger Message: %message%newline" />
    </layout>
  </appender>
  <!--Event Log Appender is used to log events to the windows event log. This appender can be used to create custom
  applkication logs if required.-->
  <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level OrchestrationInstanceId: %property{InstanceId} %logger Message: %message%newline" />
    </layout>
    <!--Defines that the logger will use the user under which the process is running
    in BizTalk terms it is either the Host Instance associated with the orchestration or the Handler processing the ports(in case of custom pipelien components)-->
    <secutrityContext type="logh4net.Util.WindowsSecurityContext">
      <credentials value="Process"></credentials>
    </secutrityContext>
    <!--Defines that the minimum level for which the entry will be logged to eventy log is Error-->
    <filter type="log4net.Filter.LevelRangeFilter">
      <levelMin value="ERROR" />
      <levelMax value="FATAL" />
    </filter>
  </appender>
</log4net>

Configuring BTDF Project

In order to facilitate the deployment of the configuration file created above, it is necessary to configure the *.btdfproj file. Following are the settings that need to be done.

Including log4net during deployment

 This can be done by adding following line in the PropertyGroup Defining the deployment conditions.

<Includelog4net>True</Includelog4net>

A typical Property Group defining the deployment conditions would look as follows.

<PropertyGroup>
  <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
  <Platform Condition="'$(Platform)' == ''">x86</Platform>
  <SchemaVersion>1.0</SchemaVersion>
  <ProjectName>BTDFTestProject</ProjectName>
  <ProjectVersion>1.0</ProjectVersion>
  <IncludeVirtualDirectories>True</IncludeVirtualDirectories>
  <UsingMasterBindings>True</UsingMasterBindings>
  <RequireXmlPreprocessDirectives>False</RequireXmlPreprocessDirectives>
  <ApplyXmlEscape>True</ApplyXmlEscape>
  <SkipIISReset>False</SkipIISReset>
  <Includelog4net>True</Includelog4net>
  <IncludeComponents>True</IncludeComponents>
</PropertyGroup>

The BTDF installation process is a 32 bit process and when the btdf configures the log4net for the application, it creates the registry key in the Registry corresponding to the 32 bit process (SYSWOW64 32) but if the host instances processing the orchestration are 64 bit, then a registry key need to be created which corresponds to the 64 bit host instances. A custom post deployment target needs to be created for this task. It can be created as a sample shown below.

<Target Name="CustomPostDeployTarget">
    <CallTarget Targets="CreateLog4Net64BitRegKey" />
  </Target>
  <Target Name="CreateLog4Net64BitRegKey">
    <Exec Command=""$(SystemRoot)\Sysnative\cscript.exe" /nologo "$(DeployTools)\WriteRegValue.vbs" $(Log4netRegKey) "@(Log4netFile)"" />
  </Target>
*Note: quotes used inside the Command="" need to be escaped using &quot; 

The registry entries created by the BTDF in both the 32 bit and the 64 bit registry folders are shown below.

Fig: BizTalk App Entry in 32 bit node 

Fig: BizTalk App Entry in 64 bit node

Integrating log4net in Orchestration.

Following steps describes how to integrate log4net framework into an orchestration..

  1. Add the references to the log4net assemblies to the Orchestration Project as shown below.



  2.  Create the variables for the logger and for the logger properties collection as shown in sample screen shot below.





  3. The variables created above can be initiated as shown below.

    varLogger = log4net.Ext.Serializable.SLogManager.GetLogger("BTDFTestProject", log4net.helpers.CallersTypeName.Name);
    varLogger.RegistryConfigurator();
    varInstanceId = TestOrch(Microsoft.XLANGs.BaseTypes.InstanceId);
    varLogProperties.Set("InstanceId", varInstanceId);
    varLogger.Debug(varLogProperties,"Logger Initiated");
    varLogger.DebugFormat(varLogProperties, "Logger Logging {0} level using Format String for Instance Id {1}", "Debug", varInstanceId);
  4. The logger can be passed to the helper classes which are called from the orchestration. For example, method from following class is called from the TestOrch orchestration. The method just logs a sample string and then throws an Exception which can be caught in the TestOrch orchestration to demonstrate the event logging capability of log4net. The helper class is as follows.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace BTDFTestProject.Components
    {
        public class OrchestrationHelper
        {
            public static void InvokeException(log4net.ILog logger, string instanceId)
            {
     
                logger.Info("This Call is Initiated from the Helper Class Library for Instance Id " + instanceId);
                 
                throw new System.Exception("Throwing Exception from the helper to show event logging ability of log4net") ;
                     
            }
        }
    }

    The call made to InvokeException function from the orchestration is as follows.

    varLogger.Info(varLogProperties, "Finished Executing Map");
    varLogger.InfoFormat(varLogProperties, "Sending Response for Instance Id : {0}", varInstanceId);
    BTDFTestProject.Components.OrchestrationHelper.InvokeException(varLogger,varInstanceId);
  5. The Logging placed in the exception block of the TestOrch is as follows.

    varLogger.Error(varLogProperties,"Exception Thrown. Error:" + ex.Message);

This completes the set up of the logger with the application.

↑Back To Top


Testing

The orchestration was triggered using the BizTalk WCF Service and following are the observations.

 log4net config File was Deployed at the location specified while installing the BTDF msi.

  

Following log was created at the location specified in the log4net file.

  

The events logged in the log file are as follows. 

2018-02-17 03:49:09,673 [65] DEBUG OrchestrationInstanceId: 05d3e6f3-ffe5-4ef1-be11-7fce83089fd2 BTDFTestProject.Orchestration.TestOrch Message: Logger Initiated
2018-02-17 03:49:09,825 [65] DEBUG OrchestrationInstanceId: 05d3e6f3-ffe5-4ef1-be11-7fce83089fd2 BTDFTestProject.Orchestration.TestOrch Message: Logger Logging Debug level using Format String for Instance Id 05d3e6f3-ffe5-4ef1-be11-7fce83089fd2
2018-02-17 03:49:18,693 [65] INFO  OrchestrationInstanceId: 05d3e6f3-ffe5-4ef1-be11-7fce83089fd2 BTDFTestProject.Orchestration.TestOrch Message: Finished Executing Map
2018-02-17 03:49:18,695 [65] INFO  OrchestrationInstanceId: 05d3e6f3-ffe5-4ef1-be11-7fce83089fd2 BTDFTestProject.Orchestration.TestOrch Message: Sending Response for Instance Id : 05d3e6f3-ffe5-4ef1-be11-7fce83089fd2
2018-02-17 03:49:18,706 [65] INFO  OrchestrationInstanceId: (null) BTDFTestProject.Orchestration.TestOrch Message: This Call is Initiated from the Helper Class Library for Instance Id 05d3e6f3-ffe5-4ef1-be11-7fce83089fd2
2018-02-17 03:49:18,773 [65] ERROR OrchestrationInstanceId: 05d3e6f3-ffe5-4ef1-be11-7fce83089fd2 BTDFTestProject.Orchestration.TestOrch Message: Exception Thrown. Error:Throwing Exception from the helper to demonstarte event logging capability of log4net

At the same time the following is a screenshot for the error logged in the event log. 

↑Back To Top


Conclusion

From the results of the testing, it can be concluded that the logging for events in BizTalk artefacts like orchestrations , helper classes can be set up easily using the log4net framework and BTDF very easily.

↑Back To Top


See Also

A great place to start learning about the BizTalk product is BizTalk Server Resources on the TechNet Wiki 

↑Back To Top


References

Information available at following websites was referred while writing this article.

  1. What is Apache log4net 
  2. Deployment Framework for BizTalk Server V5.0