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

[Resources.Azure] Add support for Container App Jobs #2064

Merged
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f20605c
add support for Container App Jobs
hansmbakker Sep 11, 2024
fa5e938
Update channgelog and readme
hansmbakker Sep 11, 2024
676444d
Merge branch 'main' into feature/container_app_job-detector
Kielek Sep 11, 2024
d75fa62
Fix line length in markdown
hansmbakker Sep 11, 2024
07dd520
Fix test
hansmbakker Sep 11, 2024
703447b
Merge branch 'feature/container_app_job-detector' of https://github.c…
hansmbakker Sep 11, 2024
9789fb6
Label environment variables for Azure Container Apps Jobs
hansmbakker Sep 12, 2024
2d16d93
Merge branch 'main' into feature/container_app_job-detector
hansmbakker Sep 12, 2024
31dd016
Add sample app to show the ContainerAppJob detection behavior
hansmbakker Sep 12, 2024
db4005b
Merge branch 'feature/container_app_job-detector' of https://github.c…
hansmbakker Sep 12, 2024
5fad1c6
remove example containerappjob project
hansmbakker Sep 13, 2024
51844af
Merge branch 'main' into feature/container_app_job-detector
hansmbakker Sep 13, 2024
8a5cc32
md-lint fix
Kielek Sep 16, 2024
cfdb25c
Merge branch 'main' into feature/container_app_job-detector
Kielek Sep 16, 2024
1bc40b8
Merge branch 'main' into feature/container_app_job-detector
cijothomas Sep 16, 2024
1d35b51
Merge branch 'main' into feature/container_app_job-detector
hansmbakker Sep 17, 2024
9d053ea
Merge branch 'main' into feature/container_app_job-detector
Kielek Sep 20, 2024
d6dad2c
Merge branch 'main' into feature/container_app_job-detector
hansmbakker Sep 20, 2024
f6ecf3a
Clear the container apps app / job name env vars between tests
hansmbakker Sep 20, 2024
2897aa2
Merge branch 'main' into feature/container_app_job-detector
Kielek Sep 24, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-Example.ContainerAppJob-78bba48b-2c15-4a83-b45a-be47cf7bfe82</UserSecretsId>

<IsPublishable>true</IsPublishable>
<EnableSdkContainerSupport>true</EnableSdkContainerSupport>
<ContainerRepository>opentelemetry-containerapp-job</ContainerRepository>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Monitor.OpenTelemetry.AspNetCore" Version="1.2.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="$(OpenTelemetryCoreLatestVersion)" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="$(OpenTelemetryCoreLatestVersion)" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="$(OpenTelemetryCoreLatestVersion)" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="$(OpenTelemetryCoreLatestVersion)" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="$(OpenTelemetryCoreLatestVersion)" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="$(OpenTelemetryCoreLatestVersion)" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\OpenTelemetry.Resources.Azure\OpenTelemetry.Resources.Azure.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using Azure.Monitor.OpenTelemetry.AspNetCore;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources.Azure;

Check warning on line 7 in examples/Azure/Example.ContainerAppJob/IHostApplicationBuilderExtensions.cs

View workflow job for this annotation

GitHub Actions / lint-dotnet-format / run-dotnet-format

Using directive is unnecessary.
using OpenTelemetry.Trace;

namespace Example.ContainerAppJob;

public static class IHostApplicationBuilderExtensions
{
public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder)
{
builder.AddAzureContainerAppsDetector();

builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});

builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation();
})
.WithTracing(tracing =>
{
tracing.AddSource("Example.ContainerAppJob")
.AddAspNetCoreInstrumentation()

// Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
// .AddGrpcClientInstrumentation()
.AddHttpClientInstrumentation();
});

builder.AddOpenTelemetryExporters();

return builder;
}

private static IHostApplicationBuilder AddAzureContainerAppsDetector(this IHostApplicationBuilder builder)
{
// Using AzureContainerAppsResourceDetector here requires adding the InternalsVisibleTo attribute in the OpenTelemetry.Resources.Azure package.
builder.Services.AddSingleton<AzureContainerAppsResourceDetector>();

builder.Services.AddOpenTelemetry()
.ConfigureResource(builder => builder
cijothomas marked this conversation as resolved.
Show resolved Hide resolved
.AddDetector(sp =>
sp.GetRequiredService<AzureContainerAppsResourceDetector>()));

return builder;
}

private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder)
{
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);

if (useOtlpExporter)
{
builder.Services.AddOpenTelemetry().UseOtlpExporter();
}

if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
{
builder.Services.AddOpenTelemetry()
.UseAzureMonitor();
}

return builder;
}
}
12 changes: 12 additions & 0 deletions examples/Azure/Example.ContainerAppJob/OpenTelemetryDiagnostics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics;

namespace Example.ContainerAppJob;

public static class OpenTelemetryDiagnostics
{
public const string SourceName = "Example.ContainerAppJob";
public static readonly ActivitySource ActivitySource = new ActivitySource(SourceName);
}
14 changes: 14 additions & 0 deletions examples/Azure/Example.ContainerAppJob/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using Example.ContainerAppJob;

var builder = Host.CreateApplicationBuilder(args);

builder.ConfigureOpenTelemetry();

builder.Services.AddHttpClient();
builder.Services.AddHostedService<Worker>();

var host = builder.Build();
host.Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"Example.ContainerAppJob": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}
43 changes: 43 additions & 0 deletions examples/Azure/Example.ContainerAppJob/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Example.ContainerAppJob

This example demonstrates the working of the `AzureContainerAppsResourceDetector`
in the context of an Azure Container Apps job.

It is intended to run the container image in an Azure Container Apps job.
It expects the `AZURE_APPINSIGHTS_CONNECTION_STRING` environment variable
to be set with the connection string of an Azure Application Insights resource.

## Building it

To build this app, run the following command from the project directory:

```shell
dotnet publish -c Release -r linux-x64 -p:PublishProfile=DefaultContainer
```

Upload it to your container registry:

```shell
az acr login --name <container-registry-name>
docker tag opentelemetry-containerapp-job <container-registry-name>.azurecr.io/opentelemetry-containerapp-job
docker push <container-registry-name>.azurecr.io/opentelemetry-containerapp-job
```

## Prerequisites

- Resources in Azure:

- Azure Container Apps job
- Azure Container Registry
- Azure Application Insights

- Building the code requires
- adding the `InternalsVisibleTo` attribute in `AssemblyInfo.cs`
in the the `OpenTelemetry.Resources.Azure` project because the
`AzureContainerAppsResourceDetector` class is marked `internal`.

```csharp
[assembly: InternalsVisibleTo("Example.ContainerAppJob")]
```

- running docker or podman on the machine
49 changes: 49 additions & 0 deletions examples/Azure/Example.ContainerAppJob/Worker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Collections;
using OpenTelemetry.Trace;

namespace Example.ContainerAppJob;

public class Worker(IHostApplicationLifetime hostApplicationLifetime, IHttpClientFactory httpClientFactory) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using (var exampleActivity = OpenTelemetryDiagnostics.ActivitySource.StartActivity("Example activity"))
{
try
{
await Task.Delay(1000, stoppingToken);
exampleActivity?.AddEvent(new System.Diagnostics.ActivityEvent("Example event"));

var client = httpClientFactory.CreateClient();
var testUri = new Uri("https://www.microsoft.com/");
var result = await client.GetAsync(testUri, stoppingToken);

// Loop over environment variables and add them as tags
foreach (DictionaryEntry envVar in (IDictionary)Environment.GetEnvironmentVariables())
{
if (envVar.Key is null)
{
continue;
}

exampleActivity?.SetTag(envVar.Key.ToString()!, envVar.Value?.ToString());
}

await Task.Delay(1000, stoppingToken);

// Simulate an exception.
throw new Exception("Example exception");
}
catch (Exception ex)
{
exampleActivity?.RecordException(ex);
}
}

// When completed, the entire app host will stop.
hostApplicationLifetime.StopApplication();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
8 changes: 8 additions & 0 deletions examples/Azure/Example.ContainerAppJob/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
30 changes: 20 additions & 10 deletions opentelemetry-dotnet-contrib.sln
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kafka", "kafka", "{3A464E7A
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.ConfluentKafka", "examples\kafka\Examples.ConfluentKafka.csproj", "{9B994669-E839-4C42-A0F1-DF9DD058C1DC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure", "Azure", "{93B1028C-4FA7-4F63-8262-09CFD38930A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.ContainerAppJob", "examples\Azure\Example.ContainerAppJob\Example.ContainerAppJob.csproj", "{BAEA2D8A-78CA-47EF-ABE7-25EB54C564B6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -722,6 +726,14 @@ Global
{A5EF701C-439E-407F-8BB4-394166000C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5EF701C-439E-407F-8BB4-394166000C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5EF701C-439E-407F-8BB4-394166000C6D}.Release|Any CPU.Build.0 = Release|Any CPU
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.Build.0 = Release|Any CPU
{62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.Build.0 = Release|Any CPU
{033CA8D4-1529-413A-B244-07958D5F9A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{033CA8D4-1529-413A-B244-07958D5F9A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{033CA8D4-1529-413A-B244-07958D5F9A48}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -806,14 +818,10 @@ Global
{9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.Build.0 = Release|Any CPU
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.Build.0 = Release|Any CPU
{62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.Build.0 = Release|Any CPU
{BAEA2D8A-78CA-47EF-ABE7-25EB54C564B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAEA2D8A-78CA-47EF-ABE7-25EB54C564B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAEA2D8A-78CA-47EF-ABE7-25EB54C564B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAEA2D8A-78CA-47EF-ABE7-25EB54C564B6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -913,6 +921,8 @@ Global
{2A51E621-BCFA-4D52-96D0-E16AFF48CBE5} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{A5FCDD8F-20FF-4657-804E-707EAD4FE31D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
{A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
{62B7060A-C35B-4D49-A0C2-3BF02880A200} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
{36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{7AD707F9-DC6D-430A-8834-D5DCD517BF6E} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
Expand All @@ -938,8 +948,8 @@ Global
{BE40900A-2859-471D-8802-21DFD73DDAA7} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{3A464E7A-42F3-44B0-B8D7-80521A7704A6} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}
{9B994669-E839-4C42-A0F1-DF9DD058C1DC} = {3A464E7A-42F3-44B0-B8D7-80521A7704A6}
{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
{62B7060A-C35B-4D49-A0C2-3BF02880A200} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
{93B1028C-4FA7-4F63-8262-09CFD38930A5} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}
{BAEA2D8A-78CA-47EF-ABE7-25EB54C564B6} = {93B1028C-4FA7-4F63-8262-09CFD38930A5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66}
Expand Down
Loading
Loading