1

I'm trying to use Semantic Logging Application Block to store logs into Azure Table Storage. Setup:

ObservableEventListener listener1 = new ObservableEventListener();
var conString =
    $"DefaultEndpointsProtocol={CloudStorageAccount.DevelopmentStorageAccount.TableEndpoint.Scheme};" +
    $"AccountName={CloudStorageAccount.DevelopmentStorageAccount.Credentials.AccountName};" +
    $"AccountKey={Convert.ToBase64String(CloudStorageAccount.DevelopmentStorageAccount.Credentials.ExportKey())}";
    
listener1.LogToWindowsAzureTable( // <---- EXCEPTION HERE
        instanceName: "instName",
        connectionString: conString);

I'm getting a strange exception:

Exception thrown: 'System.MissingMethodException' in Microsoft.Practices.EnterpriseLibrary.SemanticLogging.WindowsAzure.dll

Additional information: Method not found: 'Void Microsoft.WindowsAzure.Storage.Table.CloudTableClient.set_RetryPolicy(Microsoft.WindowsAzure.Storage.RetryPolicies.IRetryPolicy)'.

I have the same issue with a real account. Packages versions (all of them are from NuGet):

  • EnterpriseLibrary.SemanticLogging — 2.0.1406.1
  • EnterpriseLibrary.SemanticLogging.WindowsAzure — 2.0.1406.1
  • WindowsAzure.Storage — 7.0.0

How can I track the source of the exception? Google says nothing about the method that is not found. A project to test on your machine is here.

Community
  • 1
  • 1
cassandrad
  • 3,412
  • 26
  • 50
  • Note that uploading logs to Azure Tables is nice, but uploading them to Application Insights (AI) is even better: https://github.com/fidmor89/SLAB_AppInsights. If you have the Standard or Premium tier you can then configure Continuous Export to Table Storage and get that for free... – Ohad Schneider Aug 13 '16 at 09:18

2 Answers2

3

The reason you're getting this error is because SLAB is dependent on storage client library 3.0.2.0 (source) and setting Retry Policies on client (CloudTableClient for example) was deprecated in version 4.0.0.0 (source) and removed in some later version (not sure which one).

Because you're using version 7.x of storage client library, the method to set RetryPolicy on CloudTableClient is not there and hence you're getting this error.

Gaurav Mantri
  • 128,066
  • 12
  • 206
  • 241
1

Like Guarav said, SLAB is built against a very old version of Microsoft.WindowsAzure.Storage. The problem is this line, using client.RetryPolicy instead of client.DefaultRequestOptions.RetryPolicy. I tried updating the NuGet packages and change it but it seemed to break some tests and it didn't seem trivial to fix them. Also it looks like 4.6 support is not there: https://github.com/mspnp/semantic-logging/issues/64.

There's a defect for it here: https://github.com/mspnp/semantic-logging/issues/81, but I doubt anything is going to happen with it any time soon (if ever). I'll probably end up writing some simple sink that redirects the logs to a Trace Listener for Azure to take care of (including Table Storage upload).

EDIT here's the code (not tested yet):

public class SystemDiagnosticsTraceSink : IObserver<EventEntry>
{
    public void OnNext(EventEntry entry)
    {
        if (entry == null) return;
        using (var writer = new StringWriter())
        {
            new EventTextFormatter().WriteEvent(entry, writer);
            var eventText = writer.ToString();
            switch (entry.Schema.Level)
            {
                case EventLevel.LogAlways:
                case EventLevel.Critical:
                case EventLevel.Error:
                    Trace.TraceError(eventText);
                    return;
                case EventLevel.Warning:
                    Trace.TraceWarning(eventText);
                    return;
                case EventLevel.Informational:
                case EventLevel.Verbose:
                    Trace.TraceInformation(eventText);
                    return;
                default:
                    Trace.TraceError("Unknown event level: " + entry.Schema.Level);
                    Trace.TraceInformation(eventText);
                    return;
            }
        }
    }
    public void OnError(Exception error)
    {} //you might want to do something here
    public void OnCompleted()
    {} //nothing to do
}

And the extension class:

public static class SystemDiagnosticsTraceSinkExtensions
{
    public static SinkSubscription<SystemDiagnosticsTraceSink> LogToSystemDiagnosticsTrace
      (this IObservable<EventEntry> eventStream)
    {
        if (eventStream == null) throw new ArgumentNullException(nameof(eventStream));

        var sink = new SystemDiagnosticsTraceSink();
        return new SinkSubscription<SystemDiagnosticsTraceSink>(
                       eventStream.Subscribe(sink), sink);
    }
}
Ohad Schneider
  • 36,600
  • 15
  • 168
  • 198