Skip to content

Commit c799ff2

Browse files
authored
Merge pull request #11 from bmermet/codedocumentation
Add documentation on public members and code examples
2 parents 3632a9a + 707b3ec commit c799ff2

File tree

10 files changed

+130
-27
lines changed

10 files changed

+130
-27
lines changed

README.md

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ Datadog APM traces the path of each request through your application stack, reco
77
This repository contains what you need to trace C# applications. Some quick notes up front:
88

99
- **Datadog C# APM is currently in Alpha**
10-
- It supports .Net Framework version above 4.5 and .Net Core 2.0
11-
- It does not support out of process propagation
12-
- It does not provide automatic framework instrumentation, all instrumentation is [manual](#manual-instrumentation)
13-
- Multiple AppDomains are not supported (but it could work).
10+
- It supports .Net Framework version above 4.5 and .Net Core 2.0.
11+
- It does not support out of process propagation.
12+
- It does not provide automatic framework instrumentation, all instrumentation is [manual](#manual-instrumentation).
13+
- Multiple AppDomains are not supported.
1414
- Our tracer is based on the current OpenTracing standard, however we do not yet support the following features: `FollowsFrom` references, `Baggage` or `Log`.
1515

1616
## The Components
@@ -26,10 +26,104 @@ Before instrumenting your code, [install the Datadog Agent](https://app.datadogh
2626

2727
### Manual Instrumentation
2828

29+
#### Introduction
30+
31+
Before instrumenting your application, have a look at the [Datadog APM Terminology](https://docs.datadoghq.com/tracing/terminology/) to get familiar with the core concepts of Datadog APM.
32+
2933
#### Setup
3034

35+
In order to instrument you code you need to add the `Datadog.Trace` NuGet package to your project.
36+
37+
Your tracing adventure starts with the `ITracer` object, you should typically instantiate only one `ITracer` for the lifetime of your app and use it in all places of your code where you want to add tracing. Instantiating the `ITracer` is done with the `TracerFactory.GetTracer` method.
38+
39+
To get a tracer with default parameters (i.e. the agent endpoint set to `http://localhost:8126`, and the default service name set to the name of the AppDomain):
40+
41+
```csharp
42+
ITracer tracer = TracerFactory.GetTracer();
43+
```
44+
45+
Customize your tracer object by adding optional parameters to the `TracerFactory.GetTracer` call:
46+
47+
By default the service name is set to the name of the AppDomain, choose a custom name with the defaultServiceName parameter:
48+
49+
```csharp
50+
ITracer tracer = TracerFactory.GetTracer(defaultServiceName: "YourServiceName")
51+
```
52+
53+
By default, the trace endpoint is set to http://localhost:8126, send traces to a different endpoint with the agentEndpoint parameter:
54+
55+
```csharp
56+
ITracer tracer = TracerFactory.GetTracer(agentEndpoint: new Url("http://myendpoint:port"));
57+
```
58+
3159
#### Examples
3260

61+
Use the shared `ITracer` object you created to create spans, instrument any section of your code, and get detailed metrics on it.
62+
63+
Set the ServiceName to recognize which service this trace belongs to; if you don't, the parent span's service name or in case of a root span the defaultServiceName stated above is used.
64+
65+
Set the ResourceName to scope this trace to a specific endpoint or SQL Query; For instance:
66+
- "GET /users/:id"
67+
- "SELECT * FROM ..."
68+
if you don't the OperationName will be used.
69+
70+
A minimal examples is:
71+
72+
```csharp
73+
using (ISpan span = tracer.BuildSpan("OperationName").WithTag(DDTags.ServiceName, "ServiceName").Start())
74+
{
75+
span.SetTag(DDTags.ResourceName, "ResourceName");
76+
77+
// Instrumented code
78+
Thread.Sleep(1000);
79+
}
80+
```
81+
82+
You may also choose, not to use the `using` construct and close the `ISpan` object explictly:
83+
84+
```csharp
85+
ISpan span = tracer.BuildSpan("OperationName").WithTag(DDTags.ServiceName, "ServiceName").Start();
86+
span.SetTag(DDTags.ResourceName, "ResourceName");
87+
88+
// Instrumented code
89+
Thread.Sleep(1000);
90+
91+
92+
// Finish sets the span duration and sends it to the agent (if you don't call finish the data will never be sent to Datadog)
93+
span.Finish();
94+
```
95+
96+
You may add custom tags by calling `ISpan.SetTag`:
97+
98+
```csharp
99+
ISpan span = tracer.BuildSpan("SqlQuery").Start();
100+
span.SetTag("db.rows", 10);
101+
```
102+
103+
You should not have to explicitly declare parent/children relationship between your spans, but to override the default behavior - a new span is considered a child of the innermost open span in its logical context- use:
104+
105+
```csharp
106+
ISpan parent = tracer.BuildSpan("Parent").Start();
107+
ISpan child = tracer.BuildSpan("Child").AsChildOf(parent).Start();
108+
```
109+
110+
#### Advanced Usage
111+
112+
When creating a tracer, add some metadata to your services to customize how they will appear in your Datadog application:
113+
114+
```csharp
115+
var serviceInfoList = new List<ServiceInfo>
116+
{
117+
new ServiceInfo
118+
{
119+
App = "MyAppName",
120+
AppType = "web",
121+
ServiceName = "MyServiceName"
122+
}
123+
};
124+
ITracer tracer = TracerFactory.GetTracer(serviceInfoList: serviceInfoList);
125+
```
126+
33127
## Further Reading
34128

35129
- [OpenTracing's documentation](https://github.com/opentracing/opentracing-csharp); feel free to use the Trace C# API to customize your instrumentation.

src/Datadog.Trace.IntegrationTests/SendTracesToAgent.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ public async void CustomServiceName()
7070
_tracer = TracerFactory.GetTracer(new Uri("http://localhost:8126"), serviceList, null, _httpRecorder);
7171

7272
var span = (Span)_tracer.BuildSpan("Operation")
73-
.WithTag(Tags.ResourceName, "This is a resource")
74-
.WithTag(Tags.ServiceName, ServiceName)
73+
.WithTag(DDTags.ResourceName, "This is a resource")
74+
.WithTag(DDTags.ServiceName, ServiceName)
7575
.Start();
7676
span.Finish();
7777

@@ -94,8 +94,8 @@ public async void CustomServiceName()
9494
public async void Utf8Everywhere()
9595
{
9696
var span = (Span)_tracer.BuildSpan("Aᛗᚪᚾᚾᚪ")
97-
.WithTag(Tags.ResourceName, "η γλώσσα μου έδωσαν ελληνική")
98-
.WithTag(Tags.ServiceName, "На берегу пустынных волн")
97+
.WithTag(DDTags.ResourceName, "η γλώσσα μου έδωσαν ελληνική")
98+
.WithTag(DDTags.ServiceName, "На берегу пустынных волн")
9999
.WithTag("யாமறிந்த", "ნუთუ კვლა")
100100
.Start();
101101
span.Finish();

src/Datadog.Trace.Tests/TracerTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ public void BuildSpan_NoParameter_DefaultParameters()
1717

1818
var builder = tracer.BuildSpan("Op1");
1919
var span = (Span)builder.Start();
20-
21-
Assert.Equal("Datadog.Trace", span.ServiceName);
20+
#if NETCOREAPP2_0
21+
Assert.Equal("testhost", span.ServiceName);
22+
#else
23+
Assert.Equal("Datadog.Trace.Tests.Net45", span.ServiceName);
24+
#endif
2225
Assert.Equal("Op1", span.OperationName);
2326
}
2427

src/Datadog.Trace/MsgPackContent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace Datadog.Trace
99
{
10-
public class MsgPackContent<T> : HttpContent
10+
internal class MsgPackContent<T> : HttpContent
1111
{
1212
public T Value { get; private set; }
1313
private SerializationContext _serializationContext;

src/Datadog.Trace/RandomUtils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Datadog.Trace
44
{
5-
public static class RandomUtils
5+
internal static class RandomUtils
66
{
77
public static UInt64 NextUInt63(this Random rnd)
88
{

src/Datadog.Trace/Span.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,13 @@ public ISpan SetTag(string key, string value)
187187
return this;
188188
}
189189
switch (key) {
190-
case Datadog.Trace.Tags.ResourceName:
190+
case DDTags.ResourceName:
191191
ResourceName = value;
192192
return this;
193193
case OpenTracing.Tags.Error:
194194
Error = value == "True";
195195
return this;
196-
case Datadog.Trace.Tags.SpanType:
196+
case DDTags.SpanType:
197197
Type = value;
198198
return this;
199199
}

src/Datadog.Trace/SpanBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace Datadog.Trace
77
{
8-
public class SpanBuilder : ISpanBuilder
8+
internal class SpanBuilder : ISpanBuilder
99
{
1010
private static ILog _log = LogProvider.For<SpanBuilder>();
1111

@@ -112,7 +112,7 @@ public ISpanBuilder WithTag(string key, string value)
112112
{
113113
lock (_lock)
114114
{
115-
if (key == Tags.ServiceName)
115+
if (key == DDTags.ServiceName)
116116
{
117117
_serviceName = value;
118118
return this;

src/Datadog.Trace/Tags.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace Datadog.Trace
22
{
3-
public static class Tags
3+
public static class DDTags
44
{
55
public const string ServiceName = "service.name";
66
public const string ResourceName = "resource.name";

src/Datadog.Trace/Tracer.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ internal class Tracer : ITracer, IDatadogTracer
2121
public Tracer(IAgentWriter agentWriter, List<ServiceInfo> serviceInfo = null, string defaultServiceName = null)
2222
{
2323
_agentWriter = agentWriter;
24-
_defaultServiceName = GetExecutingAssemblyName() ?? Constants.UnkownService;
24+
_defaultServiceName = GetAppDomainFriendlyName() ?? Constants.UnkownService;
2525
if (serviceInfo != null)
2626
{
2727
foreach(var service in serviceInfo)
@@ -35,12 +35,11 @@ public Tracer(IAgentWriter agentWriter, List<ServiceInfo> serviceInfo = null, st
3535
}
3636
}
3737

38-
private string GetExecutingAssemblyName()
38+
private string GetAppDomainFriendlyName()
3939
{
4040
try
4141
{
42-
var name = Assembly.GetExecutingAssembly().GetName();
43-
return name.Name;
42+
return AppDomain.CurrentDomain.FriendlyName;
4443
}
4544
catch
4645
{

src/Datadog.Trace/TracerFactory.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,24 @@ public static class TracerFactory
99
{
1010
private static Uri _defaultUri = new Uri("http://localhost:8126");
1111

12-
public static ITracer GetTracer(Uri uri = null, List<ServiceInfo> serviceInfos = null, string defaultServiceName = null)
12+
/// <summary>
13+
/// Create a new ITracer object with the given parameters
14+
/// </summary>
15+
/// <param name="agentEndpoint">The agent endpoint where the traces will be sent (default is http://localhost:8126).</param>
16+
/// <param name="serviceInfoList">The service information list.</param>
17+
/// <param name="defaultServiceName">Default name of the service (default is the name of the executing assembly).</param>
18+
/// <returns></returns>
19+
public static ITracer GetTracer(Uri agentEndpoint = null, List<ServiceInfo> serviceInfoList = null, string defaultServiceName = null)
1320
{
14-
uri = uri ?? _defaultUri;
15-
return GetTracer(uri, serviceInfos, defaultServiceName, null);
21+
agentEndpoint = agentEndpoint ?? _defaultUri;
22+
return GetTracer(agentEndpoint, serviceInfoList, defaultServiceName, null);
1623
}
1724

18-
internal static Tracer GetTracer(Uri uri, List<ServiceInfo> serviceInfos = null, string defaultServiceName = null, DelegatingHandler delegatingHandler = null)
25+
internal static Tracer GetTracer(Uri agentEndpoint, List<ServiceInfo> serviceInfoList = null, string defaultServiceName = null, DelegatingHandler delegatingHandler = null)
1926
{
20-
var api = new Api(uri, delegatingHandler);
27+
var api = new Api(agentEndpoint, delegatingHandler);
2128
var agentWriter = new AgentWriter(api);
22-
var tracer = new Tracer(agentWriter, serviceInfos, defaultServiceName);
29+
var tracer = new Tracer(agentWriter, serviceInfoList, defaultServiceName);
2330
return tracer;
2431
}
2532
}

0 commit comments

Comments
 (0)