Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A code sample to show how to create new root activities that link to a previously current activity. #4957

Merged
merged 21 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8b25642
A code sample to show how to create new root activities that link to …
kalyanaj Oct 17, 2023
7cbc112
Formatting fixes
kalyanaj Oct 17, 2023
2c27b98
Updating reference URLs
kalyanaj Oct 17, 2023
00f1100
Incorporated review feedback.
kalyanaj Oct 17, 2023
3345e70
Merge branch 'main' into kalyanaj-links-sample
kalyanaj Oct 17, 2023
008fba9
Fix linter issue
kalyanaj Oct 17, 2023
2101bdb
Merge branch 'kalyanaj-links-sample' of https://github.com/kalyanaj/o…
kalyanaj Oct 17, 2023
c39b87c
Fix linting issue
kalyanaj Oct 17, 2023
63f4b8a
Updated README
kalyanaj Oct 18, 2023
09ce4be
Merge branch 'main' into kalyanaj-links-sample
cijothomas Oct 19, 2023
d0d8a9d
Added an additional fan-in sample reference + added link to a related…
kalyanaj Oct 19, 2023
6b96951
Merge branch 'main' into kalyanaj-links-sample
kalyanaj Oct 20, 2023
ea60f3e
Merge branch 'kalyanaj-links-sample' of https://github.com/kalyanaj/o…
kalyanaj Oct 27, 2023
0bb1bc0
Merge branch 'main' into kalyanaj-links-sample
kalyanaj Oct 27, 2023
ebbb81b
Merge branch 'kalyanaj-links-sample' of https://github.com/kalyanaj/o…
kalyanaj Oct 27, 2023
a3cc9a3
Merge branch 'main' into kalyanaj-links-sample
utpilla Nov 1, 2023
0200727
Incorporate PR feedback (fixes to make the output more readable).
kalyanaj Nov 1, 2023
65b100e
Merge branch 'kalyanaj-links-sample' of https://github.com/kalyanaj/o…
kalyanaj Nov 1, 2023
1d6df33
Clarify on usage of the term "resource"
kalyanaj Nov 1, 2023
e308ef6
Incorporated PR feedback from utpilla
kalyanaj Nov 1, 2023
637cc5e
Merge branch 'main' into kalyanaj-links-sample
utpilla Nov 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion OpenTelemetry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEM
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{E69578EB-B456-4062-A645-877CD964528B}"
ProjectSection(SolutionItems) = preProject
.github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml
.github\workflows\ci-aot-md.yml = .github\workflows\ci-aot-md.yml
.github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml
.github\workflows\ci-instrumentation-libraries-md.yml = .github\workflows\ci-instrumentation-libraries-md.yml
.github\workflows\ci-instrumentation-libraries.yml = .github\workflows\ci-instrumentation-libraries.yml
.github\workflows\ci-md.yml = .github\workflows\ci-md.yml
Expand Down Expand Up @@ -315,6 +315,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Metrics", "Metrics", "{1C45
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started-aspnetcore", "docs\logs\getting-started-aspnetcore\getting-started-aspnetcore.csproj", "{99B4D965-8782-4694-8DFA-B7A3630CEF60}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "links-creation", "docs\trace\links-creation-with-new-activities\links-creation.csproj", "{B4856711-6D4C-4246-A686-49458D4C1301}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -589,6 +591,10 @@ Global
{99B4D965-8782-4694-8DFA-B7A3630CEF60}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99B4D965-8782-4694-8DFA-B7A3630CEF60}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99B4D965-8782-4694-8DFA-B7A3630CEF60}.Release|Any CPU.Build.0 = Release|Any CPU
{B4856711-6D4C-4246-A686-49458D4C1301}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4856711-6D4C-4246-A686-49458D4C1301}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4856711-6D4C-4246-A686-49458D4C1301}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4856711-6D4C-4246-A686-49458D4C1301}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -637,6 +643,7 @@ Global
{A0CB9A10-F22D-4E66-A449-74B3D0361A9C} = {A49299FB-C5CD-4E0E-B7E1-B7867BBD67CC}
{1C459B5B-C702-46FF-BF1A-EE795E420FFA} = {A49299FB-C5CD-4E0E-B7E1-B7867BBD67CC}
{99B4D965-8782-4694-8DFA-B7A3630CEF60} = {3862190B-E2C5-418E-AFDC-DB281FB5C705}
{B4856711-6D4C-4246-A686-49458D4C1301} = {5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521}
Expand Down
82 changes: 82 additions & 0 deletions docs/trace/links-creation-with-new-activities/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// <copyright file="Program.cs" company="OpenTelemetry Authors">
// Copyright The 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.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Trace;

namespace LinksCreationWithNewRootActivitiesDemo;

internal class Program
{
private static readonly ActivitySource MyActivitySource = new("LinksCreationWithNewRootActivities");

public static void Main(string[] args)
{
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("LinksCreationWithNewRootActivities")
.AddConsoleExporter()
.Build();

using (var activity = MyActivitySource.StartActivity("SayHello"))
{
activity?.SetTag("foo", 1);
DoFanout();

using (var nestedActivity = MyActivitySource.StartActivity("WrapUp"))
{
nestedActivity?.SetTag("foo", 1);
}
}
}

public static void DoFanout()
{
var previous = Activity.Current;

var activityContext = Activity.Current!.Context;
var links = new List<ActivityLink>
{
new ActivityLink(activityContext),
};

// Fanning out to 10 different operations.
// We create a new root activity for each operation and
// link it to an outer activity that happens to be the current
// activity.
for (int i = 0; i < 10; i++)
{
// Reference: https://opentelemetry.io/docs/instrumentation/net/manual/#creating-new-root-activities
// Since we want to create a new root activity for each of the fanned out operations,
// this step helps us "de-parent" it from the current activity.
Activity.Current = null;

// Reference: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Api#activity-creation-options
// Reference: https://opentelemetry.io/docs/instrumentation/net/manual/#adding-links
kalyanaj marked this conversation as resolved.
Show resolved Hide resolved
// We create a new root activity for each of the fanned out operations and link it to the outer activity.
using var newRootActivityForFannedOutOperation = MyActivitySource.StartActivity(
ActivityKind.Internal, // Set this to the appropriate ActivityKind depending on your scenario
name: "FannedOutActivity",
kalyanaj marked this conversation as resolved.
Show resolved Hide resolved
links: links);

// DO THE FANOUT WORK HERE...
}

// Reset to the previous activity now that we are done with the fanout
// This will ensure that the rest of the code executes in the context of the original activity.
Activity.Current = previous;
}
}
156 changes: 156 additions & 0 deletions docs/trace/links-creation-with-new-activities/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Creating new root activities that link to an existing activity: A Sample

This sample shows how to create new root activities that
[link](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md#links-between-spans)
to an existing activity. This can be useful in a fan-out or batched operation
situation when you want to create a new trace with a new root activity
BEFORE invoking each of the fanned out operations, and at the same time
you want each of these new traces to be linked to the original activity.

To give an example, let's say that:

- Service A receives a request for an operation that impacts 1000s of
resources.
kalyanaj marked this conversation as resolved.
Show resolved Hide resolved
- Service A orchestrates this overall operation by fanning out multiple
calls to Service B, with one call for EACH of the impacted resources.
- Let's say the number of spans generated for a single resource operation
is in the order of several thousands of spans.

In the above example, if you used the same trace for the entire flow, then
you would end up with a huge trace with more than million spans. This will
make visualizing and understanding the trace difficult.

Further, it may make it difficult to do programmatic analytics at the
*individual* resource operation level (for each of the 1000s of resource
operations) as there would be no single trace that corresponds to each
of the individual resource operations.

Instead, by creating a new trace with a new root activity before the fanout
call, you get a separate trace for each of the resource operations. In
addition, by using the "span links" functionality in OpenTelemetry, we link
each of these new root activities to the original activity.

This enables more granular visualization and analytics.

## How does this example work?

To be able to create new root activities, we first set the Activity.Current
to null so that we can "de-parent" the new activity from the current activity.

For each of the fanned out operations, this creates a new root activity. As
part of this activity creation, it links it to the previously current activity.

Finally, we reset Activity.Current to the previous activity now after we are
done with the fanout. This will ensure that the rest of the code executes
in the context of the original activity.

## When should you consider such an option? What are the tradeoffs?

This is a good option to consider for operations that involve batched or
fanout operations if using the same trace causes it to become huge.
Using this approach, you can create a new trace for each of the fanned out
operations and link them to the original activity.

A tradeoff is that now we will have multiple traces instead of a single trace.
However, many Observability tools have the ability to visualize linked traces
together, and hence it is not necessarily a concern from that perspective.
However, this model has the potential to add some complexity to any
programmatic analysis since now it has to understand the concept of linked
traces.

## References

- [Links between spans](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md#links-between-spans)
- [Creating new root activities](https://opentelemetry.io/docs/instrumentation/net/manual/#creating-new-root-activities)
- [Activity Creation Options](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Api#activity-creation-options)

## Sample Output

You should see output such as the below when you run this example. You can see
that EACH of the "fanned out activities" have:

- a new trace ID
- an activity link to the original activity

```text
Activity.TraceId: 5ce4d8ad4926ecdd0084681f46fa38d9
Activity.SpanId: 8f9e9441f0789f6e
Activity.TraceFlags: Recorded
Activity.ActivitySourceName: LinksCreationWithNewRootActivities
Activity.DisplayName: FannedOutActivity
Activity.Kind: Internal
Activity.StartTime: 2023-10-17T01:24:40.4957326Z
Activity.Duration: 00:00:00.0008656
Activity.Links:
2890476acefb53b93af64a0d91939051 16b83c1517629363
Resource associated with Activity:
telemetry.sdk.name: opentelemetry
telemetry.sdk.language: dotnet
telemetry.sdk.version: 0.0.0-alpha.0.2600
service.name: unknown_service:links-creation

Activity.TraceId: 16a8ad23d14a085f2a1f260a4b474d05
Activity.SpanId: 0c3e835cfd60c604
Activity.TraceFlags: Recorded
Activity.ActivitySourceName: LinksCreationWithNewRootActivities
Activity.DisplayName: FannedOutActivity
Activity.Kind: Internal
Activity.StartTime: 2023-10-17T01:24:40.5908290Z
Activity.Duration: 00:00:00.0009197
Activity.Links:
2890476acefb53b93af64a0d91939051 16b83c1517629363
Resource associated with Activity:
telemetry.sdk.name: opentelemetry
telemetry.sdk.language: dotnet
telemetry.sdk.version: 0.0.0-alpha.0.2600
service.name: unknown_service:links-creation

Activity.TraceId: 46f0b5b68173b4acf4f50e1f5cdb3e55
Activity.SpanId: 42e7f4439fc2b416
Activity.TraceFlags: Recorded
Activity.ActivitySourceName: LinksCreationWithNewRootActivities
Activity.DisplayName: FannedOutActivity
Activity.Kind: Internal
Activity.StartTime: 2023-10-17T01:24:40.5930378Z
Activity.Duration: 00:00:00.0008622
Activity.Links:
2890476acefb53b93af64a0d91939051 16b83c1517629363
Resource associated with Activity:
telemetry.sdk.name: opentelemetry
telemetry.sdk.language: dotnet
telemetry.sdk.version: 0.0.0-alpha.0.2600
service.name: unknown_service:links-creation

Activity.TraceId: 2890476acefb53b93af64a0d91939051
Activity.SpanId: 6878c2a84d4d4996
Activity.TraceFlags: Recorded
Activity.ParentSpanId: 16b83c1517629363
Activity.ActivitySourceName: LinksCreationWithNewRootActivities
Activity.DisplayName: WrapUp
Activity.Kind: Internal
Activity.StartTime: 2023-10-17T01:24:40.5950683Z
Activity.Duration: 00:00:00.0008843
Activity.Tags:
foo: 1
Resource associated with Activity:
telemetry.sdk.name: opentelemetry
telemetry.sdk.language: dotnet
telemetry.sdk.version: 0.0.0-alpha.0.2600
service.name: unknown_service:links-creation

Activity.TraceId: 2890476acefb53b93af64a0d91939051
Activity.SpanId: 16b83c1517629363
Activity.TraceFlags: Recorded
Activity.ActivitySourceName: LinksCreationWithNewRootActivities
Activity.DisplayName: SayHello
Activity.Kind: Internal
Activity.StartTime: 2023-10-17T01:24:40.4937024Z
Activity.Duration: 00:00:00.1043390
Activity.Tags:
foo: 1
Resource associated with Activity:
telemetry.sdk.name: opentelemetry
telemetry.sdk.language: dotnet
telemetry.sdk.version: 0.0.0-alpha.0.2600
service.name: unknown_service:links-creation
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Console\OpenTelemetry.Exporter.Console.csproj" />
</ItemGroup>
</Project>
Loading