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

Commit 68bd833

Browse files
Simon ZeltserSergeyKanzhelev
authored andcommitted
Adding Resource API - v0 (#81)
* Adding Resource API - v0 - Added IResource definition based on https://github.com/census-instrumentation/opencensus-proto/blob/master/src/opencensus/proto/resource/v1/resource.proto - Added abstract class that implements IResource. Currently it's a scheleton for adding custom resources. This is needed so that the library can identify the resource for which telemetry is collected. * Addressing comments - mainly avoiding exceptions * Updates to the build process (#76) * snupkg, update the linux image and remove travis * removed publish command. It's unnecessary * remove duplicated commands * added comment * use buildProperties instead of arguments * removed comment and updated to ANY 2.2 * latest 2.2 * Adding Resource API - v0 - Added IResource definition based on https://github.com/census-instrumentation/opencensus-proto/blob/master/src/opencensus/proto/resource/v1/resource.proto - Added abstract class that implements IResource. Currently it's a scheleton for adding custom resources. This is needed so that the library can identify the resource for which telemetry is collected. * Addressing comments - mainly avoiding exceptions * Catch up docs updates after release (#79) * readme and changelog updates * fix issues * fix the license warnings (#83) * fix the license and apply NuGet/Announcements#32 * missed a few files * Make span.Name settable, update it with the route info for ASP.NET Core (#80) * better name * make it work * revert wrong addition * addressed code review * fix build failure and added comment for the sampler * added changelog entry * added route into the attributs as well * IList -> IEnumerable (few of them) (#84) * few IList replaced with IEnumerable * parent links from IList to IEnumerable * a few more of IList -> IEnumerable * one more * stats event with IEnumerable now * smal utils method should not use IList * another utility method * allow net45 compilation for abstractions so some common SDKs may take a dependency on it (#86) * Event logging - docs and a single event example. (#85) * documents * first warning was implemented * first version of docs complete * 1) Removed argument.check method and replaced with direct argument checking 2) Added a few events logging 3) Added tests for Resource parsing (labels and resource type) * Fixing build break * Addressed comments: - Changed IList to IEnumerable - Refined error messages to more details.
1 parent f6a8cb4 commit 68bd833

File tree

7 files changed

+468
-1
lines changed

7 files changed

+468
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ the release.
1010
- Application Insights exporter improvements - now understands http attributes
1111
and process links, annotations and messages.
1212
- ASP.NET Core collector now uses `http.route` for the span name.
13+
- Initial implementation of Resource Specification.
1314

1415
## 0.1.0-alpha-33381
1516

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// <copyright file="IResource.cs" company="OpenCensus Authors">
2+
// Copyright 2018, OpenCensus Authors
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// </copyright>
16+
17+
namespace OpenCensus.Resources
18+
{
19+
using System.Collections.Generic;
20+
using OpenCensus.Tags;
21+
22+
/// <summary>
23+
/// Represents a resource, which captures identifying information about the entities
24+
/// for which signals(stats or traces) are reported. It further provides a framework for detection
25+
/// of resource information from the environment and progressive population as signals propagate from
26+
/// the core instrumentation library to a backend's exporter.
27+
/// </summary>
28+
public interface IResource
29+
{
30+
/// <summary>
31+
/// Gets Type identifier for the resource.
32+
/// </summary>
33+
string Type { get; }
34+
35+
/// <summary>
36+
/// Gets the map of the labels/tags that describe the resource.
37+
/// </summary>
38+
IEnumerable<ITag> Tags { get; }
39+
}
40+
}

src/OpenCensus.Exporter.Stackdriver/OpenCensus.Exporter.Stackdriver.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'OpenCensus.sln'))\build\Common.prod.props" />
3+
34
<PropertyGroup>
45
<TargetFrameworks>net46;netstandard2.0</TargetFrameworks>
56
<TargetFrameworks Condition="$(OS) != 'Windows_NT'">netstandard2.0</TargetFrameworks>
6-
<Description>Stackdriver Exporter for OpenCensus.</Description>
7+
<Description>Stackdriver .NET Exporter for OpenCensus.</Description>
78
<IncludeSymbols>True</IncludeSymbols>
89
<PackageTags>Tracing;OpenCensus;Management;Monitoring;Stackdriver;Google;GCP;distributed-tracing</PackageTags>
910
<PackageIconUrl>https://opencensus.io/images/opencensus-logo.png</PackageIconUrl>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// <copyright file="Resource.cs" company="OpenCensus Authors">
2+
// Copyright 2018, OpenCensus Authors
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of theLicense at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// </copyright>
16+
17+
namespace OpenCensus.Implementation
18+
{
19+
/// <summary>
20+
/// Constants enforced by OpenCensus specifications.
21+
/// </summary>
22+
internal class Constants
23+
{
24+
/// <summary>
25+
/// Maximum length of the resource type name.
26+
/// </summary>
27+
public const int MaxResourceTypeNameLength = 255;
28+
29+
/// <summary>
30+
/// Special resource type name that is assigned if nothing else is detected.
31+
/// </summary>
32+
public const string GlobalResourceType = "Global";
33+
34+
/// <summary>
35+
/// OpenCensus Resource Type Environment Variable Name.
36+
/// </summary>
37+
public const string ResourceTypeEnvironmentVariable = "OC_RESOURCE_TYPE";
38+
39+
/// <summary>
40+
/// OpenCensus Resource Labels Environment Variable Name.
41+
/// </summary>
42+
public const string ResourceLabelsEnvironmentVariable = "OC_RESOURCE_LABELS";
43+
}
44+
}

src/OpenCensus/Implementation/OpenCensusEventSource.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,27 @@ public void ExporterThrownExceptionWarning(string ex)
4141
this.WriteEvent(1, ex);
4242
}
4343

44+
[Event(2, Message = "Failed to parse a resource tag. {0} should be an ASCII string with a length greater than 0 and not exceeding {1} characters.", Level = EventLevel.Warning)]
45+
public void InvalidCharactersInResourceElement(string element)
46+
{
47+
this.WriteEvent(2, element, Constants.MaxResourceTypeNameLength);
48+
}
49+
50+
[NonEvent]
51+
public void FailedReadingEnvironmentVariableWarning(string environmentVariableName, Exception ex)
52+
{
53+
if (Log.IsEnabled(EventLevel.Warning, EventKeywords.All))
54+
{
55+
this.FailedReadingEnvironmentVariableWarning(environmentVariableName, ToInvariantString(ex));
56+
}
57+
}
58+
59+
[Event(3, Message = "Failed to read environment variable {0}. Main library failed with security exception: {1}", Level = EventLevel.Warning)]
60+
public void FailedReadingEnvironmentVariableWarning(string environmentVariableName, string ex)
61+
{
62+
this.WriteEvent(3, environmentVariableName, ex);
63+
}
64+
4465
/// <summary>
4566
/// Returns a culture-independent string representation of the given <paramref name="exception"/> object,
4667
/// appropriate for diagnostics tracing.
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// <copyright file="Resource.cs" company="OpenCensus Authors">
2+
// Copyright 2018, OpenCensus Authors
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of theLicense at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// </copyright>
16+
17+
namespace OpenCensus.Resources
18+
{
19+
using System;
20+
using System.Collections.Generic;
21+
using System.Security;
22+
using System.Text.RegularExpressions;
23+
using OpenCensus.Implementation;
24+
using OpenCensus.Tags;
25+
using OpenCensus.Utils;
26+
27+
/// <summary>
28+
/// Represents a resource that captures identification information about the entities for which signals (stats or traces)
29+
/// are reported. It further provides a framework for detection of resource information from the environment and progressive
30+
/// population as signals propagate from the core instrumentation library to a backend's exporter.
31+
/// </summary>
32+
public abstract class Resource : IResource
33+
{
34+
/// <summary>
35+
/// Tag list splitter.
36+
/// </summary>
37+
private const char LabelListSplitter = ',';
38+
39+
/// <summary>
40+
/// Key-value splitter.
41+
/// </summary>
42+
private const char LabelKeyValueSplitter = '=';
43+
44+
/// <summary>
45+
/// Environment identification (for example, AKS/GKE/etc).
46+
/// </summary>
47+
private static readonly string EnvironmentType;
48+
49+
private static readonly ITag[] EnvironmentToLabelMap;
50+
51+
static Resource()
52+
{
53+
string openCensusResourceType;
54+
string openCensusEnvironmentTags;
55+
56+
try
57+
{
58+
openCensusResourceType = Environment.GetEnvironmentVariable(Constants.ResourceTypeEnvironmentVariable);
59+
}
60+
catch (SecurityException ex)
61+
{
62+
openCensusResourceType = Constants.GlobalResourceType;
63+
64+
Log.FailedReadingEnvironmentVariableWarning(Constants.ResourceTypeEnvironmentVariable, ex);
65+
}
66+
67+
try
68+
{
69+
openCensusEnvironmentTags = Environment.GetEnvironmentVariable(Constants.ResourceLabelsEnvironmentVariable);
70+
}
71+
catch (SecurityException ex)
72+
{
73+
openCensusEnvironmentTags = string.Empty;
74+
75+
Log.FailedReadingEnvironmentVariableWarning(Constants.ResourceLabelsEnvironmentVariable, ex);
76+
}
77+
78+
TryParseResourceType(openCensusResourceType, out EnvironmentType);
79+
EnvironmentToLabelMap = ParseResourceLabels(Environment.GetEnvironmentVariable(Constants.ResourceLabelsEnvironmentVariable));
80+
}
81+
82+
/// <summary>
83+
/// Gets or sets the identification of the resource.
84+
/// </summary>
85+
public abstract string Type { get; protected set; }
86+
87+
/// <summary>
88+
/// Gets the map between the tag and its value.
89+
/// </summary>
90+
public abstract IEnumerable<ITag> Tags { get; }
91+
92+
private static OpenCensusEventSource Log => OpenCensusEventSource.Log;
93+
94+
/// <summary>
95+
/// Creates a label/tag map from the OC_RESOURCE_LABELS environment variable.
96+
/// OC_RESOURCE_LABELS: A comma-separated list of labels describing the source in more detail,
97+
/// e.g. “key1=val1,key2=val2”. Domain names and paths are accepted as label keys.
98+
/// Values may be quoted or unquoted in general. If a value contains whitespaces, =, or " characters, it must
99+
/// always be quoted.
100+
/// </summary>
101+
/// <param name="rawEnvironmentTags">Environment tags as a raw, comma separated string</param>
102+
/// <returns>Environment Tags as a list.</returns>
103+
internal static ITag[] ParseResourceLabels(string rawEnvironmentTags)
104+
{
105+
if (rawEnvironmentTags == null)
106+
{
107+
return new ITag[0] { };
108+
}
109+
else
110+
{
111+
var labels = new List<ITag>();
112+
string[] rawLabels = rawEnvironmentTags.Split(LabelListSplitter);
113+
114+
Regex regex = new Regex("^\"|\"$", RegexOptions.Compiled);
115+
116+
foreach (var rawLabel in rawLabels)
117+
{
118+
string[] keyValuePair = rawLabel.Split(LabelKeyValueSplitter);
119+
if (keyValuePair.Length != 2)
120+
{
121+
continue;
122+
}
123+
124+
string key = keyValuePair[0].Trim();
125+
string value = Regex.Replace(keyValuePair[1].Trim(), "^\"|\"$", string.Empty);
126+
127+
if (!IsValidAndNotEmpty(key))
128+
{
129+
Log.InvalidCharactersInResourceElement("Label key");
130+
return new ITag[0] { };
131+
}
132+
133+
if (!IsValid(value))
134+
{
135+
Log.InvalidCharactersInResourceElement("Label key");
136+
return new ITag[0] { };
137+
}
138+
139+
labels.Add(new Tag(TagKey.Create(key), TagValue.Create(value)));
140+
}
141+
142+
return labels.ToArray();
143+
}
144+
}
145+
146+
internal static bool TryParseResourceType(string rawEnvironmentType, out string resourceType)
147+
{
148+
if (string.IsNullOrEmpty(rawEnvironmentType))
149+
{
150+
resourceType = Constants.GlobalResourceType;
151+
return false;
152+
}
153+
154+
if (rawEnvironmentType.Length > Constants.MaxResourceTypeNameLength)
155+
{
156+
Log.InvalidCharactersInResourceElement(rawEnvironmentType);
157+
resourceType = Constants.GlobalResourceType;
158+
return false;
159+
}
160+
161+
resourceType = rawEnvironmentType.Trim();
162+
return true;
163+
}
164+
165+
/// <summary>
166+
/// Checks whether given string is a valid printable ASCII string with a length not exeeding
167+
/// <see cref="Constants.MaxResourceTypeNameLength"/> characters.
168+
/// </summary>
169+
/// <param name="name">The string.</param>
170+
/// <returns>Whether given string is valid.</returns>
171+
private static bool IsValid(string name)
172+
{
173+
return name.Length <= Constants.MaxResourceTypeNameLength && StringUtil.IsPrintableString(name);
174+
}
175+
176+
/// <summary>
177+
/// Checks whether given string is a valid printable ASCII string with a length
178+
/// greater than 0 and not exceeding <see cref="Constants.MaxResourceTypeNameLength"/> characters.
179+
/// </summary>
180+
/// <param name="name">The string.</param>
181+
/// <returns>Whether given string is valid.</returns>
182+
private static bool IsValidAndNotEmpty(string name)
183+
{
184+
return !string.IsNullOrEmpty(name) && IsValid(name);
185+
}
186+
}
187+
}

0 commit comments

Comments
 (0)