Logging API - quandis/qbo3-Documentation GitHub Wiki

Logging Overview

Given the inclusion of Microsoft's ETL Logging pattern in QBO 3, we can leverage logging in a number of interesting ways, including:

  • Tracking performance (execution time) of methods and statements,
  • Tracking time spent on the phone by agents doing skip tracing,
  • Tracking who is executing "sensitive" methods or statements

Background

The ETL Logging pattern has some very nice features, including:

  • It is very lightweight, having minimal impact on the performance of code calling logging methods
  • If a log is broken, errors are not raised in code
  • Logging can be turned on or off from a configuration file (web.config)
  • When logging an activity, one can data-drive which logging sinks should record the activity
  • Custom logging sinks are easy to write, enabling us to log to a text file, Azure ApplicationInsights, Amazon Xray Tracing, our own Message or LedgerItem tables

Audit Logging

Each method or statement can include an Audit property, with a string of categories to log to. Examples:

In Decision.config:

<Statement Name="Cancel" Query="UPDATE Decision SET CanceledDate=GETDATE()..." Audit="SecurityLog"/>
<Statement Name="ProcessStep" Query="..." Audit="BillingLog, SecurityLog"/>

In PaymentMessage.config

<Statement Name="StartCall" Query="..." Audit="AgentLog, BillingLog"/>

In ContactMethod.cs

[Audit("AgentLog")]
public void CallOutbound(string phoneNumber) {...}

Configuration

In web.config, the logging section can be configured like this:

<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
 <!-- These are the "sinks": classes we write to save logging data somewhere -->
 <listeners>
   <add name="FlatFile" type="..." listenerDataType="..." fileName="flatFile.log" formatter="Text Formatter" rollInterval="Day" />
   <add name="LedgerItem" type="..." listenerDataType="..." rollInterval="Month" formatter="Ledger Formatter" />
   <add name="Message" type="..." listenerDataType="..." formatter="Message Formatter" /> 
   <add name="SkipTraceMessage" type="..." listenerDataType="..." formatter="SkipTrace Message" /> 
   ...
 </listeners>
 <!-- These allow a sink to data-drive the "body" of the log -->
 <formatters>
   <add type="..." template="{templated data goes here, including method and parameters}" name="Text Formatter" />
   <add type="..." template="{templated data goes here, including method and parameters}" name="Message Formatter" />
   <add type="..." template="{templated data goes here, including method and parameters}" name="SkipTrace Message" />
 </formatters>
 <!-- This allows turning all, or partial, logging on or off -->
 <logFilters>
   <add type="..." enabled="true" name="Logging Enabled Filter" />
 </logFilters>
 <-- This is where we map what audited logs are actually written to; if there is no listener defined, the log can be ignored -->
 <categorySources>
   <add switchValue="All" name="BillingLog">
     <listeners>
       <add name="LedgerItem" />
     </listeners>
   </add>
   <add switchValue="All" name="AgentLog">
     <listeners>
       <add name="Message" />
     </listeners>
   </add>
 </categorySources>
</loggingConfiguration>
⚠️ **GitHub.com Fallback** ⚠️