Post date: May 11, 2012 1:33:50 PM
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, Amazon Simple DB, 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>