Skip to content

Commit

Permalink
WCF: Added TelemetryContractBehaviorAttribute to support programmatic…
Browse files Browse the repository at this point in the history
… configuration (#153)

* Added TelemetryContractBehaviorAttribute to support programmatic configuration.

* Updated PR link in README

* Lint

* Lint 2
  • Loading branch information
CodeBlanch authored Sep 13, 2021
1 parent b907e05 commit 844a3cf
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 17 deletions.
6 changes: 5 additions & 1 deletion src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# Changelog

## Unreleased
## 1.0.0-rc3

* Added `TelemetryServiceBehavior`. **Breaking change** (config update
required): Renamed `TelemetryBehaviourExtensionElement` ->
`TelemetryEndpointBehaviorExtensionElement`
([#152](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/152))

* Added `TelemetryContractBehaviorAttribute` which can be used for programmatic
configuration of WCF services & clients
([#153](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/153))

## 1.0.0-rc2

* Updated OTel SDK package version to 1.1.0-beta1
Expand Down
29 changes: 27 additions & 2 deletions src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,11 @@ Example project available in

## WCF Server Configuration (.NET Framework)

Add the `IDispatchMessageInspector` instrumentation via an endpoint behavior
extension on the service endpoints you want to instrument:
### Option 1: Instrument by endpoint

To add the `IDispatchMessageInspector` instrumentation to select endpoints of a
service, use the endpoint behavior extension on the service endpoints you want
to instrument:

<!-- markdownlint-disable MD013 -->
```xml
Expand Down Expand Up @@ -149,6 +152,8 @@ Example project available in
[examples/wcf/server-netframework](../../examples/wcf/server-netframework/)
folder.

### Option 2: Instrument by service

To add the `IDispatchMessageInspector` instrumentation for all endpoints of a
service, use the service behavior extension on the services you want to
instrument:
Expand Down Expand Up @@ -192,6 +197,26 @@ instrument:
```
<!-- markdownlint-enable MD013 -->

## WCF Programmatic Configuration Server and/or Client (.NET Framework + .NET Core)

To add `IDispatchMessageInspector` for servers (.NET Framework only) and/or
`IClientMessageInspector` for clients (.NET Framework & .NET Core)
programmatically, use the `TelemetryContractBehaviorAttribute` on the service
contracts you want to instrument:

```csharp
[ServiceContract(
Namespace = "http://opentelemetry.io/",
Name = "StatusService",
SessionMode = SessionMode.Allowed)]
[TelemetryContractBehavior]
public interface IStatusServiceContract
{
[OperationContract]
Task<StatusResponse> PingAsync(StatusRequest request);
}
```

## References

* [OpenTelemetry Project](https://opentelemetry.io/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// <copyright file="TelemetryContractBehaviorAttribute.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace OpenTelemetry.Contrib.Instrumentation.Wcf
{
#if NETFRAMEWORK
/// <summary>
/// An <see cref="IContractBehavior"/> <see cref="Attribute"/> to add the
/// <see cref="TelemetryDispatchMessageInspector"/> to service operations
/// and <see cref="TelemetryClientMessageInspector"/> to client operations
/// programmatically.
/// </summary>
#else
/// <summary>
/// An <see cref="IContractBehavior"/> <see cref="Attribute"/> to add the
/// <see cref="TelemetryClientMessageInspector"/> to client operations
/// programmatically.
/// </summary>
#endif
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
public class TelemetryContractBehaviorAttribute : Attribute, IContractBehavior
{
/// <inheritdoc />
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}

/// <inheritdoc />
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
TelemetryEndpointBehavior.ApplyClientBehaviorToClientRuntime(clientRuntime);
}

/// <inheritdoc />
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
#if NETFRAMEWORK
TelemetryEndpointBehavior.ApplyDispatchBehaviorToEndpoint(dispatchRuntime.EndpointDispatcher);
#endif
}

/// <inheritdoc />
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,7 @@ public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterColle
/// <inheritdoc/>
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
var actionMappings = new Dictionary<string, ActionMetadata>(StringComparer.OrdinalIgnoreCase);

foreach (var clientOperation in clientRuntime.ClientOperations)
{
actionMappings[clientOperation.Action] = new ActionMetadata
{
ContractName = $"{clientRuntime.ContractNamespace}{clientRuntime.ContractName}",
OperationName = clientOperation.Name,
};
}

clientRuntime.ClientMessageInspectors.Add(new TelemetryClientMessageInspector(actionMappings));
ApplyClientBehaviorToClientRuntime(clientRuntime);
}

/// <inheritdoc/>
Expand All @@ -71,6 +60,22 @@ public void Validate(ServiceEndpoint endpoint)
{
}

internal static void ApplyClientBehaviorToClientRuntime(ClientRuntime clientRuntime)
{
var actionMappings = new Dictionary<string, ActionMetadata>(StringComparer.OrdinalIgnoreCase);

foreach (var clientOperation in clientRuntime.ClientOperations)
{
actionMappings[clientOperation.Action] = new ActionMetadata
{
ContractName = $"{clientRuntime.ContractNamespace}{clientRuntime.ContractName}",
OperationName = clientOperation.Name,
};
}

clientRuntime.ClientMessageInspectors.Add(new TelemetryClientMessageInspector(actionMappings));
}

#if NETFRAMEWORK
internal static void ApplyDispatchBehaviorToEndpoint(EndpointDispatcher endpointDispatcher)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// limitations under the License.
// </copyright>

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
Expand Down

0 comments on commit 844a3cf

Please sign in to comment.