Sealights .NET Core agent - Configuring the Profiler-Initiated Collector

Sealights .NET Core agent - Configuring the Profiler-Initiated Collector

There are multiple cases when there is no suitable place in the pipeline to call explicit commands to set and start the Coverage Collector:

  • docker container requires changes to the entry point and replacing a single command with a more complicated script

  • Azure environment - there is no place where we can tell Azure to start the collector before the IIS worker

  • PCF environment also has some complications with stopping BGTL

  • Azure DevOps environment with TestSuits doesn’t allow to override the test runner command.

To avoid explicit execution of the collector, the profiler can start the detached process of the collector on initialization and connect to it without providing CLI args for the collector. All collector configurations should be set over env variables or using the configuration file. Once the profiled process is finished, the profiler will signal the collector to stop.

 

This scenario is valid only if the profiler is instructed to use the PIC feature over the env variable:

SL_PROFILER_INITIALIZECOLLECTOR=1

When working with containers that you do not want to modify by adding the Sealights Agent to it, we recommend to mount a folder to thecontainer with the agent there and simply provide the path to the mounted directory.

Agent Setup

To instruct the profiler to start the collector, the target process should have a set of environmental variables:

Windows (Powershell)

Linux

Windows (Powershell)

Linux

# .Net Legacy [Environment]::SetEnvironmentVariable("COR_ENABLE_PROFILING", "1", "Machine") [Environment]::SetEnvironmentVariable("COR_PROFILER", "{01CA2C22-DC03-4FF5-8350-59E32A3536BA}", "Machine") [Environment]::SetEnvironmentVariable("COR_PROFILER_PATH_32", "path\to\SL.DotNet.ProfilerLib.Windows_x86.dll", "Machine") [Environment]::SetEnvironmentVariable("COR_PROFILER_PATH_64", "path\to\SL.DotNet.ProfilerLib.Windows_x64.dll", "Machine") # .NetCore [Environment]::SetEnvironmentVariable("CORECLR_ENABLE_PROFILING", "1", "Machine") [Environment]::SetEnvironmentVariable("CORECLR_PROFILER", "{01CA2C22-DC03-4FF5-8350-59E32A3536BA}", "Machine") [Environment]::SetEnvironmentVariable("CORECLR_PROFILER_PATH_32", "path\to\SL.DotNet.ProfilerLib.Windows_x86.dll", "Machine") [Environment]::SetEnvironmentVariable("CORECLR_PROFILER_PATH_64", "path\to\SL.DotNet.ProfilerLib.Windows_x64.dll", "Machine") [Environment]::SetEnvironmentVariable("SL_PROFILER_INITIALIZECOLLECTOR", "1", "Machine") [Environment]::SetEnvironmentVariable('SL_SESSION_BUILDSESSIONID', "$SL_BSID", "Machine") #[Environment]::SetEnvironmentVariable('SL_SESSION_BUILDSESSIONIDFILE', "path\to\buildSessionId.txt", "Machine") [Environment]::SetEnvironmentVariable('SL_SESSION_TOKENFILE', "path\to\sltoken.txt", "Machine") [Environment]::SetEnvironmentVariable('SL_SESSION_LABID', "$LAB_ID", "Machine") #[Environment]::SetEnvironmentVariable("SL_PROFILER_INCLUDEPROCESSFILTER", "*include*,*what*,*is*,*ne?ded*", "Machine") #Optional parameters #[Environment]::SetEnvironmentVariable("SL_PROFILER_EXCLUDEPROCESSFILTER", "*exclude*,*unnee?ed", "Machine") #[Environment]::SetEnvironmentVariable("SL_COVERAGECOLLECTOR_STARTUPINACTIVITYTIMEOUTSEC", "10", "Machine") #[Environment]::SetEnvironmentVariable("SL_COVERAGECOLLECTOR_IDLETIMEOUTSEC", "0", "Machine")
export CORECLR_ENABLE_PROFILING=1 export CORECLR_PROFILER="{3B1DAA64-89D4-4999-ABF4-6A979B650B7D}" export CORECLR_PROFILER_PATH_32="path\to\libSL.DotNet.ProfilerLib.Linux.so" export CORECLR_PROFILER_PATH_64="path\to\libSL.DotNet.ProfilerLib.Linux.so" export SL_PROFILER_INITIALIZECOLLECTOR=1 export SL_SESSION_BUILDSESSIONID="$SL_BSID" #export SL_SESSION_BUILDSESSIONIDFILE="path\to\buildSessionId.txt" export SL_SESSION_TOKENFILE="path\to\sltoken.txt" export SL_SESSION_LABID="$LAB_ID" #export SL_PROFILER_INCLUDEPROCESSFILTER="*include*,*what*,*is*,*ne?ded*" #Optional parameters #export SL_PROFILER_EXCLUDEPROCESSFILTER="*exclude*,*unnee?ed" #export SL_COVERAGECOLLECTOR_STARTUPINACTIVITYTIMEOUTSEC=10 #export SL_COVERAGECOLLECTOR_IDLETIMEOUTSEC=0

If the process starts successfully, the profiler starts a connection to the collector using the same key. If the profiled process has child processes, they will reuse the same collector in most cases.

Ensure the variables specifying the profiler path are correct, given where you installed the agent binaries (for example: CORECLR_PROFILER_PATH_32=/usr/local/lib/libSL.DotNet.ProfilerLib.Linux.so)

When you successfully complete this step, you will see new entries appear in the Cockpit > Live Agents Monitor: the testListener and an entity called Profiler with the version details of your application.

Logging (Optional)

If you want to enable logging, you can add the following variables declaration.

Windows (Powershell)

Linux

Windows (Powershell)

Linux

[Environment]::SetEnvironmentVariable("SL_LOGGING_ENABLED", "true", "Machine") [Environment]::SetEnvironmentVariable("SL_LOGLEVEL", "6", "Machine") [Environment]::SetEnvironmentVariable("SL_LOGGING_TOFILE", "true", "Machine") [Environment]::SetEnvironmentVariable("SL_LOGDIR", "path/to/logs/", "Machine") [Environment]::SetEnvironmentVariable("SL_LOGGING_FILENAME", "path/to/logs/pic.log", "Machine")
export SL_LOGGING_ENABLED="true" export SL_LOGLEVEL=6 export SL_LOGGING_TOFILE="true" export SL_LOGDIR="path/to/logs/" export SL_LOGGING_FILENAME="path/to/logs/pic.log"

Sample K8s yaml

spec: initContainers: - name: sealights-dotnet-agent image: ubuntu:latest imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c"] args: - | wget -nv -O sealights-dotnet-agent-linux.tar.gz https://agents.sealights.co/dotnetcore/latest/sealights-dotnet-agent-linux-self-contained.tar.gz tar -xzf ./sealights-dotnet-agent-linux.tar.gz --directory /sealights echo "[Sealights] .NetCore Agent version is: $(cat /sealights/version.txt)" volumeMounts: - mountPath: /sealights name: sealights-dotnet-agent-file containers: - name: your-app-service-container # other container configurations # [...] env: ### SL Profiler - Generic vars - name: SL_SESSION_TOKEN secretKeyRef: name: sealights key: SEALIGHTS_AGENT_TOKEN - name: CORECLR_ENABLE_PROFILING value: "1" - name: CORECLR_PROFILER value: "{3B1DAA64-89D4-4999-ABF4-6A979B650B7D}" - name: CORECLR_PROFILER_PATH_32 value: /sealights/libSL.DotNet.ProfilerLib.Linux.so - name: CORECLR_PROFILER_PATH_64 value: /sealights/libSL.DotNet.ProfilerLib.Linux.so - name: SL_PROFILER_INITIALIZECOLLECTOR value: 1 - name: SL_PROFILER_BLOCKING_CONNECTION_STARTUP value: "ASYNC" ### SL Profiler - Logging - name: SL_LOGGING_ENABLED value: "true" - name: SL_LOGLEVEL value: "6" - name: SL_LOGGING_TOFILE value: "true" - name: SL_LOGDIR value: /sealights/logs/ ### SL Profiler - Env Specific vars - name: SL_SESSION_BUILDSESSIONIDFILE value: "path\to\buildSessionId.txt" - name: SL_SESSION_LABID value: "integ_main_mysampleapplication" volumeMounts: - mountPath: /sealights name: sealights-dotnet-agent-file volumes: - name: sealights-dotnet-agent-file emptyDir: {}