diff --git a/.cspell/other.txt b/.cspell/other.txt index 8c9f8cf570..8bbe0c2538 100644 --- a/.cspell/other.txt +++ b/.cspell/other.txt @@ -2,6 +2,7 @@ AWSSDK bitness bytecode cmake +coreutils Couchbase distro ducktype @@ -13,6 +14,7 @@ metricsexporter mkdir mktemp MSMQ +myapp Npgsql omnisharp OTEL_DOTNET_AUTO_FLUSH_ON_UNHANDLEDEXCEPTION diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 43d63eefbb..20fac0eb95 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -35,7 +35,7 @@ Steps to reproduce the behavior: 3. etc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78eab839a0..7a88512499 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,26 +77,43 @@ jobs: include: - machine: windows-2022 distribution: windows + log-dir: "/c/ProgramData/OpenTelemetry .NET AutoInstrumentation/logs" - machine: ubuntu-20.04 distribution: linux-glibc + log-dir: "/var/log/opentelemetry/dotnet" - machine: ubuntu-20.04 distribution: linux-musl + test-instrument: "false" - machine: macos-11 distribution: macos + log-dir: "/var/log/opentelemetry/dotnet" runs-on: ${{ matrix.machine }} steps: - - name: Run convenient installation Bash script + - run: brew install coreutils + if: ${{ runner.os == 'macOS' }} + - name: Download OTel .NET AutoInstrumentation using download.sh shell: bash run: | set -o pipefail curl -sSfL https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/download.sh | DISTRIBUTION=${{ matrix.distribution }} bash -s - - name: Test if ./otel-dotnet-auto contains any files + - name: Test download.sh - verify if binaries are downloaded + shell: bash + run: test "$(ls -A ./otel-dotnet-auto)" + - uses: actions/setup-dotnet@v2.1.1 + with: + dotnet-version: 6.0.x + - run: sudo mkdir -p ${{ matrix.log-dir }} && sudo chmod a+rwx ${{ matrix.log-dir }} # workaround before next release + if: ${{ runner.os != 'Windows' && matrix.test-instrument != 'false' }} + - name: Instrument dotnet using instrument.sh shell: bash run: | - if [ -z "$(ls -A ./otel-dotnet-auto)" ]; then - echo "Empty" - exit 1 - else - echo "otel-dotnet-auto is installed" - fi + set -e + curl -fL https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/instrument.sh -O + DISTRIBUTION=${{ matrix.distribution }} source ./instrument.sh + dotnet help + - name: Test instrument.sh - verify if internal logs are created + if: ${{ matrix.test-instrument != 'false' }} + shell: bash + run: test "$(ls -A '${{ matrix.log-dir }}' )" + diff --git a/docs/README.md b/docs/README.md index 22c1580cbb..02541e8010 100644 --- a/docs/README.md +++ b/docs/README.md @@ -94,15 +94,16 @@ Download and extract the appropriate binaries from > The path where you put the binaries is referenced as `$INSTALL_DIR` -You can also use the [download.sh](../download.sh) script with the following parameters: +You can also use the [download.sh](../download.sh) script which uses following +environment variables as parameters: -| Parameter | Description | Required | Default value | -|----------------|-------------------------------------------------------------------|----------|-----------------------------------------------------------------------------------| -| `DISTRIBUTION` | Possible values: `linux-glibc`, `linux-musl`, `macos`, `windows`. | Yes | | -| `INSTALL_DIR` | Location where binaries are to be installed | No | `./otel-dotnet-auto` | -| `RELEASES_URL` | GitHub releases URL | No | `https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases` | -| `TMPDIR` | Temporary directory used when downloading the files | No | `$(mktemp -d)` | -| `VERSION` | Version to download | No | `v0.3.1-beta.1` | +| Parameter | Description | Required | Default value | +|----------------|------------------------------------------------------------------|----------|-----------------------------------------------------------------------------------| +| `DISTRIBUTION` | Possible values: `linux-glibc`, `linux-musl`, `macos`, `windows` | Yes | | +| `INSTALL_DIR` | Location where binaries are to be installed | No | `./otel-dotnet-auto` | +| `RELEASES_URL` | GitHub releases URL | No | `https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases` | +| `TMPDIR` | Temporary directory used when downloading the files | No | `$(mktemp -d)` | +| `VERSION` | Version to download | No | `v0.3.1-beta.1` | ```sh ( set -o pipefail @@ -157,7 +158,8 @@ OTEL_RESOURCE_ATTRIBUTES=deployment.environment=staging,service.version=1.0.0 On [.NET (Core)](https://dotnet.microsoft.com/download/dotnet), if you don't need [bytecode instrumentations](config.md#instrumentations), -you can unset or remove the following environment variables: +you can unset or remove the following environment variables +to not set the [.NET CLR Profiler](config.md#net-clr-profiler): ```env COR_ENABLE_PROFILING @@ -172,6 +174,23 @@ CORECLR_PROFILER_PATH_64 OTEL_DOTNET_AUTO_INTEGRATIONS_FILE ``` +You can also use the [instrument.sh](../instrument.sh) script which uses following +environment variables as parameters: + +| Parameter | Description | Required | Default value | +|--------------------|------------------------------------------------------------------------|----------|----------------------| +| `DISTRIBUTION` | Possible values: `linux-glibc`, `linux-musl`, `macos`, `windows` | Yes | | +| `ENABLE_PROFILING` | Whether to set the .NET CLR Profiler, possible values: `true`, `false` | No | `true` | +| `INSTALL_DIR` | Location where binaries are to be installed | No | `./otel-dotnet-auto` | + +> On macOS [`coreutils`](https://formulae.brew.sh/formula/coreutils) is required. + +```sh +curl -fL https://raw.githubusercontent.com/open-telemetry/opentelemetry-dotnet-instrumentation/main/instrument.sh -O +DISTRIBUTION=linux-glibc source ./instrument.sh +OTEL_SERVICE_NAME=myapp dotnet run +``` + ## Instrument a Windows Service running a .NET application See [windows-service-instrumentation.md](windows-service-instrumentation.md). diff --git a/download.sh b/download.sh index 458e1ad29d..a871cbbb1e 100755 --- a/download.sh +++ b/download.sh @@ -1,15 +1,15 @@ #!/bin/sh set -e -test -z "$DISTRIBUTION" && { - echo "Please specify the distribution by setting the DISTRIBUTION env var." >&2 - echo "Supported values:" >&2 - echo " linux-glibc" >&2 - echo " linux-musl" >&2 - echo " macos" >&2 - echo " windows" >&2 - exit 1 -} +case "$DISTRIBUTION" in + "linux-glibc"|"linux-musl"|"macos"|"windows") + ;; + *) + echo "Please specify the distribution by setting the DISTRIBUTION env var. Supported values: linux-glibc, linux-musl, macos, windows." >&2 + exit 1 + ;; +esac + test -z "$INSTALL_DIR" && INSTALL_DIR="./otel-dotnet-auto" test -z "$RELEASES_URL" && RELEASES_URL="https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases" test -z "$TMPDIR" && TMPDIR="$(mktemp -d)" diff --git a/instrument.sh b/instrument.sh new file mode 100755 index 0000000000..501f962425 --- /dev/null +++ b/instrument.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +# validate input +case "$DISTRIBUTION" in + "linux-glibc"|"linux-musl"|"macos"|"windows") + ;; + *) + echo "Please specify the distribution by setting the DISTRIBUTION env var. Supported values: linux-glibc, linux-musl, macos, windows." >&2 + return 2 + ;; +esac + +case "$ENABLE_PROFILING" in + "true"|"false") + ;; + "") + ENABLE_PROFILING="true" + ;; + *) + echo "Invalid ENABLE_PROFILING env var. Supported values: true, false." >&2 + return 2 + ;; +esac + +# set defaults +test -z "$INSTALL_DIR" && INSTALL_DIR="./otel-dotnet-auto" + + +# check $INSTALL_DIR and use it to set the absolute path $OTEL_DIR +if [ -z "$(ls -A $INSTALL_DIR)" ]; then + echo "There are no files under the location specified via INSTALL_DIR." + return 1 +fi +if [ "$DISTRIBUTION" == "macos" ]; then + OTEL_DIR=$(greadlink -fn $INSTALL_DIR) +else + OTEL_DIR=$(readlink -fn $INSTALL_DIR) +fi +if [ "$DISTRIBUTION" == "windows" ]; then + OTEL_DIR=$(cygpath -w $OTEL_DIR) +fi +if [ -z "$OTEL_DIR" ]; then + echo "Failed to get INSTALL_DIR absolute path. " + return 1 +fi + +if [ "$ENABLE_PROFILING" = "true" ]; then + # Set the .NET CLR Profiler file sufix + case "$DISTRIBUTION" in + "linux-glibc"|"linux-musl") + SUFIX="so" + ;; + "macos") + SUFIX="dylib" + ;; + "windows") + SUFIX="dll" + ;; + *) + echo "BUG: Unknown distribution. Please submit an issue in https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation." >&2 + return 1 + ;; + esac + + # Enable .NET Framework Profiling API + if [ "$DISTRIBUTION" == "windows" ] + then + export COR_ENABLE_PROFILING="1" + export COR_PROFILER="{918728DD-259F-4A6A-AC2B-B85E1B658318}" + # Set paths for both bitness on Windows, see https://docs.microsoft.com/en-us/dotnet/core/run-time-config/debugging-profiling#profiler-location + export COR_PROFILER_PATH_64="$OTEL_DIR/win-x64/OpenTelemetry.AutoInstrumentation.Native.$SUFIX" + export COR_PROFILER_PATH_32="$OTEL_DIR/win-x86/OpenTelemetry.AutoInstrumentation.Native.$SUFIX" + fi + + # Enable .NET Core Profiling API + export CORECLR_ENABLE_PROFILING="1" + export CORECLR_PROFILER="{918728DD-259F-4A6A-AC2B-B85E1B658318}" + if [ "$DISTRIBUTION" == "windows" ] + then + # Set paths for both bitness on Windows, see https://docs.microsoft.com/en-us/dotnet/core/run-time-config/debugging-profiling#profiler-location + export CORECLR_PROFILER_PATH_64="$OTEL_DIR/win-x64/OpenTelemetry.AutoInstrumentation.Native.$SUFIX" + export CORECLR_PROFILER_PATH_32="$OTEL_DIR/win-x86/OpenTelemetry.AutoInstrumentation.Native.$SUFIX" + else + export CORECLR_PROFILER_PATH="$OTEL_DIR/OpenTelemetry.AutoInstrumentation.Native.$SUFIX" + fi + + # Configure the bytecode instrumentation configuration file + export OTEL_DOTNET_AUTO_INTEGRATIONS_FILE="$OTEL_DIR/integrations.json" +fi + +# Configure .NET Core Runtime +export DOTNET_ADDITIONAL_DEPS="$OTEL_DIR/AdditionalDeps" +export DOTNET_SHARED_STORE="$OTEL_DIR/store" +export DOTNET_STARTUP_HOOKS="$OTEL_DIR/netcoreapp3.1/OpenTelemetry.AutoInstrumentation.StartupHook.dll" + +# Configure OpenTelemetry .NET Auto-Instrumentation +export OTEL_DOTNET_AUTO_HOME="$OTEL_DIR"