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

Commit 46ecfab

Browse files
Simon ZeltserSergeyKanzhelev
authored andcommitted
Improvements to Stackdriver Stats Exporter (#101)
* Minor fix - updating zipkin sample so we can execute it from command line * Fix zipkin sample * Updated zipkin sample to follow the quickstart of opencensus.io for other languages * Revert the todo * Adding support for custom json file specification for obtaining service account credentials in Stackdriver metrics exporter * Changing Stackdriver sample code for metrics to use sum aggregation instead of distribution
1 parent dfeee49 commit 46ecfab

File tree

6 files changed

+69
-14
lines changed

6 files changed

+69
-14
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ public static Metric GetMetric(
222222
string domain)
223223
{
224224
var metric = new Metric();
225-
metric.Type = metricDescriptor.Name;
225+
metric.Type = metricDescriptor.Type;
226226

227227
IList<ITagKey> columns = view.Columns;
228228

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
namespace OpenCensus.Exporter.Stackdriver.Implementation
1818
{
1919
using Google.Api;
20+
using Google.Apis.Auth.OAuth2;
2021
using System;
2122

2223
/// <summary>
@@ -41,6 +42,11 @@ public class StackdriverStatsConfiguration
4142
/// </summary>
4243
public string ProjectId { get; set; }
4344

45+
/// <summary>
46+
/// Credential used to authenticate against Google Stackdriver Monitoring APIs
47+
/// </summary>
48+
public GoogleCredential GoogleCredential { get; set; }
49+
4450
/// <summary>
4551
/// Monitored Resource associated with metrics collection.
4652
/// By default, the exporter detects the environment where the export is happening,

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ namespace OpenCensus.Exporter.Stackdriver.Implementation
1919
using Google.Api;
2020
using Google.Api.Gax;
2121
using Google.Api.Gax.Grpc;
22+
using Google.Apis.Auth.OAuth2;
2223
using Google.Cloud.Monitoring.V3;
24+
using Grpc.Auth;
2325
using Grpc.Core;
2426
using OpenCensus.Exporter.Stackdriver.Utils;
2527
using OpenCensus.Stats;
@@ -39,6 +41,7 @@ internal class StackdriverStatsExporter
3941

4042
private readonly Dictionary<IView, MetricDescriptor> metricDescriptors = new Dictionary<IView, MetricDescriptor>(new ViewNameComparer());
4143
private readonly ProjectName project;
44+
private readonly GoogleCredential credential;
4245
private MetricServiceClient metricServiceClient;
4346
private CancellationTokenSource tokenSource;
4447

@@ -73,8 +76,8 @@ public StackdriverStatsExporter(
7376
StackdriverStatsConfiguration configuration)
7477
{
7578
GaxPreconditions.CheckNotNull(configuration, "configuration");
76-
GaxPreconditions.CheckNotNullOrEmpty(configuration.ProjectId, "configuration.ProjectId");
7779
GaxPreconditions.CheckNotNull(configuration.MonitoredResource, "configuration.MonitoredResource");
80+
GaxPreconditions.CheckNotNull(configuration.GoogleCredential, "configuration.GoogleCredential");
7881
GaxPreconditions.CheckArgument(
7982
configuration.ExportInterval != TimeSpan.Zero,
8083
paramName: "configuration.ExportInterval",
@@ -84,6 +87,7 @@ public StackdriverStatsExporter(
8487
monitoredResource = configuration.MonitoredResource;
8588
collectionInterval = configuration.ExportInterval;
8689
project = new ProjectName(configuration.ProjectId);
90+
credential = configuration.GoogleCredential;
8791

8892
domain = GetDomain(configuration.MetricNamePrefix);
8993
displayNamePrefix = GetDisplayNamePrefix(configuration.MetricNamePrefix);
@@ -109,7 +113,7 @@ public void Start()
109113
if (!isStarted)
110114
{
111115
tokenSource = new CancellationTokenSource();
112-
metricServiceClient = CreateMetricServiceClient(tokenSource);
116+
metricServiceClient = CreateMetricServiceClient(credential, tokenSource);
113117

114118
Task.Factory.StartNew(DoWork, tokenSource.Token);
115119

@@ -272,7 +276,7 @@ private void Export()
272276
}
273277
}
274278

275-
private static MetricServiceClient CreateMetricServiceClient(CancellationTokenSource tokenSource)
279+
private static MetricServiceClient CreateMetricServiceClient(GoogleCredential credential, CancellationTokenSource tokenSource)
276280
{
277281
// Make sure to add Opencensus header to every outgoing call to Stackdriver APIs
278282
Action<Metadata> addOpencensusHeader = m => m.Add(USER_AGENT_KEY, USER_AGENT);
@@ -283,12 +287,17 @@ private static MetricServiceClient CreateMetricServiceClient(CancellationTokenSo
283287
headerMutation: addOpencensusHeader,
284288
writeOptions: WriteOptions.Default,
285289
propagationToken: null);
290+
291+
var channel = new Channel(
292+
MetricServiceClient.DefaultEndpoint.ToString(),
293+
credential.ToChannelCredentials());
294+
286295
var metricServiceSettings = new MetricServiceSettings()
287296
{
288297
CallSettings = callSettings
289298
};
290299

291-
return MetricServiceClient.Create(settings: metricServiceSettings);
300+
return MetricServiceClient.Create(channel, settings: metricServiceSettings);
292301
}
293302

294303
private static string GetDomain(string metricNamePrefix)

src/OpenCensus.Exporter.Stackdriver/StackdriverExporter.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
namespace OpenCensus.Exporter.Stackdriver
1919
{
20+
using Google.Api.Gax;
21+
using Google.Apis.Auth.OAuth2;
22+
using Google.Cloud.Monitoring.V3;
2023
using OpenCensus.Exporter.Stackdriver.Implementation;
2124
using OpenCensus.Stats;
2225
using OpenCensus.Trace.Export;
@@ -31,6 +34,7 @@ public class StackdriverExporter
3134
private readonly IExportComponent exportComponent;
3235
private readonly IViewManager viewManager;
3336
private readonly string projectId;
37+
private readonly string jsonPath;
3438
private StackdriverStatsExporter statsExporter;
3539
private object locker = new object();
3640
private bool isInitialized = false;
@@ -44,9 +48,27 @@ public class StackdriverExporter
4448
public StackdriverExporter(
4549
string projectId,
4650
IExportComponent exportComponent,
51+
IViewManager viewManager) : this(projectId, null, exportComponent, viewManager)
52+
{
53+
}
54+
55+
/// <summary>
56+
/// Initializes a new instance of the <see cref="StackdriverExporter"/> class.
57+
/// </summary>
58+
/// <param name="projectId">Google Cloud ProjectId that is used to send data to Stackdriver</param>
59+
/// <param name="jsonPath">File path to the json file containing the service credential used to authenticate against Stackdriver APIs</param>
60+
/// <param name="exportComponent">Exporter to get traces from</param>
61+
/// <param name="viewManager">View manager to get the stats from</param>
62+
public StackdriverExporter(
63+
string projectId,
64+
string jsonPath,
65+
IExportComponent exportComponent,
4766
IViewManager viewManager)
4867
{
68+
GaxPreconditions.CheckNotNullOrEmpty(projectId, "projectId");
69+
4970
this.projectId = projectId;
71+
this.jsonPath = jsonPath;
5072
this.exportComponent = exportComponent;
5173
this.viewManager = viewManager;
5274
}
@@ -73,7 +95,10 @@ public void Start()
7395
// Register stats(metrics) exporter
7496
if (viewManager != null)
7597
{
98+
GoogleCredential credential = GetGoogleCredential();
99+
76100
StackdriverStatsConfiguration statsConfig = StackdriverStatsConfiguration.Default;
101+
statsConfig.GoogleCredential = credential;
77102
if (statsConfig.ProjectId != projectId)
78103
{
79104
statsConfig.ProjectId = projectId;
@@ -115,5 +140,21 @@ public void Stop()
115140
isInitialized = false;
116141
}
117142
}
143+
144+
private GoogleCredential GetGoogleCredential()
145+
{
146+
GoogleCredential credential;
147+
if (string.IsNullOrEmpty(jsonPath))
148+
{
149+
credential = GoogleCredential.GetApplicationDefault();
150+
}
151+
else
152+
{
153+
credential = GoogleCredential.FromFile(jsonPath)
154+
.CreateScoped(MetricServiceClient.DefaultScopes);
155+
}
156+
157+
return credential;
158+
}
118159
}
119160
}

src/Samples/TestStackdriver.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,18 @@ internal class TestStackdriver
1717
private static ITagger tagger = Tags.Tagger;
1818

1919
private static IStatsRecorder statsRecorder = Stats.StatsRecorder;
20-
private static readonly IMeasureDouble VideoSize = MeasureDouble.Create("my_org/measure/video_size2", "size of processed videos", "MiB");
20+
private static readonly IMeasureDouble VideoSize = MeasureDouble.Create("my_org/measure/video_size", "size of processed videos", "MiB");
2121
private static readonly ITagKey FrontendKey = TagKey.Create("my_org/keys/frontend");
2222

2323
private static long MiB = 1 << 20;
2424

25-
private static readonly IViewName VideoSizeViewName = ViewName.Create("my_org/views/video_size2");
25+
private static readonly IViewName VideoSizeViewName = ViewName.Create("my_org/views/video_size");
2626

2727
private static readonly IView VideoSizeView = View.Create(
2828
name: VideoSizeViewName,
2929
description: "processed video size over time",
3030
measure: VideoSize,
31-
//aggregation: Sum.Create(),
32-
aggregation: Distribution.Create(BucketBoundaries.Create(new List<double> { 0.0, 16.0 * MiB, 256.0 * MiB })),
31+
aggregation: Sum.Create(),
3332
columns: new List<ITagKey>() { FrontendKey });
3433

3534
internal static object Run(string projectId)
@@ -53,14 +52,12 @@ internal static object Run(string projectId)
5352
{
5453
using (var scopedSpan = spanBuilder.StartScopedSpan())
5554
{
56-
tracer.CurrentSpan.AddAnnotation("Start processing video.");
57-
55+
tracer.CurrentSpan.AddAnnotation("Processing video.");
5856
Thread.Sleep(TimeSpan.FromMilliseconds(10));
57+
5958
statsRecorder.NewMeasureMap()
6059
.Put(VideoSize, 25 * MiB)
6160
.Record();
62-
63-
tracer.CurrentSpan.AddAnnotation("Finished processing video.");
6461
}
6562
}
6663

src/Samples/TestZipkin.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@ private static void DoWork(int i)
5858
// 7. Start another span. If another span was already started, it'll use that span as the parent span.
5959
// In this example, the main method already started a span, so that'll be the parent span, and this will be
6060
// a child span.
61-
using (OpenCensus.Common.IScope scope = tracer.SpanBuilder("DoWork").StartScopedSpan(out ISpan span))
61+
using (OpenCensus.Common.IScope scope = tracer.SpanBuilder("DoWork").StartScopedSpan())
6262
{
6363
// Simulate some work.
64+
ISpan span = tracer.CurrentSpan;
65+
6466
try
6567
{
6668
Console.WriteLine("Doing busy work");

0 commit comments

Comments
 (0)