Skip to content

Latest commit

 

History

History
317 lines (231 loc) · 10.7 KB

File metadata and controls

317 lines (231 loc) · 10.7 KB

Development

Development environment

On all platforms, the minimum requirements are:

Windows

  • Visual Studio 2022 (17.4) or higher
    • Workloads with the following components:
      • ASP.NET and web development
      • .NET desktop development
      • Desktop development with C++
    • Individual components:
      • MSVC v142 - Visual Studio 2019 C++ x64/x86 build tools (version 14.29)

Microsoft provides evaluation developer VMs with Windows and Visual Studio preinstalled.

macOS

  • Run: xcode-select --install

Linux

  • cmake, make, gcc, clang, clang++

GitHub Codespaces

Run:

`./dev/codespaces-init.sh`

Build

This repository uses Nuke for build automation.

Support plugins are available for:

Restore dotnet tools to prepare build tools for solution. This installs the dotnet nuke tool locally.

dotnet tool restore

To see a list of possible targets and configurations run:

dotnet nuke --help

To build, run:

dotnet nuke

The main build artifacts are in bin/tracer-home.

Clean your repository by running:

git clean -fXd

Building NuGet packages locally

To build the NuGet package with the native components (OpenTelemetry.AutoInstrumentation.Runtime.Native) locally it is necessary to download CI artifacts.

Download the bin-* artifacts from a successful CI job and expand each one into a folder with the same name as the artifact under ./bin/ci-artifacts/. The PowerShell snippet below shows how to properly copy and expand the artifacts, it assumes that the code is run from the root of the repository and the CI artifacts we added to ~/Downloads/:

$artifacts = @("bin-alpine", "bin-centos", "bin-macos-11", "bin-windows-2022")
$destFolder = "./bin/ci-artifacts/"
$zipFilesFolder = "~/Downloads/"

rm -r -force $destFolder
mkdir $destFolder

$artifacts | % { $dest = $(Join-Path $destFolder $_); $zip = $(Join-Path $zipFilesFolder $_) + ".zip"; Expand-Archive $zip $dest }

Documentation lint

If you made changes to the Markdown documents (*.md files), ensure that lint tool and spellcheck passed without any issues by executing:

nuke InstallDocumentationTools ValidateDocumentation

Some issues can be automatically fixed by:

nuke MarkdownLintFix

All MarkdownLint tasks require Node.js installed locally.

Managed code formatting

The .NET code formatting is based on the OpenTelemetry .NET repository.

Installing formatter:

dotnet tool install -g dotnet-format

Formatting (Bash):

dotnet-format --folder

Native code formatting

The C++ code formatting is based on the .NET Runtime repository and .NET JIT utils repository.

Installing formatter (Bash):

./scripts/download-clang-tools.sh

Formatting (Bash):

./scripts/format-native.sh

Manual testing

Test environment

The dev/docker-compose.yaml contains configuration for running the OpenTelemetry Collector and Jaeger.

You can run the services using:

docker compose -f dev/docker-compose.yaml up

The following Web UI endpoints are exposed:

You can also find the exported telemetry in dev/log directory.

Instrument an application

Warning Make sure to build and prepare the test environment beforehand.

You can reuse instrument.sh to export profiler environmental variables to your current Shell session:

export OTEL_DOTNET_AUTO_HOME="bin/tracer-home"
. ./instrument.sh

Using playground application

You can use the example playground application to test the local changes.

Release process

The release process is described in releasing.md.

Integration tests

Apart from regular unit tests this repository contains integration tests under test/IntegrationTests as they give the biggest confidence if the auto-instrumentation works properly.

Each test class has its related test application that can be found under test/test-applications/integrations Each library instrumentation has its own test class. Other features are tested via SmokeTests class or have its own test class if a dedicated test application is needed.

Currently, the strategy is to test the library instrumentations against following versions:

  • its lowest supported, but not vulnerable, version,
  • one version from every major release,
  • the latest supported version (defined in test/Directory.Packages.props),
  • other specific versions, eg. containing breaking changes for our instrumentations.

Tests against these versions are executed when you are using nuke commands. In case of execution from Visual Studio, only test against the latest supported are executed.

To update set of the version modify PackageVersionDefinitions.cs, execute LibraryVersionsGenerator, and commit generated files.

Note TestApplication.AspNet.NetFramework is an exception to this strategy as it would not work well, because of multiple dependent packages. TestApplication.AspNet.NetFramework references the latest versions of the ASP.NET packages.

To verify that a test is not flaky, you can manually trigger the verify-test.yml GitHub workflow.

Debug the .NET runtime on Linux

  • Requirements

  • Building .NET Runtime

    ./build.sh clr+libs
  • Using corerun

    PATH="$PATH:$PWD/artifacts/bin/coreclr/Linux.x64.Debug/corerun"
    export CORE_LIBRARIES="$PWD/artifacts/bin/runtime/net6.0-Linux-Debug-x64"
    corerun ~/repos/opentelemetry-dotnet-instrumentation/examples/ConsoleApp/bin/Debug/net6.0/Examples.ConsoleApp.dll
  • Debugging

    The following example shows how you can debug if the profiler is attached:

    ~/repos/opentelemetry-dotnet-instrumentation$ export OTEL_DOTNET_AUTO_HOME="bin/tracer-home"
    ~/repos/opentelemetry-dotnet-instrumentation$ . ./instrument.sh 
    ~/repos/opentelemetry-dotnet-instrumentation$ cd ../runtime/
    ~/repos/runtime$ lldb -- ./artifacts/bin/coreclr/Linux.x64.Debug/corerun ~/repos/opentelemetry-dotnet-instrumentation/examples/ConsoleApp/bin/Debug/net6.0/Examples.ConsoleApp.dll
    (lldb) target create "./artifacts/bin/coreclr/Linux.x64.Debug/corerun"
    Current executable set to '/home/user/repos/runtime/artifacts/bin/coreclr/Linux.x64.Debug/corerun' (x86_64).
    (lldb) settings set -- target.run-args  "/home/user/repos/opentelemetry-dotnet-instrumentation/examples/ConsoleApp/bin/Debug/net6.0/Examples.ConsoleApp.dll"
    (lldb) process launch -s
    Process 1905 launched: '/home/user/repos/runtime/artifacts/bin/coreclr/Linux.x64.Debug/corerun' (x86_64)
    (lldb) process handle -s false SIGUSR1 SIGUSR2
    NAME         PASS   STOP   NOTIFY
    ===========  =====  =====  ======
    SIGUSR1      true   false  true 
    SIGUSR2      true   false  true 
    (lldb) b EEToProfInterfaceImpl::CreateProfiler
    Breakpoint 1: no locations (pending).
    WARNING:  Unable to resolve breakpoint to any actual locations.
    (lldb) s
    Process 1905 stopped
    * thread #1, name = 'corerun', stop reason = instruction step into
        frame #0: 0x00007ffff7fd0103 ld-2.31.so
    ->  0x7ffff7fd0103: callq  0x7ffff7fd0df0            ; ___lldb_unnamed_symbol18$$ld-2.31.so
        0x7ffff7fd0108: movq   %rax, %r12
        0x7ffff7fd010b: movl   0x2c4e7(%rip), %eax
        0x7ffff7fd0111: popq   %rdx
    (lldb) c
    Process 1905 resuming
    1 location added to breakpoint 1
    Process 1905 stopped
    * thread #1, name = 'corerun', stop reason = breakpoint 1.1
        frame #0: 0x00007ffff7050ed2 libcoreclr.so`EEToProfInterfaceImpl::CreateProfiler(this=0x00005555555f7690, pClsid=0x00007fffffffce88, wszClsid=u"{918728DD-259F-4A6A-AC2B-B85E1B658318}", wszProfileDLL=u"/home/user/repos/opentelemetry-dotnet-instrumentation/bin/tracer-home/OpenTelemetry.AutoInstrumentation.Native.so") at eetoprofinterfaceimpl.cpp:633:5
      630      CONTRACTL_END;
      631 
      632      // Always called before Thread created.
    -> 633      _ASSERTE(GetThreadNULLOk() == NULL);
      634 
      635      // Try and CoCreate the registered profiler
      636      ReleaseHolder<ICorProfilerCallback2> pCallback2;
    (lldb) 

    You might need to add a dlerror() call in order to get the error message. For example:

    Process 20148 stopped
    * thread #1, name = 'corerun', stop reason = instruction step over
        frame #0: 0x00007ffff76166f8 libcoreclr.so`LOADLoadLibraryDirect(libraryNameOrPath="/home/user/repos/opentelemetry-dotnet-instrumentation/bin/tracer-home/OpenTelemetry.AutoInstrumentation.Native.so") at module.cpp:1477:9
      1474     if (dl_handle == nullptr)
      1475     {
      1476         LPCSTR err_msg = dlerror();
    -> 1477         TRACE("dlopen() failed %s\n", err_msg);
      1478         SetLastError(ERROR_MOD_NOT_FOUND);
      1479     }
      1480     else
    (lldb) var
    (LPCSTR) libraryNameOrPath = 0x00005555555f84c0 "/home/user/repos/opentelemetry-dotnet-instrumentation/bin/tracer-home/OpenTelemetry.AutoInstrumentation.Native.so"
    (NATIVE_LIBRARY_HANDLE) dl_handle = 0x0000000000000000
    (LPCSTR) err_msg = 0x00005555555f8740 "/home/user/repos/opentelemetry-dotnet-instrumentation/bin/tracer-home/OpenTelemetry.AutoInstrumentation.Native.so: undefined symbol: _binary_Datadog_Trace_ClrProfiler_Managed_Loader_pdb_end"