Skip to content
This repository was archived by the owner on Dec 18, 2023. It is now read-only.

Commit 819277f

Browse files
Simon ZeltserSergeyKanzhelev
authored andcommitted
Adding Opencensus c# headers when sending data to Stackdriver (#78)
* Introducing Stackdriver Exporter for Opencensus C# library - Current implementation can only store string values - Added the exporter and trace handler only - The exporter relies on newest Trace API from Stackdriver. * Updating translation from ISpan to Stackdriver's Span to cover more fields * Fixing the issue that prevented Stackdriver API call to succeed: now construction of Span resource is taken care of by SpanName class that is part of Stackdriver Trace V2 API. * - Added support for capturing all types of trace spans (long/bool/string) - Fixed csproj, so it produces both .NET Core and .NET versions. It also means signing the assembly using the same mechanism as other assemblies in the solution * - Added support for storing links - Minor fixes to proto<->opencensus translation methods * Fixing merge issue * Added command line support for the Samples project. This will make it easier to script testing multiple exporters as well as prevent commenting and uncommenting different test procedures for different exporters. Finally, it will making test code cleaner for showing samples embedded in documentation website. In order to test the exporter, you can either execute it from the command line: samples.dll prometheus or to debug using Visual Studio: Debug => Sample Properties => Debug. Now create a profile for your testing execution and fill application arguments if needed. Now choose your profile in running configuration of Visual Studio. Running settings are local to the machine and are ignored in PRs. * Adding sceleton of metrics support in Stackdriver Exporter. Currently we can't detect all types of monitoring resources but we can ship the batches of metrics with time series to Stackdriver. Thorough testing TBD * Fixing a few bugs in Stackdriver metrics exporter - Small refactoring - Assinging default values for time intervals * - Fixing a few bugs around metric creation and labels - Refactoring MetricsConversions - Fixing stackdriver stats configuration - population of default resource and projects * First working version of Stackdriver Stats Exporter. 1) Fixed bugs related to Stackdriver Metrics Descriptor creation 2) Renamed Metrics Exporter to Stats Exporter to follow Opencensus terminology 3) Cache Stackdriver Metrics Descriptors locally so it's easy which descriptor holds the time series to upload 4) Fixed test code that was producing the metrics using Opencensus and uploading it to Stackdriver 5) Minor refactoring Current limitations: 1) Supporting only string labels 2) We support only "Global" monitored resource. We need to detect dynamically where the code is running and attach corresponding labels to the monitored resource, so metrics are stored correctly 3) More Tests * Removing commented lines * Fixed Stackdriver export interval propagation Added Opencensus headers into every call into Stackdriver APIs Added consts for resources that Stackdriver Exporter should auto-detect when running on GCP * - Added test project for Stackdriver Exporter - Added tests for StackdriverStatsConfiguration * Trying to fix the tests that fail on CI as a result of wrong signing key for InternalVisibleTo * Updating Travis build definition to latest .netcore sdk and running all tests * Adding an option to set google cloud projectId in environment variable for testing purposes(Stackdriver exporter). * Temporarily commenting out lines that read from a friend assembly as it doesn't work on a build server * Added AssemblyInfo.cs into Stackdriver Exporter, so it's visible to tests on both signed and unsigned builds * Introducing Stackdriver Exporter for Opencensus C# library - Current implementation can only store string values - Added the exporter and trace handler only - The exporter relies on newest Trace API from Stackdriver. * Updating translation from ISpan to Stackdriver's Span to cover more fields * Fixing the issue that prevented Stackdriver API call to succeed: now construction of Span resource is taken care of by SpanName class that is part of Stackdriver Trace V2 API. * - Added support for storing links - Minor fixes to proto<->opencensus translation methods * Added command line support for the Samples project. This will make it easier to script testing multiple exporters as well as prevent commenting and uncommenting different test procedures for different exporters. Finally, it will making test code cleaner for showing samples embedded in documentation website. In order to test the exporter, you can either execute it from the command line: samples.dll prometheus or to debug using Visual Studio: Debug => Sample Properties => Debug. Now create a profile for your testing execution and fill application arguments if needed. Now choose your profile in running configuration of Visual Studio. Running settings are local to the machine and are ignored in PRs. * Adding sceleton of metrics support in Stackdriver Exporter. Currently we can't detect all types of monitoring resources but we can ship the batches of metrics with time series to Stackdriver. Thorough testing TBD * Fixing a few bugs in Stackdriver metrics exporter - Small refactoring - Assinging default values for time intervals * - Fixing a few bugs around metric creation and labels - Refactoring MetricsConversions - Fixing stackdriver stats configuration - population of default resource and projects * First working version of Stackdriver Stats Exporter. 1) Fixed bugs related to Stackdriver Metrics Descriptor creation 2) Renamed Metrics Exporter to Stats Exporter to follow Opencensus terminology 3) Cache Stackdriver Metrics Descriptors locally so it's easy which descriptor holds the time series to upload 4) Fixed test code that was producing the metrics using Opencensus and uploading it to Stackdriver 5) Minor refactoring Current limitations: 1) Supporting only string labels 2) We support only "Global" monitored resource. We need to detect dynamically where the code is running and attach corresponding labels to the monitored resource, so metrics are stored correctly 3) More Tests * Removing commented lines * Fixed Stackdriver export interval propagation Added Opencensus headers into every call into Stackdriver APIs Added consts for resources that Stackdriver Exporter should auto-detect when running on GCP * - Added test project for Stackdriver Exporter - Added tests for StackdriverStatsConfiguration * Trying to fix the tests that fail on CI as a result of wrong signing key for InternalVisibleTo * Adding an option to set google cloud projectId in environment variable for testing purposes(Stackdriver exporter). * Temporarily commenting out lines that read from a friend assembly as it doesn't work on a build server * Added AssemblyInfo.cs into Stackdriver Exporter, so it's visible to tests on both signed and unsigned builds * Rebasing origin to upstream * Updated readme to include a link to Stackdriver package * Update Stackdriver Exporter instructions and split the table of nuget packages for better visibility on various screen sizes * Add user-agent header in Stackdriver metrics and trace exporters * Protecting static constructor from exceptions, addressing comments
1 parent c6b9bef commit 819277f

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

src/OpenCensus.Exporter.Stackdriver/Implementation/Constants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ namespace OpenCensus.Exporter.Stackdriver.Implementation
2020

2121
internal class Constants
2222
{
23+
public const string PACKAGE_VERSION_UNDEFINED = "undefined";
24+
2325
public const string LABEL_DESCRIPTION = "OpenCensus TagKey";
2426
public const string OPENCENSUS_TASK = "opencensus_task";
2527
public const string OPENCENSUS_TASK_DESCRIPTION = "Opencensus task identifier";

src/OpenCensus.Exporter.Stackdriver/Implementation/StackdriverStatsExporter.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ namespace OpenCensus.Exporter.Stackdriver.Implementation
2626
using System;
2727
using System.Collections.Generic;
2828
using System.Diagnostics;
29+
using System.Linq;
30+
using System.Reflection;
2931
using System.Threading;
3032
using System.Threading.Tasks;
3133

@@ -45,9 +47,8 @@ internal class StackdriverStatsExporter
4547
private const string CUSTOM_METRIC_DOMAIN = "custom.googleapis.com/";
4648
private const string CUSTOM_OPENCENSUS_DOMAIN = CUSTOM_METRIC_DOMAIN + "opencensus/";
4749

48-
// TODO - zeltser - figure out how to extract OpenCensus package version
49-
private const string USER_AGENT = "opencensus-csharp [0.0]";
5050
private const string USER_AGENT_KEY = "user-agent";
51+
private static string USER_AGENT;
5152

5253
private readonly string domain;
5354
private readonly string displayNamePrefix;
@@ -88,6 +89,19 @@ public StackdriverStatsExporter(
8889
displayNamePrefix = GetDisplayNamePrefix(configuration.MetricNamePrefix);
8990
}
9091

92+
static StackdriverStatsExporter()
93+
{
94+
try
95+
{
96+
string assemblyPackageVersion = typeof(StackdriverStatsExporter).GetTypeInfo().Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().First().InformationalVersion;
97+
USER_AGENT = $"opencensus-csharp/{assemblyPackageVersion}";
98+
}
99+
catch (Exception)
100+
{
101+
USER_AGENT = $"opencensus-csharp/{Constants.PACKAGE_VERSION_UNDEFINED}";
102+
}
103+
}
104+
91105
public void Start()
92106
{
93107
lock (locker)

src/OpenCensus.Exporter.Stackdriver/Implementation/StackdriverTraceExporter.cs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616

1717
namespace OpenCensus.Exporter.Stackdriver.Implementation
1818
{
19+
using System;
1920
using System.Collections.Generic;
2021
using System.Linq;
22+
using System.Reflection;
23+
using Google.Api.Gax.Grpc;
2124
using Google.Cloud.Trace.V2;
25+
using Grpc.Core;
2226
using OpenCensus.Exporter.Stackdriver.Utils;
2327
using OpenCensus.Trace;
2428
using OpenCensus.Trace.Export;
@@ -139,24 +143,67 @@ public static Google.Cloud.Trace.V2.AttributeValue ToAttributeValue(this IAttrib
139143
/// </summary>
140144
internal class StackdriverTraceExporter : IHandler
141145
{
142-
private Google.Api.Gax.ResourceNames.ProjectName googleCloudProjectId;
146+
private static string STACKDRIVER_EXPORTER_VERSION;
147+
private static string OPENCENSUS_EXPORTER_VERSION;
148+
149+
private readonly Google.Api.Gax.ResourceNames.ProjectName googleCloudProjectId;
150+
private readonly TraceServiceSettings traceServiceSettings;
143151

144152
public StackdriverTraceExporter(string projectId)
145153
{
146154
googleCloudProjectId = new Google.Api.Gax.ResourceNames.ProjectName(projectId);
147155

156+
// Set header mutation for every outgoing API call to Stackdriver so the BE knows
157+
// which version of OC client is calling it as well as which version of the exporter
158+
CallSettings callSettings = CallSettings.FromHeaderMutation(StackDriverCallHeaderAppender);
159+
traceServiceSettings = new TraceServiceSettings();
160+
traceServiceSettings.CallSettings = callSettings;
161+
}
162+
163+
static StackdriverTraceExporter()
164+
{
165+
try
166+
{
167+
string assemblyPackageVersion = typeof(StackdriverTraceExporter).GetTypeInfo().Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().First().InformationalVersion;
168+
STACKDRIVER_EXPORTER_VERSION = assemblyPackageVersion;
169+
}
170+
catch (Exception)
171+
{
172+
STACKDRIVER_EXPORTER_VERSION = $"{Constants.PACKAGE_VERSION_UNDEFINED}";
173+
}
174+
175+
try
176+
{
177+
OPENCENSUS_EXPORTER_VERSION = Assembly.GetCallingAssembly().GetName().Version.ToString();
178+
}
179+
catch (Exception)
180+
{
181+
OPENCENSUS_EXPORTER_VERSION = $"{Constants.PACKAGE_VERSION_UNDEFINED}";
182+
}
148183
}
149184

150185
public void Export(IList<ISpanData> spanDataList)
151186
{
152-
TraceServiceClient traceWriter = TraceServiceClient.Create();
187+
TraceServiceClient traceWriter = TraceServiceClient.Create(settings: traceServiceSettings);
188+
153189
var batchSpansRequest = new BatchWriteSpansRequest
154190
{
155191
ProjectName = googleCloudProjectId,
156192
Spans = { spanDataList.Select(s => s.ToSpan(googleCloudProjectId.ProjectId)) },
157193
};
194+
195+
traceWriter.BatchWriteSpansAsync(batchSpansRequest);
196+
}
158197

159-
traceWriter.BatchWriteSpans(batchSpansRequest);
198+
/// <summary>
199+
/// Appends OpenCensus headers for every outgoing request to Stackdriver Backend
200+
/// </summary>
201+
/// <param name="metadata">The metadata that is sent with every outgoing http request</param>
202+
private static void StackDriverCallHeaderAppender(Metadata metadata)
203+
{
204+
205+
metadata.Add("AGENT_LABEL_KEY", "g.co/agent");
206+
metadata.Add("AGENT_LABEL_VALUE_STRING", $"{OPENCENSUS_EXPORTER_VERSION}; stackdriver-exporter {STACKDRIVER_EXPORTER_VERSION}");
160207
}
161208
}
162209
}

0 commit comments

Comments
 (0)