Saturday 10 November 2012

Trace logging with the Enterprise Library for MS Dynamics CRM 2011 plug-ins - part 2

In part one of this series I described the changes needed to use the trace logging capabilities of the enterprise library, in this post I shall describe how to add these changes using Wix.

The more eagled eyed readers, will notice that the listeners are different from the last time, this is because we are actually using a private queue on the database server to log the Trace messages to. These are then processed by the Enterprise Library MSMQ Distributor service, I shall discuss this in detail in an upcoming post.

I've not managed to insert the configSections element at the beginning of CrmAsyncService.exe.config file, which is where it needs to be, so I just deleted what it was there, added the configSections element and re-added what was originally there. It feels too much like a hack but ...

 Wix Sample
 <?xml version="1.0" encoding="UTF-8"?>
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
   <Fragment >
 
     <Component Id="pluginlogging" Guid="BA77335E-ADF1-4037-9881-68E116BA543D" Directory="dirB50C76F5A59FB10334E162992F65AAAA" KeyPath="yes">
       <Condition>DYNAMICS</Condition>
       <util:XmlConfig Id="web.logging"  File="[DYNAMICSCRMWEB]\web.config" Action="create"
               ElementPath="/configuration/configSections" On="install"  Node="document" Sequence="1" VerifyPath="/configuration/configSections/section[\[]@name='loggingConfiguration'[\]]" >
         <![CDATA[<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> ]]>
       </util:XmlConfig>
 
       <util:XmlConfig Id="webloggingConfiguration" Action="create" ElementPath="/configuration"   File="[DYNAMICSCRMWEB]\web.config" Node="document" On="install" Sequence="2" VerifyPath="/configuration/loggingConfiguration/listeners">
         <![CDATA[<loggingConfiguration name="" tracingEnabled="true" defaultCategory="Trace">
     <listeners>
       <add name="Message Queuing Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.MsmqTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.MsmqTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         queuePath="FormatName:Direct=OS:[SQLHOSTNAME]\private$\logging" formatter="Binary Log Message Formatter"
         timeToReachQueue="10.00:00:00" timeToBeReceived="10.00:00:00"
         recoverable="true" useDeadLetterQueue="true" traceOutputOptions="None" />
        <add name="Event Log Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         source="Enterprise Library Logging" formatter="Text Formatter" />
     </listeners>
     <formatters>
       <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         template="Timestamp: {timestamp}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
         name="Text Formatter" />
       <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.BinaryLogFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         name="Binary Log Message Formatter" />
     </formatters>
     <categorySources>
       <add switchValue="All" name="Trace">
         <listeners>
           <add name="Message Queuing Trace Listener" />
         </listeners>
       </add>
       <add switchValue="All" name="Error">
         <listeners>
           <add name="Message Queuing Trace Listener" />
         </listeners>
       </add>
     </categorySources>
     <specialSources>
       <allEvents switchValue="All" name="All Events" />
       <notProcessed switchValue="All" name="Unprocessed Category" />
       <errors switchValue="All" name="Logging Errors &amp; Warnings">
         <listeners>
           <add name="Event Log Trace Listener" />
         </listeners>
       </errors>
     </specialSources>
   </loggingConfiguration>]]>
       </util:XmlConfig>
 
 
       <util:XmlConfig Id="asyncloggingConfiguratiodn" Action="delete" ElementPath="/configuration"   File="[DYNAMICSCRM]\Server\bin\CrmAsyncService.exe.config" Node="element"
                  On="install" Sequence="3" VerifyPath="runtime" />
 
       <util:XmlConfig Id="asynclogging" Action="create" ElementPath="/configuration"
                       File="[DYNAMICSCRM]\Server\bin\CrmAsyncService.exe.config" Node="document" On="install" Sequence="4" VerifyPath="/configuration/configSections/section[\[]@name='loggingConfiguration'[\]]" >
         <![CDATA[<configSections><section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" /></configSections>]]>
       </util:XmlConfig>
 
       <util:XmlConfig Id="asyncloggingmlarky" Action="create" ElementPath="/configuration"
                       File="[DYNAMICSCRM]\Server\bin\CrmAsyncService.exe.config" Node="document" On="install" Sequence="5" VerifyPath="/configuration/runtime" >
         <![CDATA[<runtime><gcServer enabled="true"/>
         <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
           <dependentAssembly>
             <assemblyIdentity name="Microsoft.Crm.Sdk" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
             <bindingRedirect oldVersion="4.0.0.0-5.0.0.0" newVersion="5.0.0.0"/>
           </dependentAssembly>
         </assemblyBinding>
       </runtime>]]>
       </util:XmlConfig>
 
       <util:XmlConfig Id="asyncloggingConfiguration" Action="create" ElementPath="/configuration"
                       File="[DYNAMICSCRM]\Server\bin\CrmAsyncService.exe.config" Node="document" On="install" Sequence="6" VerifyPath="/configuration/loggingConfiguration/listeners" >
         <![CDATA[<loggingConfiguration name="" tracingEnabled="true" defaultCategory="Trace">
     <listeners>
       <add name="Message Queuing Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.MsmqTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.MsmqTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         queuePath="FormatName:Direct=OS:[SQLHOSTNAME]\private$\logging" formatter="Binary Log Message Formatter"
         timeToReachQueue="10.00:00:00" timeToBeReceived="10.00:00:00"
         recoverable="true" useDeadLetterQueue="true" traceOutputOptions="None" />
        <add name="Event Log Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         source="Enterprise Library Logging" formatter="Text Formatter" />
     </listeners>
     <formatters>
       <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         template="Timestamp: {timestamp}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
         name="Text Formatter" />
       <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.BinaryLogFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
         name="Binary Log Message Formatter" />
     </formatters>
     <categorySources>
       <add switchValue="All" name="Trace">
         <listeners>
           <add name="Message Queuing Trace Listener" />
         </listeners>
       </add>
       <add switchValue="All" name="Error">
         <listeners>
           <add name="Message Queuing Trace Listener" />
         </listeners>
       </add>
     </categorySources>
     <specialSources>
       <allEvents switchValue="All" name="All Events" />
       <notProcessed switchValue="All" name="Unprocessed Category" />
       <errors switchValue="All" name="Logging Errors &amp; Warnings">
         <listeners>
           <add name="Event Log Trace Listener" />
         </listeners>
       </errors>
     </specialSources>
   </loggingConfiguration>]]>
       </util:XmlConfig>
       <File Id="fileA8FAD71029831AC3655E19B9142ABCD"  Source="..\..\bin\Microsoft.Practices.EnterpriseLibrary.Common.dll" >
         <CopyFile Id="cfile1" DestinationProperty="DYNAMICSBIN"/>
         <CopyFile Id="cfilea" DestinationProperty="DYNAMICSWEBBIN"/>
       </File>
       <File Id="fileA6A5ADE82FC3926C6591208B146ABCD"  Source="..\..\bin\Microsoft.Practices.EnterpriseLibrary.Data.dll" >
         <CopyFile Id="cfile2" DestinationProperty="DYNAMICSBIN"/>
         <CopyFile Id="cfileb" DestinationProperty="DYNAMICSWEBBIN"/>
       </File>
       <File Id="fileA87A152C5D90176A5F35A9ED31AABCD"  Source="..\..\bin\Microsoft.Practices.EnterpriseLibrary.Logging.Database.dll" >
         <CopyFile Id="cfile3" DestinationProperty="DYNAMICSBIN"/>
         <CopyFile Id="cfilec" DestinationProperty="DYNAMICSWEBBIN"/>
       </File>
       <File Id="fileA83ADD8942E77F370200E658EAEABCD"  Source="..\..\bin\Microsoft.Practices.EnterpriseLibrary.Logging.dll" >
         <CopyFile Id="cfile4" DestinationProperty="DYNAMICSBIN"/>
         <CopyFile Id="cfiled" DestinationProperty="DYNAMICSWEBBIN"/>
       </File>
       <File Id="fileAE5A8C078462AB1F516A8987676ABCD"  Source="..\..\bin\Microsoft.Practices.ServiceLocation.dll" >
         <CopyFile Id="cfile5" DestinationProperty="DYNAMICSBIN"/>
         <CopyFile Id="cfilee" DestinationProperty="DYNAMICSWEBBIN"/>
       </File>
       <File Id="fileA5CDA0533279F89ACC36D7BDCD6ABCD"  Source="..\..\bin\Microsoft.Practices.Unity.dll" >
         <CopyFile Id="cfile6" DestinationProperty="DYNAMICSBIN"/>
         <CopyFile Id="cfilef" DestinationProperty="DYNAMICSWEBBIN"/>
       </File>
       <File Id="fileAC309FAF27707DCE67A3664FA1FABCD"  Source="..\..\bin\Microsoft.Practices.Unity.Interception.dll" >
         <CopyFile Id="cfile7" DestinationProperty="DYNAMICSBIN"/>
         <CopyFile Id="cfileg" DestinationProperty="DYNAMICSWEBBIN"/>
       </File>
     </Component>
   </Fragment>
   <Fragment>
     <DirectoryRef  Id="INSTALLLOCATION">
       <Directory Id="dirB50C76F5A59FB10334E162992F65AAAA" />
     </DirectoryRef>
   </Fragment>
 </Wix>
Property Definition Sample
 <Property Id="DYNAMICSCRMWEB" Value="C:\Program Files\Microsoft Dynamics CRM\CRMWeb">
   <RegistrySearch Id="Dynamicscrmweb_RegKey" Type="raw" Root="HKLM" Key="SOFTWARE\Microsoft\MSCRM" Name="WebSitePath" Win64="yes"/>
 </Property>
 
 <Property Id="DYNAMICSCRM" >
   <RegistrySearch Id="Dynamics_RegKey" Type="raw" Root="HKLM" Key="SOFTWARE\Microsoft\MSCRM" Name="CRM_Server_InstallDir" Win64="yes"/>
 </Property>
 
 <Property Id="DYNAMICS" >
   <RegistrySearch Id="DynamicsgKey" Type="raw" Root="HKLM" Key="SOFTWARE\Microsoft\MSCRM" Name="roles" Win64="yes"/>
 </Property>
 
 <Property Id="DYNAMICSWEBBIN"/>
 
 <SetProperty Id="DYNAMICSWEBBIN" Value="[DYNAMICSCRMWEB]\bin" After="CostFinalize"/>
 
 <Property Id="DYNAMICSBIN"/>
 
 <SetProperty Id="DYNAMICSBIN" Value="[DYNAMICSCRM]\Server\bin" After="CostFinalize"/>
The next post of the series can be found here

No comments:

Post a Comment