Problem

Often there is a disagreement between the BizTalk Developer and BizTalk Administrator when it comes to logging the events in BizTalk Apps using the Event Logs in the Production Environment or any other testing or QA Environments for that matter. Sometimes a new BizTalk Developer starts writing to the Event Log through the app without giving it much thought. This article aims at providing information about the good practices that can be followed while logging the events in the BizTalk Apps using the Event Log.

How BizTalk Stack Uses the EventLog

BizTalk by default logs all the information, errors, and warnings it encounters while message processing in the Windows Application Event Log. These entries comprise of the entries by BizTalk Engine, database engine, and IIS. Refer a sample screenshot which shows the entries made by the BackUpBiztalkServer Job in the Event Log.

These entries in the event log are of paramount importance to a BizTalk Admin when it comes to the troubleshooting of the issues. Now when a developer decides to write to an event log, using the EventLog class with the WriteEntry() method, they basically start writing to the stock application event log as the source of which they are writing will get by default registered in the application log. Now these entries are mixed up with the entries written by the BizTalk Stack (BizTalk Engine, Database Engine and IIS) and it becomes increasingly difficult for a BizTalk Admin to isolate the stock entries. Refer below screenshot for how the source gets registered in the Stock ApplicationLog if it is not bind to a custom event log.

Creating A Custom EventLog and Registering the Source

The first and most important thing that needs to be done is that a custom event log should be created before the deployment of the BizTalk App which instruments using the Event Log. Once the custom event log is created then next step is to register the app as a source in this newly created event log. The best way to accomplish is using a PowerShell script.  The PowerShell Script uses a config file which stores the CustomLog names and The App Source that needs to be registered.

<Servers>
  <Server>
    <Name>LocalHost</Name>
    <LogInfo>
      <LogName>BizCustomLog</LogName>
      <Source>BiztalkPOCApp1</Source>
    </LogInfo>
  </Server>
</Servers>

The PowerShell Script to create and register the event log and the app source is as follows.

Function CreateCustomLogAndRegisterSource
{
    param
    (
        $ConfigFilePath
    )
  
    if(Test-path $ConfigFilePath)
    {
        [xml]$Config= Get-Content "$ConfigFilePath\Config.xml"
        foreach($Server in $Config.Servers.Server)
        {
            $LogName= $Server.LogInfo.LogName
            $Source= $Server.LogInfo.Source
            $ServerName= $Server.Name
            $RegSources= @()
            if(Test-Connection $ServerName)
            {
                #Check if the Event Log is present on the server and the provided source exist or not
                $EventLogs= Get-EventLog -ComputerName $ServerName  -LogName $LogName
                if($EventLogs -ne $null)
                {
                    foreach($EventLog in $EventLogs)
                    {
                          
                        $RegSources += $EventLog.Source
                    }
                    if($RegSources -contains $Source)
                    {
                        Write-Host "Source is already registered for the Event Log $LogName"
                    }
                    else
                    {
                        #Register the Source to the provided custom event Log
                        New-EventLog -ComputerName $ServerName -LogName $LogName -Source $Source 
                        #This Registers the Source to the Event Log
                    }
                }
                else
                {
                    #Create a new Event Log and register the source inside the Event Log
                    New-EventLog -ComputerName $ServerName -LogName $LogName -Source $Source
  
                }
                  
            }
        }
    }
}

This will create a custom event log and write the entries to it.  For Example, the above script was used to create a custom event Log and to register the app source as per the provided config file as above. So when a call to write entry to the event log is made as shown below,

static void Logger()
       {
System.Diagnostics.EventLog.WriteEntry("BiztalkPOCApp1", "ClassLibraryCall", System.Diagnostics.EventLogEntryType.Information);
       }

The entry will get written to the custom event log "BizCustomLog." Refer the sample below 

So it is important to run the above script before the BizTalk app is deployed to the Testing,QA or Production Environment. Once this is done, all the entries viz. Information, Errors and Warnings pertaining to this source will get written to the custom log.

Notifying Errors and Warnings To DevOps Team

Once the Custom event log is created, source registered and the BizTalk app is deployed to the production environment, then it becomes the duty of the DevOps team to monitor the app behavior if it throws any errors or warnings as such. These warnings(Custom errors caught in the exception Handling or Warnings in functional validation failure) should be sent to the DevOps team for an analysis. Again Powershell Script plays an important role in setting up this notification system. The PowerShell script accepts the names of the event logs and emails the warnings and errors logged in the error log. The script is as below.

Function SendEevntLogDetails
{
    param
    (
        $strFilePath
    )
    $MailBody="Hi OpsTeam, <br/><br/> Following is the list of errors and warnings for the Custom Logs used fopr Biztalk App Instrumentations"
    $Logs= Get-Content "$strFilePath\CustomLogs.txt"
    $style="<style>BODY{background-color:white;}TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse; }TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:lightSkyBlue }TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:white}</style>"
    $head= "<head>$style</head>"
      
    $MachineName="LocalHost"
    foreach($log in $Logs)
    {
          
        $tableBOdy= "<body>$style<table><colgroup><col/><col/><col/><col/></colgroup><tr><th>ServerName</th><th>Source</th><th>EntryType</th><th>EventId</th><th>Message</th></tr>"
        $MailBody+= "<br/><br/><b>Machine Name:$MachineName</b><br/> <b>EventLog:$log</b> <br/>"
        $EntryType=@("Warning","Error")
        $EventlOGS= Get-EventLog -LogName $log -EntryType $EntryType
        # Get the event Logf Details
        foreach($Event in $EventlOGS)    
        {
            $Entry=$Event.EntryType
            $EventId=$Event.EventID
            $Message=$Event.Message
            if($Entry -eq "Error")
            {
                  
                $Message="<font color='Red'>$Message</font>"
            }
                          
            $Source=$Event.Source
            $tableBOdy += "<tr><td>$MachineName</td><td>$Source</td><td>$Entry</td><td>$EventId</td><td>$Message</td></tr>"
        }
        $tableBOdy=$tableBOdy+"</table></body>"
        $html="<html>$head$tableBOdy</html>"
        $MailBody += $html
  
         
    }
    $MailBody += "<br/>Thank You</br>Regards,<br/>Admin Team"
  
    [string]$Subject= "Custom Event log Notification"       
    [string[]]$users = "lmn@pqr.com"
    [string]$fromemail = "abc@pqr.com" 
    [string]$server = "SMTP Ip or Name Here"     
    send-mailmessage -from $fromemail -to $users -subject $Subject -BodyAsHTML $MailBody -priority High -smtpServer $server 
    Write-Host "Mail Sent successfully...!!!"
  
      
      
}

Refer the sample mail below.

Archiving The Event Log

The Event Logs Should be archived periodically to avoid their overgrowth or in another case the loss of the data. So a good practice is to archive the event logs periodically and clear the event logs so that fresh data can be logged to it. Such Archived Event Logs can be shared with the Developers or the Operation teams if the need arises. Once again PowerShell can be used to automate this task. The config file is as below.

<Configuration>
  <Server>
    <BackUpPath>Enter the back Up path here</BackUpPath>
    <LogName>BizCustomLog</LogName>
    <ServerName>localhost</ServerName>
  </Server>
</Configuration>

The PowerShell Script for Archiving the Logs is as below.

Function ArchiveEventLog
{
    param
    (
        $ConfigFilePath
    )
  
    if(Test-path $ConfigFilePath)
    {
        [xml]$Config= Get-Content "$ConfigFilePath/Config.xml"
        $backUpPath=$Config.Configuration.Server.BackUpPath
        $LogName=$Config.Configuration.Server.LogName
        $Servername=$Config.Configuration.Server.ServerName
        if(test-path $backUpPath)
        {
            $EventLog= Get-WmiObject -Class Win32_NTEventLogFile -ComputerName $Servername -Filter ("LogfileName='$LogName'")
             
            $date=get-date -Format "yyyymmdd"
            $backUpPath="$backUpPath\$LogName"+"_$date.evt"
            $Status=($EventLog.BackupEventLog($backUpPath)).ReturnValue
            if($Status -eq 0)
            {
                #Clear The Event Log
                $ClearStatus= ($EventLog.ClearEventLog()).ReturnValue
  
            }
  
        }
          
    }
}

The PowerShell Script can be scheduled using the Windows task Scheduler to archive the logs at a pre-defined time.The PowerShell script uses a config file to read the log to be backed up , the path and the name of the server

Conclusion

A good Logging Strategy for the BizTalk App using the Event Log will include

  • Creating a Custom Event Log
  • Registering the Source of the BizTalk App with the Custom Event Log.
  • Notifying DevOps Team with Important Warnings and Errors
  • Archiving the event logs to a folder to avoid data loss.

See Also

Another important place to find a huge amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki