|
| 1 | +# Selective sampling |
| 2 | + |
| 3 | +> [!IMPORTANT] |
| 4 | +> Selective sampling is an experimental feature. |
| 5 | +
|
| 6 | +This feature builds on top of the continuous profiling capabilities. |
| 7 | +See [Continuous profiling](./continuous-profiler.md) for more details. |
| 8 | + |
| 9 | +Selective sampling API allows you to enable span-based sampling. |
| 10 | +After span is selected for frequent sampling, any thread associated with |
| 11 | +the span context will be sampled, until span is deselected. |
| 12 | + |
| 13 | +Span can be selected for frequent sampling by calling: |
| 14 | +```csharp |
| 15 | +SelectiveSamplingStart(Activity activity) |
| 16 | + ``` |
| 17 | + |
| 18 | +Span is removed from selection by calling: |
| 19 | +```csharp |
| 20 | +SelectiveSamplingStop(Activity activity) |
| 21 | + ``` |
| 22 | + |
| 23 | +You can enable frequent sampling using the custom plugin, which |
| 24 | +can parse thread sampling data and export it. |
| 25 | + |
| 26 | +## How does the thread sampler work? |
| 27 | + |
| 28 | +The profiler uses the |
| 29 | +[.NET profiler](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/) |
| 30 | +to perform periodic call stack sampling. |
| 31 | + |
| 32 | +The native-side sampling thread, and managed-side exporter thread |
| 33 | +are shared with continuous profiler, if it is enabled. |
| 34 | + |
| 35 | +Continuous profiling and selective sampling can be enabled independently. |
| 36 | + |
| 37 | +## Requirements |
| 38 | + |
| 39 | +* .NET 8.0 or higher (`ICorProfilerInfo12` available in runtime). |
| 40 | +* .NET Framework is not supported, as `ICorProfiler10` and `ICorProfiler12` |
| 41 | + are not available in .NET Fx. |
| 42 | + |
| 43 | +## Enable the frequent sampling |
| 44 | + |
| 45 | +In order to enable the frequent sampling, implement following method in your custom plugin: |
| 46 | + |
| 47 | +```csharp |
| 48 | + public Tuple<uint, TimeSpan, TimeSpan, object> GetSelectiveSamplingConfiguration() |
| 49 | +``` |
| 50 | + |
| 51 | +Fields in the returned tuple are expected to be: |
| 52 | +- `uint` - sampling period in milliseconds (values lower than 50ms are not recommended due to sampling overhead). |
| 53 | +- `TimeSpan` - export interval. |
| 54 | +- `TimeSpan` - export timeout. |
| 55 | +- `object` - exporter instance, expected to contain `ExportSelectedThreadSamples` method. |
| 56 | + |
| 57 | +```csharp |
| 58 | +public void ExportSelectedThreadSamples(byte[] buffer, int read, CancellationToken cancellationToken) |
| 59 | +``` |
| 60 | +The `buffer` contains thread samples encoded by the profiler, `read` is the number of bytes read into the buffer. |
| 61 | + |
| 62 | +See [`TestApplication.SelectiveSampler`](../../test/test-applications/integrations/TestApplication.SelectiveSampler) |
| 63 | +for sample implementation of plugin. |
| 64 | + |
| 65 | +## Limits |
| 66 | + |
| 67 | +- Spans selected for frequent sampling more than 15 minutes in the past will be considered stale |
| 68 | + and will be automatically deselected. |
| 69 | +- Number of spans selected for frequent sampling is limited to 50 at a time. |
| 70 | + |
| 71 | +Thread sampling supported by the continuous profiler, and selective sampling share native-side |
| 72 | +sampling thread, and managed-side exporter thread. |
| 73 | + |
| 74 | +Considering both types of profiling can configure export interval and export timeout, the following rules apply: |
| 75 | +- If different export intervals are configured, the higher export interval will be used. |
| 76 | +- If different export timeouts are configured, the higher export timeout will be used. |
| 77 | + |
| 78 | +Additional restrictions apply to sampling intervals: |
| 79 | +- Continuous profiling interval is required to be higher than selective sampling interval. |
| 80 | +- Continuous profiling interval is required to be a multiple of selective sampling interval. |
| 81 | + |
| 82 | +In order to avoid unnecessary overhead, if both continuous profiling and selective sampling |
| 83 | +are enabled, during collection of the call stacks for all the threads, if thread is associated |
| 84 | +with a span selected for frequent sampling, collected sample will have additional flag set. |
| 85 | +Exporter can use this flag to identify samples associated with spans selected for frequent sampling. |
| 86 | + |
| 87 | +See [`SampleNativeFormatParser`](../../test/test-applications/integrations/TestApplication.ContinuousProfiler/Exporter/SampleNativeFormatParser.cs) for sample implementation. |
0 commit comments