Skip to content

Commit

Permalink
Redis instrumentation with ActivitySource by Eddy & Mike (#800)
Browse files Browse the repository at this point in the history
* Attempting to get Redis instrumentation up and working using ActivitySource API.

* updating tests

* renaming and updating tests

* Test fixes.

* Fixed Redis net461 tests failing on connection.

* Redis integration tests and bug fixes.

* Adding tests

* Put back redis connection options.

* Updates for changes in master.

* adding comments to testRedis

* updating based on comments

* updating summary

* Switched a couple spots using string keys to constants.

* Redis integration tests

* Small tweak to the GitHub action to make it more consistent with the others.

* Made instrumentation internal. Updated README.

* rename MaxFlushInterval to FlushInterval, adding flushInterval to samples

* Removed running of non-integration tests from Redis dockerfile.

Co-authored-by: Eddy Nakamura <eddynaka@gmail.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
  • Loading branch information
3 people authored Jul 14, 2020
1 parent 3214f1c commit 9298e0e
Show file tree
Hide file tree
Showing 27 changed files with 674 additions and 332 deletions.
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/docker-compose*
**/Dockerfile*
**/bin
**/obj
**/*.yaml
**/*.yml
**/*.md
**/*.ps1
15 changes: 15 additions & 0 deletions .github/workflows/integration-redis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Redis Integration Tests

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build-compose-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run redis docker-compose.integration
run: docker-compose --file=test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.integration.yml --project-directory=. up --exit-code-from=redis_integration_tests --build
2 changes: 2 additions & 0 deletions OpenTelemetry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Tests", "test
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B7408D66-487A-40E1-BDB7-BC17BD28F721}"
ProjectSection(SolutionItems) = preProject
.dockerignore = .dockerignore
.editorconfig = .editorconfig
CHANGELOG.md = CHANGELOG.md
CONTRIBUTING.md = CONTRIBUTING.md
Expand Down Expand Up @@ -120,6 +121,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
.github\workflows\dotnet-core-linux.yml = .github\workflows\dotnet-core-linux.yml
.github\workflows\dotnet-core-win.yml = .github\workflows\dotnet-core-win.yml
.github\workflows\dotnet-core.yml = .github\workflows\dotnet-core.yml
.github\workflows\integration-redis.yml = .github\workflows\integration-redis.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C1542297-8763-4DF4-957C-489ED771C21D}"
Expand Down
2 changes: 1 addition & 1 deletion build/Common.prod.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<ItemGroup>
<PackageReference Include="MinVer" Version="2.3.0">
<PackageReference Include="MinVer" Version="2.3.0" Condition="'$(IntegrationBuild)' != 'true'">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
2 changes: 1 addition & 1 deletion samples/Exporters/Console/Exporters.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.3.0" />
<PackageReference Include="StackExchange.Redis" Version="2.0.519" />
<PackageReference Include="StackExchange.Redis" Version="2.1.58" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion samples/Exporters/Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class Program
/// <param name="args">Arguments from command line.</param>
public static void Main(string[] args)
{
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, HttpClientOptions, ZPagesOptions, ConsoleOptions, OtlpOptions>(args)
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, HttpClientOptions, RedisOptions, ZPagesOptions, ConsoleOptions, OtlpOptions>(args)
.MapResult(
(JaegerOptions options) => TestJaegerExporter.Run(options.Host, options.Port),
(ZipkinOptions options) => TestZipkinExporter.Run(options.Uri),
Expand Down
33 changes: 22 additions & 11 deletions samples/Exporters/Console/TestRedis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;

using OpenTelemetry.Instrumentation.StackExchangeRedis;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Configuration;

using StackExchange.Redis;

namespace Samples
Expand All @@ -28,8 +30,19 @@ internal class TestRedis
{
internal static object Run(string zipkinUri)
{
// connect to the server
var connection = ConnectionMultiplexer.Connect("localhost:6379");
/*
* Setup redis service inside local docker.
* docker run --name opentelemetry-redis-test -d -p 6379:6379 redis
*
* If you face any issue with the first command, do the following ones:
* docker exec -it opentelemetry-redis-test sh
* redis-cli
* set bind 0.0.0.0
* save
*/

// connect to the redis server. The default port 6379 will be used.
var connection = ConnectionMultiplexer.Connect("localhost");

// Configure exporter to export traces to Zipkin
using var openTelemetry = OpenTelemetrySdk.EnableOpenTelemetry(
Expand All @@ -39,13 +52,11 @@ internal static object Run(string zipkinUri)
o.ServiceName = "redis-test";
o.Endpoint = new Uri(zipkinUri);
})
// TODO: Uncomment when we change Redis to Activity mode
// .AddInstrumentation(t =>
// {
// var instrumentation = new StackExchangeRedisCallsInstrumentation(t);
// connection.RegisterProfiler(instrumentation.GetProfilerSessionsFactory());
// return instrumentation;
// })
.AddRedisInstrumentation(connection, options =>
{
// changing flushinterval from 10s to 5s
options.FlushInterval = TimeSpan.FromSeconds(5);
})
.AddActivitySource("redis-test"));

ActivitySource activitySource = new ActivitySource("redis-test");
Expand Down Expand Up @@ -88,8 +99,8 @@ private static void DoWork(IDatabase db, ActivitySource activitySource)
catch (ArgumentOutOfRangeException e)
{
// Set status upon error
activity.AddTag("ot.status", SpanHelper.GetCachedCanonicalCodeString(Status.Internal.CanonicalCode));
activity.AddTag("ot.status_description", e.ToString());
activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(Status.Internal.CanonicalCode));
activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, e.ToString());
}

// Annotate our activity to capture metadata about our operation
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Import Project="..\Directory.Build.targets" Condition="Exists('..\Directory.Build.targets')" />

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-*">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-*" Condition="'$(IntegrationBuild)' != 'true'">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// <copyright file="RedisProfilerEntryToActivityConverter.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.Collections.Generic;
using System.Diagnostics;
using System.Net;
using OpenTelemetry.Trace;
using StackExchange.Redis.Profiling;

namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation
{
internal static class RedisProfilerEntryToActivityConverter
{
public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfiledCommand command)
{
var name = command.Command; // Example: SET;
if (string.IsNullOrEmpty(name))
{
name = StackExchangeRedisCallsInstrumentation.ActivityName;
}

var activity = StackExchangeRedisCallsInstrumentation.ActivitySource.StartActivity(
name,
ActivityKind.Client,
parentActivity?.Context ?? default,
startTime: command.CommandCreated);

if (activity == null)
{
return null;
}

if (activity.IsAllDataRequested == true)
{
// see https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/database.md

// Timing example:
// command.CommandCreated; //2019-01-10 22:18:28Z

// command.CreationToEnqueued; // 00:00:32.4571995
// command.EnqueuedToSending; // 00:00:00.0352838
// command.SentToResponse; // 00:00:00.0060586
// command.ResponseToCompletion; // 00:00:00.0002601

// Total:
// command.ElapsedTime; // 00:00:32.4988020

activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(StatusCanonicalCode.Ok));
activity.AddTag(SpanAttributeConstants.DatabaseSystemKey, "redis");
activity.AddTag(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName, command.Flags.ToString());

if (command.Command != null)
{
// Example: "db.statement": SET;
activity.AddTag(SpanAttributeConstants.DatabaseStatementKey, command.Command);
}

if (command.EndPoint != null)
{
if (command.EndPoint is IPEndPoint ipEndPoint)
{
activity.AddTag(SpanAttributeConstants.NetPeerIp, ipEndPoint.Address.ToString());
activity.AddTag(SpanAttributeConstants.NetPeerPort, ipEndPoint.Port.ToString());
}
else if (command.EndPoint is DnsEndPoint dnsEndPoint)
{
activity.AddTag(SpanAttributeConstants.NetPeerName, dnsEndPoint.Host);
activity.AddTag(SpanAttributeConstants.NetPeerPort, dnsEndPoint.Port.ToString());
}
else
{
activity.AddTag(SpanAttributeConstants.PeerServiceKey, command.EndPoint.ToString());
}
}

activity.AddTag(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName, command.Db.ToString());

// TODO: deal with the re-transmission
// command.RetransmissionOf;
// command.RetransmissionReason;

var enqueued = command.CommandCreated.Add(command.CreationToEnqueued);
var send = enqueued.Add(command.EnqueuedToSending);
var response = send.Add(command.SentToResponse);

activity.AddEvent(new ActivityEvent("Enqueued", enqueued));
activity.AddEvent(new ActivityEvent("Sent", send));
activity.AddEvent(new ActivityEvent("ResponseReceived", response));

activity.SetEndTime(command.CommandCreated + command.ElapsedTime);
}

activity.Stop();

return activity;
}

public static void DrainSession(Activity parentActivity, IEnumerable<IProfiledCommand> sessionCommands)
{
foreach (var command in sessionCommands)
{
ProfilerCommandToActivity(parentActivity, command);
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<ItemGroup>
<ProjectReference Include="..\OpenTelemetry\OpenTelemetry.csproj" />
<PackageReference Include="StackExchange.Redis" Version="2.0.519" />
<PackageReference Include="StackExchange.Redis" Version="2.1.58" />
</ItemGroup>

</Project>
Loading

0 comments on commit 9298e0e

Please sign in to comment.