diff --git a/integration-examples/splunk-otel-dotnet-docker/Dockerfile b/integration-examples/splunk-otel-dotnet-docker/Dockerfile new file mode 100644 index 0000000..fff8d87 --- /dev/null +++ b/integration-examples/splunk-otel-dotnet-docker/Dockerfile @@ -0,0 +1,42 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER app +WORKDIR /app +EXPOSE 8080 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["MultiStageDocker/MultiStageDocker.csproj", "MultiStageDocker/"] +RUN dotnet restore "./MultiStageDocker/./MultiStageDocker.csproj" +COPY . . +WORKDIR "/src/MultiStageDocker" +RUN dotnet build "./MultiStageDocker.csproj" -c $BUILD_CONFIGURATION -o /app/build + +# Add dependencies for splunk-otel-dotnet-install.sh +RUN apt-get update && \ + apt-get install -y unzip + +# Download Splunk OTel .NET installer +RUN curl -sSfL https://github.com/signalfx/splunk-otel-dotnet/releases/latest/download/splunk-otel-dotnet-install.sh -O + +# Install the distribution +RUN sh ./splunk-otel-dotnet-install.sh + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./MultiStageDocker.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final + +# Copy instrumentation file tree +WORKDIR "//home/app/.splunk-otel-dotnet" +COPY --from=build /root/.splunk-otel-dotnet/ . + +WORKDIR /app +COPY --from=publish /app/publish . +COPY --from=build /src/MultiStageDocker/entrypoint.sh . + +ENTRYPOINT ["sh", "entrypoint.sh"] +CMD ["dotnet", "MultiStageDocker.dll"] \ No newline at end of file diff --git a/integration-examples/splunk-otel-dotnet-docker/MultiStageDocker.csproj b/integration-examples/splunk-otel-dotnet-docker/MultiStageDocker.csproj new file mode 100644 index 0000000..ce6dc0a --- /dev/null +++ b/integration-examples/splunk-otel-dotnet-docker/MultiStageDocker.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + Linux + + + + + + + diff --git a/integration-examples/splunk-otel-dotnet-docker/Program.cs b/integration-examples/splunk-otel-dotnet-docker/Program.cs new file mode 100644 index 0000000..1760df1 --- /dev/null +++ b/integration-examples/splunk-otel-dotnet-docker/Program.cs @@ -0,0 +1,6 @@ +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); + +app.MapGet("/", () => "Hello World!"); + +app.Run(); diff --git a/integration-examples/splunk-otel-dotnet-docker/README.md b/integration-examples/splunk-otel-dotnet-docker/README.md new file mode 100644 index 0000000..de531ca --- /dev/null +++ b/integration-examples/splunk-otel-dotnet-docker/README.md @@ -0,0 +1,88 @@ +# Splunk OTel Dotnet & Docker + +This example demonstrates the execution of a .NET application within a Docker container, utilizing the Splunk Distribution of OpenTelemetry for .NET. +The Docker image is constructed using a multi-stage Docker image approach, wherein the build image is more substantial, and the runtime image is a barebone image. + +The installation of instrumentation needs to be divided between different stages. +During the build step, the instrumentation is installed, and subsequently, the outcome is transferred to the final image, eliminating the necessity for additional dependencies specified in a separate build step. + +The `entrypoint.sh` is essential for sourcing environment variables from the `instrument.sh` script, which is included with the instrumentation. This ensures the correct setup of environment variables for each platform. + +## Instructions + +Execute or run points 1-3 manually: + +```bash +docker run -d \ + -e OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED=true \ + -p 8181:8080 \ + multistagedocker:latest +``` + +1. Set `ENV OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED=true` in the Dockerfile for verification purposes. +1. Build the Docker image. +1. Map a random host port (e.g.: 8181) to the container port (8080). +1. Open your browser and navigate to `http://localhost:8181`. +1. Verify the execution of instrumentation by examining the container logs, which should now include Activity information. (Refer to the sample output below.) + +Sample log output: + +```txt +2023-12-01 15:34:28 info: Microsoft.Hosting.Lifetime[14] +2023-12-01 15:34:28 Now listening on: http://[::]:8080 +2023-12-01 15:34:28 info: Microsoft.Hosting.Lifetime[0] +2023-12-01 15:34:28 Application started. Press Ctrl+C to shut down. +2023-12-01 15:34:28 info: Microsoft.Hosting.Lifetime[0] +2023-12-01 15:34:28 Hosting environment: Production +2023-12-01 15:34:28 info: Microsoft.Hosting.Lifetime[0] +2023-12-01 15:34:28 Content root path: /app +2023-12-01 15:34:32 Activity.TraceId: 7f34db4b569f6b6dd6c77c1a5d5164e2 +2023-12-01 15:34:32 Activity.SpanId: 87c76863b1d6b603 +2023-12-01 15:34:32 Activity.TraceFlags: Recorded +2023-12-01 15:34:32 Activity.ActivitySourceName: OpenTelemetry.Instrumentation.AspNetCore +2023-12-01 15:34:32 Activity.DisplayName: GET / +2023-12-01 15:34:32 Activity.Kind: Server +2023-12-01 15:34:32 Activity.StartTime: 2023-12-01T13:34:32.4239711Z +2023-12-01 15:34:32 Activity.Duration: 00:00:00.0958729 +2023-12-01 15:34:32 Activity.Tags: +2023-12-01 15:34:32 net.host.name: localhost +2023-12-01 15:34:32 net.host.port: 8181 +2023-12-01 15:34:32 http.method: GET +2023-12-01 15:34:32 http.scheme: http +2023-12-01 15:34:32 http.target: / +2023-12-01 15:34:32 http.url: http://localhost:8181/ +2023-12-01 15:34:32 http.flavor: 1.1 +2023-12-01 15:34:32 http.user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0 +2023-12-01 15:34:32 http.route: / +2023-12-01 15:34:32 http.status_code: 200 +2023-12-01 15:34:32 Resource associated with Activity: +2023-12-01 15:34:32 service.name: MultiStageDocker +2023-12-01 15:34:32 splunk.distro.version: 1.2.0 +2023-12-01 15:34:32 telemetry.distro.name: splunk-otel-dotnet +2023-12-01 15:34:32 telemetry.distro.version: 1.2.0 +2023-12-01 15:34:32 container.id: 9cc3abcf5e01dd5276768fe5e008ffc0a83cb57073d8dd98dc2e2c79f5620100 +2023-12-01 15:34:32 telemetry.sdk.name: opentelemetry +2023-12-01 15:34:32 telemetry.sdk.language: dotnet +2023-12-01 15:34:32 telemetry.sdk.version: 1.6.0 +2023-12-01 15:34:32 +``` + +## Common known issues + +### Visual Studio is not starting the instrumentation + +Utilize Visual Studio for constructing the Docker image by right-clicking on the Dockerfile and selecting "Build Docker image." Use Docker Desktop to run the image. It is noteworthy that initiating a container directly from Visual Studio is known to not start the instrumentation. + +### instrument.sh is not found + +Linux distributions that do not recognize CRLF (Carriage Return Line Feed) file endings may encounter issues when executing the `entrypoint.sh` script. It is necessary to ensure that on such systems, `entrypoint.sh` uses LF (Line Feed) file endings, especially when the file has been modified in a Windows environment. + +See more info [here](https://en.wikipedia.org/wiki/Newline#Issues_with_different_newline_formats). + +### The docker exec process may not display all environment variables + +The environment variables derived from the `instrument.sh` are not visible when the `env` command is executed through `docker exec`. This occurs because `docker exec` initiates a new session, and the environment variables set in the entry point only apply to the `dotnet MultiStageDocker.dll` session. + +### Activity log does not appear + +Either the instrumentation wasn't configured properly, or there is no action triggering the activity. In this example, opening the browser at `http://localhost:8181` generates HTTP activity. diff --git a/integration-examples/splunk-otel-dotnet-docker/entrypoint.sh b/integration-examples/splunk-otel-dotnet-docker/entrypoint.sh new file mode 100644 index 0000000..e0ef4dc --- /dev/null +++ b/integration-examples/splunk-otel-dotnet-docker/entrypoint.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# Read in the file of environment settings +. /$HOME/.splunk-otel-dotnet/instrument.sh + +# Then run the CMD +exec "$@" \ No newline at end of file