Skip to content

Commit

Permalink
add stackdriver exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeGoldsmith committed May 6, 2020
1 parent 4f14e13 commit 00d1289
Show file tree
Hide file tree
Showing 17 changed files with 1,298 additions and 0 deletions.
433 changes: 433 additions & 0 deletions .gitignore

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project>
<PropertyGroup>
<LangVersion>8.0</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

</Project>
3 changes: 3 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Project>
<!-- Empty for now -->
</Project>
56 changes: 56 additions & 0 deletions opentelemetry-dotnet-contrib.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{2097345F-4DD3-477D-BC54-A922F9B2B402}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Exporter.Stackdriver.Tests\OpenTelemetry.Exporter.Stackdriver.Tests.csproj", "{39EF6946-9909-498D-9181-479DEF6CB4B7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Debug|x64.ActiveCfg = Debug|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Debug|x64.Build.0 = Debug|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Debug|x86.ActiveCfg = Debug|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Debug|x86.Build.0 = Debug|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Release|Any CPU.Build.0 = Release|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Release|x64.ActiveCfg = Release|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Release|x64.Build.0 = Release|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Release|x86.ActiveCfg = Release|Any CPU
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2}.Release|x86.Build.0 = Release|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Debug|x64.ActiveCfg = Debug|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Debug|x64.Build.0 = Debug|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Debug|x86.ActiveCfg = Debug|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Debug|x86.Build.0 = Debug|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Release|Any CPU.Build.0 = Release|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Release|x64.ActiveCfg = Release|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Release|x64.Build.0 = Release|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Release|x86.ActiveCfg = Release|Any CPU
{39EF6946-9909-498D-9181-479DEF6CB4B7}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D7F6B622-ED4B-4A3B-BAFD-24FB503666C2} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
{39EF6946-9909-498D-9181-479DEF6CB4B7} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
EndGlobalSection
EndGlobal
34 changes: 34 additions & 0 deletions src/OpenTelemetry.Exporter.Stackdriver/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// <copyright file="AssemblyInfo.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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.Exporter.Stackdriver.Tests" + AssemblyInfo.PublicKey)]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)]

#if SIGNED
internal static class AssemblyInfo
{
public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898";
public const string MoqPublicKey = ", PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7";
}
#else
internal static class AssemblyInfo
{
public const string PublicKey = "";
public const string MoqPublicKey = "";
}
#endif
53 changes: 53 additions & 0 deletions src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// <copyright file="Constants.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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;

namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
internal class Constants
{
public static readonly string PackagVersionUndefined = "undefined";

public static readonly string LabelDescription = "OpenTelemetry string";
public static readonly string OpenTelemetryTask = "OpenTelemetry_task";
public static readonly string OpenTelemetryTaskDescription = "OpenTelemetry task identifier";

public static readonly string GcpGkeContainer = "k8s_container";
public static readonly string GcpGceInstance = "gce_instance";
public static readonly string AwsEc2Instance = "aws_ec2_instance";
public static readonly string Global = "global";

public static readonly string ProjectIdLabelKey = "project_id";
public static readonly string OpenTelemetryTaskValueDefault = GenerateDefaultTaskValue();

public static readonly string GceGcpInstanceType = "cloud.google.com/gce/instance";
public static readonly string GcpInstanceIdKey = "cloud.google.com/gce/instance_id";
public static readonly string GcpAccountIdKey = "cloud.google.com/gce/project_id";
public static readonly string GcpZoneKey = "cloud.google.com/gce/zone";

public static readonly string K8sContainerType = "k8s.io/container";
public static readonly string K8sClusterNameKey = "k8s.io/cluster/name";
public static readonly string K8sContainerNameKey = "k8s.io/container/name";
public static readonly string K8sNamespaceNameKey = "k8s.io/namespace/name";
public static readonly string K8sPodNameKey = "k8s.io/pod/name";

private static string GenerateDefaultTaskValue()
{
// Something like '<pid>@<hostname>'
return $"dotnet-{System.Diagnostics.Process.GetCurrentProcess().Id}@{Environment.MachineName}";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// <copyright file="ExporterStackdriverEventSource.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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.Diagnostics.Tracing;
using System.Globalization;
using System.Threading;

namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
[EventSource(Name = "OpenTelemetry-Exporter-Stackdriver")]
internal class ExporterStackdriverEventSource : EventSource
{
public static readonly ExporterStackdriverEventSource Log = new ExporterStackdriverEventSource();

[NonEvent]
public void UnknownProblemInWorkerThreadError(Exception ex)
{
if (Log.IsEnabled(EventLevel.Error, EventKeywords.All))
{
this.UnknownProblemInWorkerThreadError(ToInvariantString(ex));
}
}

[Event(1, Message = "Stackdriver exporter encountered an unknown error and will shut down. Exception: {0}", Level = EventLevel.Error)]
public void UnknownProblemInWorkerThreadError(string ex)
{
this.WriteEvent(1, ex);
}

[NonEvent]
public void UnknownProblemWhileCreatingStackdriverTimeSeriesError(Exception ex)
{
if (Log.IsEnabled(EventLevel.Error, EventKeywords.All))
{
this.UnknownProblemWhileCreatingStackdriverTimeSeriesError(ToInvariantString(ex));
}
}

[Event(2, Message = "Stackdriver exporter failed to create time series. Time series will be lost. Exception: {0}", Level = EventLevel.Error)]
public void UnknownProblemWhileCreatingStackdriverTimeSeriesError(string ex)
{
this.WriteEvent(2, ex);
}

/// <summary>
/// Returns a culture-independent string representation of the given <paramref name="exception"/> object,
/// appropriate for diagnostics tracing.
/// </summary>
private static string ToInvariantString(Exception exception)
{
var originalUICulture = Thread.CurrentThread.CurrentUICulture;

try
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
return exception.ToString();
}
finally
{
Thread.CurrentThread.CurrentUICulture = originalUICulture;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// <copyright file="GoogleCloudResourceUtils.cs" company="OpenTelemetry Authors">
// Copyright 2018, 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.IO;
using Google.Api;

namespace OpenTelemetry.Exporter.Stackdriver.Implementation
{
/// <summary>
/// Utility methods for working with Google Cloud Resources.
/// </summary>
public static class GoogleCloudResourceUtils
{
/// <summary>
/// Detects Google Cloud ProjectId based on the environment on which the code runs.
/// Supports GCE/GKE/GAE and projectId tied to service account
/// In case the code runs in a different environment,
/// the method returns null.
/// </summary>
/// <returns>Google Cloud Project ID.</returns>
public static string GetProjectId()
{
// Try to detect projectId from the environment where the code is running
var instance = Google.Api.Gax.Platform.Instance();
var projectId = instance?.ProjectId;
if (!string.IsNullOrEmpty(projectId))
{
return projectId;
}

// Try to detect projectId from service account credential if it exists
var serviceAccountFilePath = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
if (!string.IsNullOrEmpty(serviceAccountFilePath) && File.Exists(serviceAccountFilePath))
{
using var stream = new FileStream(serviceAccountFilePath, FileMode.Open, FileAccess.Read);
var credential = Google.Apis.Auth.OAuth2.ServiceAccountCredential.FromServiceAccountData(stream);
return credential.ProjectId;
}

projectId = Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID");
return projectId;
}

/// <summary>
/// Determining the resource to which the metrics belong.
/// </summary>
/// <param name="projectId">The project id.</param>
/// <returns>Stackdriver Monitored Resource.</returns>
public static MonitoredResource GetDefaultResource(string projectId)
{
var resource = new MonitoredResource();
resource.Type = Constants.Global;
resource.Labels.Add(Constants.ProjectIdLabelKey, projectId);

// TODO - zeltser - setting monitored resource labels for detected resource
// along with all the other metadata

return resource;
}
}
}
Loading

0 comments on commit 00d1289

Please sign in to comment.