Skip to content

Commit

Permalink
AWS SDK clients instrumentation (#44)
Browse files Browse the repository at this point in the history
* AWS SDK instrumentation initial commit

* AWS SDK instrumentation initial commit

* Adding http status code and response content length. Adding status on exception.

* Adding UnitTests and helper tools for AWS SDK client instrumentation

* Adding a semantic convention file for AWS specific attributes

* Renaming files, some code refactors

* Fixing typo in Opentelemetry namespace

* Changing from AddTag to SetTag on activity

* Adding Unset status for successful request

* Fixed condition check on Status. Adding proper response to SQS test otherwise it fails

* Adding tests for .net452 and helper code for mocking the http layer

* Adding README for AWS client instrumentation usage

* Fixing typo in readme

* Adding fallback to fetch region from ServiceURL if RegionEndpoint is null

* Changing the namespace to make it similar in structure with other instrumentations

* Adding options for AWS client instrumentation. Suppressing downstream http instrumentation. Updating readme.

* only adding info if the isAllDataRequested is true for the activity

* Moving AWS instrumentation to its own project

* Minor fixes

* Adding readme

* Update README.md

* Moving implementation specific classes to Implementation folder

* Self implementation of GetTagValue method

* Unit test fixes. Using TagObjects

* Adding minver tag prefix and release workflow file

* Removed assembily signed check. Added await to async operations in tests.

* Some null checks before string opserations

* Remove explicit setting status to Unset for successful requests
  • Loading branch information
srprash authored Feb 23, 2021
1 parent 2aedf32 commit 0a4307d
Show file tree
Hide file tree
Showing 24 changed files with 1,836 additions and 37 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/package-Instrumentation.AWS.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Pack OpenTelemetry.Contrib.Instrumentation.AWS

on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
push:
tags:
- 'Instrumentation.AWS-*' # trigger when we create a tag with prefix "Instrumentation.AWS-"

jobs:
build-test-pack:
runs-on: ${{ matrix.os }}
env:
PROJECT: OpenTelemetry.Contrib.Instrumentation.AWS

strategy:
matrix:
os: [windows-latest]

steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # fetching all

- name: Install dependencies
run: dotnet restore

- name: dotnet build ${{env.PROJECT}}
run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true

- name: dotnet test ${{env.PROJECT}}
run: dotnet test test/${{env.PROJECT}}

- name: dotnet pack ${{env.PROJECT}}
run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build

- name: Publish Artifacts
uses: actions/upload-artifact@v2
with:
name: ${{env.PROJECT}}-packages
path: '**/${{env.PROJECT}}/bin/**/*.*nupkg'

- name: Publish MyGet
run: |
nuget setApiKey ${{ secrets.MYGET_TOKEN }} -Source https://www.myget.org/F/opentelemetry-contrib/api/v2/package
nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://www.myget.org/F/opentelemetry-contrib/api/v2/package
14 changes: 14 additions & 0 deletions opentelemetry-dotnet-contrib.sln
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exten
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AWSXRay.Tests", "test\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj", "{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWS", "src\OpenTelemetry.Contrib.Instrumentation.AWS\OpenTelemetry.Contrib.Instrumentation.AWS.csproj", "{970673DA-F308-4960-A58D-ECCEA44CEF6B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Contrib.Instrumentation.AWS.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWS.Tests\OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj", "{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -125,6 +129,14 @@ Global
{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Release|Any CPU.Build.0 = Release|Any CPU
{970673DA-F308-4960-A58D-ECCEA44CEF6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{970673DA-F308-4960-A58D-ECCEA44CEF6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{970673DA-F308-4960-A58D-ECCEA44CEF6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{970673DA-F308-4960-A58D-ECCEA44CEF6B}.Release|Any CPU.Build.0 = Release|Any CPU
{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -143,6 +155,8 @@ Global
{899E506C-8525-4471-8C6D-5A9FA6B8517B} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{970673DA-F308-4960-A58D-ECCEA44CEF6B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
<Description>OpenTelemetry extensions for AWS X-Ray.</Description>
<MinVerTagPrefix>Extensions.AWSXRay-</MinVerTagPrefix>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="OpenTelemetry" Version="1.0.1" />
</ItemGroup>

</Project>
36 changes: 0 additions & 36 deletions src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,42 +140,6 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder()
Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator());
```

### Instrumenting AWS SDK

For tracing downstream call to AWS services from your .Net application,
you will need three components: the `AWSXRayIdGenerator`,
the `AWSXRayPropagator`, and the AWS client instrumentation.

Download the `OpenTelemetry.Contrib.Extensions.AWSXRay` package:

```shell
dotnet add package OpenTelemetry.Contrib.Extensions.AWSXRay
```

Add the `AWSXRayIdGenerator`, `AWSXRayPropagator` and `AWSInstrumentation`
to your application. The below example is for an ASP.Net Core application.

```csharp
using OpenTelemetry;
using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace;
using OpenTelemetry.Trace;

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOpenTelemetryTracing((builder) => builder
// for generating AWS X-Ray compliant trace IDs
.AddXRayTraceId()
// for tracing calls to AWS services via AWS SDK for .Net
.AddAWSInstrumentation()
.AddAspNetCoreInstrumentation()
.AddOtlpExporter());

// configure AWSXRayPropagator
Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator());
}
```

### Adding Custom Attributes

You can add custom attributes to an `Activity` by calling
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// <copyright file="AWSClientInstrumentationOptions.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>

namespace OpenTelemetry.Contrib.Instrumentation.AWS
{
/// <summary>
/// Options for AWS client instrumentation.
/// </summary>
public class AWSClientInstrumentationOptions
{
/// <summary>
/// Gets or sets a value indicating whether downstream Http instrumentation is suppressed.
/// </summary>
public bool SuppressDownstreamInstrumentation { get; set; } = true;
}
}
19 changes: 19 additions & 0 deletions src/OpenTelemetry.Contrib.Instrumentation.AWS/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// <copyright file="AssemblyInfo.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.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.AWS.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// <copyright file="AWSClientsInstrumentation.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 Amazon.Runtime.Internal;

namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation
{
internal class AWSClientsInstrumentation
{
public AWSClientsInstrumentation(AWSClientInstrumentationOptions options)
{
RuntimePipelineCustomizerRegistry.Instance.Register(new AWSTracingPipelineCustomizer(options));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// <copyright file="AWSSemanticConventions.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>

namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation
{
internal static class AWSSemanticConventions
{
public const string AttributeAWSServiceName = "aws.service";
public const string AttributeAWSOperationName = "aws.operation";
public const string AttributeAWSRegion = "aws.region";
public const string AttributeAWSRequestId = "aws.requestId";

public const string AttributeAWSDynamoTableName = "aws.table_name";
public const string AttributeAWSSQSQueueUrl = "aws.queue_url";

public const string AttributeHttpStatusCode = "http.status_code";
public const string AttributeHttpResponseContentLength = "http.response_content_length";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// <copyright file="AWSTracingPipelineCustomizer.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 Amazon.Runtime;
using Amazon.Runtime.Internal;

namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation
{
internal class AWSTracingPipelineCustomizer : IRuntimePipelineCustomizer
{
private readonly AWSClientInstrumentationOptions options;

public AWSTracingPipelineCustomizer(AWSClientInstrumentationOptions options)
{
this.options = options;
}

public string UniqueName
{
get
{
return "AWS Tracing Registration Customization";
}
}

public void Customize(Type serviceClientType, RuntimePipeline pipeline)
{
if (serviceClientType.BaseType != typeof(AmazonServiceClient))
{
return;
}

pipeline.AddHandlerAfter<EndpointResolver>(new AWSTracingPipelineHandler(this.options));
}
}
}
Loading

0 comments on commit 0a4307d

Please sign in to comment.