Configuration based Service Bus ConnectionStatusBehavior to monitor relay connectivity
Sometime it requires to monitor Service Bus relay connectivity. ConnectionStatusBehavior allows us to monitor the same through Connecting, Online and Offline events. However, it requires to modify the code to handle these events if listener doesn’t have the same implemented already, and most of the times this is the case. However, when there’s situation to monitor the Service Bus connectivity in crisis, there’s no option but to modify the code of relay listener.
Many of us know customers’ concerns when we request them to apply ConnectionStatusBehavior to monitor Service Bus relay connectivity. Their concerns are valid to some extent as we’re requesting them to add code in their application to log monitoring events which requires rebuilding and redeploying relay listener in production L.
Thus, many of us have a demand if there’s an option to apply Service Bus ConnectionStatusBehavior on relay endpoint through configuration which emits connectivity events.
Good news, we’ve created a ConnectionStatusBehavior behavior extension (let’s name it ConnectionStatusBehaviorExtention) which allows to apply ConnectionStatusBehavior on endpoint through configuration. Please find the binaries in attached ConnectionStatusElementExtended.zip file.
ConnectionStatusBehaviorExtention can be applied following below simple steps,
a) Copy ConnectionStatusElementExtended.dll (in attached zip file) under WCF Relay service installation folder (bin)
b) Open WCF Relay Service configuration (i.e. Web.config),
I. Add following configuration under <system.serviceModel>\<behaviorExtensions> element to register ConnectionStatusBehaviorExtention,
<addname="connectionStatusBehaviorExtention"type="ConnectionStatusElementExtended.ConnectionStatusExtendedBehaviorElement, ConnectionStatusElementExtended" />
II. Then, add following configuration under endpointBehavior used by relay endpoint to apply above defined behavior extension. This is the line which applies our extended ConnectionStatusBehaviorExtension on relay endpoint
<connectionStatusBehaviorExtention />
III. I have built ConnectionStatusBehaviorExtention referencing Microsoft.ServiceBus.dll v2.7.00. Considering Microsoft.ServiceBus.dll assembly version changes frequently and assembly is signed, we’d need following configuration to be applied to redirect .net runtime to use Microsoft.ServiceBus.dll used by customer’s WCF Relay Service. Define Microsoft.ServiceBus.dll version used by WCF relay service (listener) under newVersion configuration (highlighted).
<runtime>
<assemblyBindingxmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentityname="Microsoft.ServiceBus"publicKeyToken="31bf3856ad364e35"culture="neutral" />
<!-- Assembly versions can be redirected in app, publisher policy, or machine configuration files. -->
<bindingRedirectoldVersion="2.7.0.0"newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
For example, based on above configuration, my WCF Relay Service on which ConnectionStatusBehaviorExtention is applied seems to be using Microsoft.ServiceBus.dll v3.0.0.0.
Please note that the version number is to be taken from Microsoft.ServiceBus.dll assembly name, it’s not the file version.
That’s it! With above simple steps ConnectionStatusBehaviorExtention is applied and ready to log the connection event information.
Where’re the logs Written?
======================
a) ConnectionStatusBehaviorExtention logs the events in Application eventlog with Source: Microsoft.ServiceBus.ConnectStatus. The event ids are between 990-992. You can try filtering the event log to view events based on Source Microsoft.ServiceBus.ConnectStatus or event id range 990 - 992.
b) I’ve also added tracing feature built on top of System.Diagnostics to allow emit trace events using different TraceListeners (Similar like WCF tracing or System.Net tracing). The trace source name is same: Microsoft.ServiceBus.ConnectStatus.
Capturing these traces should be extremely useful in situations where we need to correlate the connectivity traces with WCF traces or confirm the callstacks responsible for emitting the events i.e. online or offline.
here’s the sample configuration which can be used to emit events using XmlWriterTraceListener.
<system.diagnostics>
<sources>
<sourcename="Microsoft.ServiceBus.ConnectStatus"switchValue="Information">
<listeners>
<addname="ConnectStatusTraceListener">
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<addinitializeData="connection_tracelog.svclog"type="System.Diagnostics.XmlWriterTraceListener"
name="ConnectStatusTraceListener"traceOutputOptions="Timestamp, ProcessId, ThreadId, Callstack">
</add>
</sharedListeners>
<traceautoflush="true" />
</system.diagnostics>
Here's a sample WCF Relay listener service configuration which uses extended ConnectionStatusBehavior on relay endpoints (Please see the highlighted text),
<runtime>
<assemblyBindingxmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentityname="Microsoft.ServiceBus"publicKeyToken="31bf3856ad364e35"culture="en-us" />
<!-- Assembly versions can be redirected in app, publisher policy, or machine configuration files. -->
<bindingRedirectoldVersion="2.7.0.0"newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.serviceModel>
<services>
<servicebehaviorConfiguration="HelloServiceBus.HelloServiceBus"name="HelloServiceBus.HelloServiceBus">
<endpointaddress="https://xxxx.servicebus.windows.net/netrelay"behaviorConfiguration="sharedSecretClientCredentials"binding="basicHttpRelayBinding"bindingConfiguration="HttpRelayEndpointConfig"
contract="HelloServiceBus.IHelloServiceBus"/>
</service>
</services>
<bindings>
<basicHttpRelayBinding>
<!--<binding name="HttpRelayEndpointConfig" proxyAddress="sproxy-se.corp.vattenfall.com:8086" useDefaultWebProxy="false" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:05:00" sendTimeout="00:05:00">-->
<bindingname="HttpRelayEndpointConfig">
<readerQuotasmaxDepth="2147483647"maxStringContentLength="2147483647"maxArrayLength="2147483647"maxBytesPerRead="2147483647"maxNameTableCharCount="2147483647" />
<securityrelayClientAuthenticationType="RelayAccessToken" />
</binding>
</basicHttpRelayBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behaviorname="sharedSecretClientCredentials">
<connectionStatusBehaviorExtention />
<serviceRegistrySettingsdiscoveryMode="Public" />
<transportClientEndpointBehavior>
<tokenProvider>
<sharedAccessSignaturekeyName="XXX"key="XXX"/>
</tokenProvider>
</transportClientEndpointBehavior>
<!--<ServiceRegistrySettings discoveryMode="Public" />-->
</behavior>
</endpointBehaviors>
...
...
</behaviors>
<extensions>
<!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
<behaviorExtensions>
<addname="connectionStatusBehaviorExtention"type="ConnectionStatusElementExtended.ConnectionStatusExtendedBehaviorElement, ConnectionStatusElementExtended" />
<addname="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<addname="serviceRegistrySettings"
type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
...
...
</extensions>
</system.serviceModel>