6

We're trying to implement some dynamically configurable logging into our Azure application and we're using the enterprise libraries to do so which works fine, however the xml required to facilitate this is more complex than the simple 'appSetting' style setting which the ServiceConfiguration.cscfg file seems to accept in that it requires nested xml nodes,

e.g.

<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>

which is resolved by (forgive the formatting in this window please):

<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
    <listeners>
        <add listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.CustomTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
            type="OurSolution.Common.AzureDiagnosticTraceListener, Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
            name="AzureDiagnosticTraceListener" />
    </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" />
    </formatters>
    <categorySources>
        <add switchValue="All" name="General">
            <listeners>
                <add name="AzureDiagnosticTraceListener" />
            </listeners>
        </add>
    </categorySources>
</loggingConfiguration>

I can't see a way of fooling the ServiceDefinition or ServiceConfiguration files to accept this, although if I could I can see a way of telling the enterprise libraries to use the ServiceConfiguration file which I can do in app.config.

Why we are trying to solve this is to allow us to dynamically adjust the settings for the logging, i.e. change from No logging to Verbose without having to do a redeploy, which is proving time consuming and impractical in our live application which has only recently gone live so may still have the odd bug present ;-)

Any thoughts would be most gratefully received Regards Kindo Malay

Kindo Malay
  • 237
  • 1
  • 2
  • 10

2 Answers2

1

At the moment the ServiceConfiguration files are restricted to to basic <Setting name="foo" value="bar" /> structure.

But the value is simply just a string value. What I've done when needing something more expressive is to put the XML as a string in the value of the setting and then deserialize it to XML when I read it out. This does make the config file look pretty ugly when you're editing it directly because it encodes all of the XML in your setting, but it does work.

If we just look at your the listeners section to keep the example small:

<listeners>
    <add listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.CustomTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    type="OurSolution.Common.AzureDiagnosticTraceListener, Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
    name="AzureDiagnosticTraceListener" />
</listeners>

This could be put in the ServiceConfiguration file looking like:

<Setting name="Logging" value="&lt;listeners&gt;&lt;add listenerDataType=&quot;Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.CustomTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&quot; type=&quot;OurSolution.Common.AzureDiagnosticTraceListener, Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&quot; name=&quot;AzureDiagnosticTraceListener&quot; /&gt;&lt;/listeners&gt;" />

The easiest way to do this is to take your source XML, replace all tabs and carriage returns, and update the setting through the cloud project properties settings section.

Altering this once it's been deployed is not entirely straight forward, but doable.

knightpfhor
  • 9,299
  • 3
  • 29
  • 42
1

Other options:

  • Base64 encoding for arbitrary configs and put them into the value of cscfg
  • (my favorite) Simply keep extra configs in the blob storage or database (makes life simpler for managing deployments)
Rinat Abdullin
  • 23,036
  • 8
  • 57
  • 80
  • I like the idea of putting settings in blob storage, but you lose the built in ability to detect config changes. That's not to say you couldn't come up with something yourself to do that. – knightpfhor Nov 03 '10 at 19:31
  • Basically you can just load settings from BLOB only on the start-up and have a side thread that sleeps almost all the time. Once in a few minutes it would check for the changes in BLOB and, if detected, simply ask Management API to restart worker. – Rinat Abdullin Nov 04 '10 at 13:05
  • We went a different way in the end but thanks very much for the information – Kindo Malay Apr 12 '11 at 05:19