RUM Configuration¶
The Windows SDK collects the same View, Action, Resource, Error, and Long Task data in both C# and Native C/C++. C# provides automatic UI framework collection; Native uses an explicit C ABI and adapters for HWND and WinHTTP.
RUM Initialization Configuration¶
Sampling Configuration¶
| Semantics | .NET / C# | Native C/C++ | Default | Range |
|---|---|---|---|---|
| Regular Session sampling | SampleRate |
sample_rate |
1.0 |
0.0–1.0 |
| Additional Error Session sampling | SessionErrorSampleRate |
session_error_sample_rate |
0.0 |
0.0–1.0 |
The sampling decision remains consistent within the same Session. We recommend verifying integration with 1.0 first, then adjusting based on data volume.
Collection Boundaries¶
| Capability | .NET / C# | Native C/C++ |
|---|---|---|
| View | WPF and WinForms automatic; WinUI 3 requires explicit Window association | Call the View C ABI within the window lifecycle |
| Action | Automatic collection for common UI controls and app launch | Automatic collection for app launch; call the Action C ABI for business operations |
| Resource | Automatic collection via HttpClient |
WinHTTP adapter or manual Resource C ABI |
| Error | Automatic collection for unhandled exceptions; manual Error supported | Native crash recovery or manual Error |
| Long Task | UI thread probing or manual reporting | HWND Watchdog or manual reporting |
Enabling Collection¶
GuanceSdk.EnableAutomaticInstrumentation(new AutomaticInstrumentationOptions
{
EnableWpf = true,
EnableWinForms = true,
EnableWinUI = true,
EnableWebView = true,
EnableHttpClient = true,
EnableUnhandledException = true,
EnableUiThreadBlock = true,
EnableAppLaunch = true,
UiThreadBlockThreshold = TimeSpan.FromMilliseconds(500),
UiThreadProbeInterval = TimeSpan.FromMilliseconds(250),
UiThreadLongTaskCooldown = TimeSpan.FromSeconds(5)
});
Automatic Collection Parameters¶
| Parameter | Default | Description |
|---|---|---|
EnableWpf |
true |
Automatically collects WPF Window and common controls. |
EnableWinForms |
true |
Automatically collects WinForms Form and common controls. |
EnableWinUI |
true |
Enables WinUI 3 control collection; Window still requires explicit association. |
EnableWebView |
true |
Automatically discovers supported WebView2 controls. |
EnableHttpClient |
true |
Collects Resources through .NET HTTP diagnostic events. |
EnableUnhandledException |
true |
Collects unhandled exceptions from application domains and UI frameworks. |
EnableUiThreadBlock |
true |
Monitors UI thread blocking. |
EnableAppLaunch |
true |
Collects the app launch phase. |
UiThreadBlockThreshold |
500 ms |
Long Task threshold. |
UiThreadProbeInterval |
250 ms |
UI thread probe interval. |
UiThreadLongTaskCooldown |
5 s |
Cooldown for merging consecutive blocking reports. |
Repeated calls do not re-register the same set of collectors, but the application should still call this only once during the startup flow.
After initialization, the Native SDK automatically collects cold and hot launches by default and generates Actions with action_type=launch_cold and action_type=launch_hot, respectively. guance_sdk_config_init() initializes enable_app_launch_tracking to 1; if automatic launch Actions are not needed, set it to 0 before calling guance_sdk_init():
Automatic collection observes the current process's top-level window and the first composed frame. A cold start Action includes three phases: before application code runs, application initialization, and the first frame; a hot start Action is generated when the application returns to the foreground from the background. The application can still use guance_rum_add_launch_action() to report a launch phase already measured by the host; once a cold start has been manually reported, the SDK will not generate a duplicate automatic cold start Action.
After creating the top-level window, you can enable the UI Watchdog and crash recovery:
guance_sdk_native_monitoring_config monitoring;
guance_sdk_native_monitoring_config_init(&monitoring);
monitoring.enable_ui_hang_monitoring = 1;
monitoring.main_window_handle = reinterpret_cast<uintptr_t>(main_window);
monitoring.enable_native_crash_reporting = 1;
monitoring.enable_minidump = 0;
if (!guance_sdk_enable_native_monitoring(rum, &monitoring)) {
// Invalid HWND or configuration.
}
Native Monitoring Parameters¶
guance_sdk_native_monitoring_config is a versioned structure; you must call the initialization function first.
| Field | Default | Description |
|---|---|---|
enable_ui_hang_monitoring |
0 |
Whether to enable the HWND UI Watchdog. |
enable_native_crash_reporting |
0 |
Whether to enable SEH and crash recovery on the next launch. |
main_window_handle |
0 |
A valid top-level HWND owned by the current process. |
ui_probe_interval_ms |
250 |
UI probe interval. |
long_task_threshold_ms |
500 |
Long Task threshold. |
hang_threshold_ms |
5000 |
Application Not Responding threshold. |
hang_report_cooldown_ms |
5000 |
Cooldown for continuous hang reports. |
crash_cache_path |
SDK default directory | Local directory for crash envelopes and optional dumps. |
enable_minidump |
0 |
Whether to keep a local minidump; dumps are not uploaded to RUM. |
max_crash_files |
3 |
Maximum number of crash files. |
max_crash_file_bytes |
32 MiB |
Maximum total bytes for crash files. |
C++ applications should include guance_sdk.hpp so that the host-side adapter correctly installs and restores the std::terminate handler. The crashed process does not perform network or queue writes; the next initialization converts the limited crash envelope into a RUM Error.
Network Resources¶
When EnableHttpClient = true, the SDK automatically records the URL, method, status code, total duration, request/response sizes, and HTTP protocol. If you need an explicit handler:
C++ WinHTTP uses a scoped adapter:
guance::rum::WinHttpResource resource(
rum,
request,
"https://api.example.com/items",
"GET");
resource.send();
resource.receive();
For other network libraries, call guance_rum_start_resource() and guance_rum_stop_resource_ext(). For Trace headers and RUM correlation, see Trace Configuration.
Applications should record DNS, TCP, TLS, or TTFB only when real network phase timings are available; do not estimate missing phases.
RUM Manual Instrumentation¶
When automatic collection cannot express business semantics, you can manually report Action, View, Error, Long Task, and Resource. .NET / C# uses GuanceSdk, and Native C/C++ uses the C ABI in guance_rum.h; both integration approaches produce the same Windows RUM data types.
Avoid Duplicate Collection
Manual APIs and automatic collection write to the same Session. Do not manually report data that has already been collected automatically by windows, controls, HttpClient, WinHTTP, or WebView2.
Action¶
Auto-Ending Actions¶
Used to collect user operations and associate Resources, Errors, and Long Tasks generated during the operation:
Normal mode behaves like the Android SDK: only one active Action is kept at any time; consecutive StartAction calls within 100 ms ignore the new call, and a call after more than 100 ms ends the previous Action and starts a new one. An Action ends when the View changes and lasts for about 5 seconds at most.
Actions Waiting for Business Completion¶
When a business operation must cover a piece of asynchronous logic, enable needWait mode. Only this mode must be paired with StopAction:
You can also save the ActionId and call GuanceSdk.StopAction(actionId) when the business logic finishes.
A needWait Action is not replaced by a new Action until explicitly ended, but it is still subject to the approximately 5-second maximum duration and View switch restrictions. If starting an Action returns an empty ID, the call was not accepted, and you should not call StopAction.
Actions with Known Duration¶
AddAction is used to directly report a standalone Action that has already finished and whose duration is known. It is not subject to the 100 ms high-frequency protection or the 5-second limit, and it does not associate with subsequently generated Resources, Errors, or Long Tasks.
View¶
Starting a new View automatically ends the currently active View. View names should describe stable pages and must not contain order numbers, user IDs, object addresses, or search terms.
Error¶
try
{
await LoadOrdersAsync();
}
catch (Exception exception)
{
GuanceSdk.AddError(
exception,
new Dictionary<string, object?>
{
["operation"] = "load_orders"
});
}
For errors that are not Exception, you can use GuanceSdk.AddError(stack, message, errorType, source). When automatic collection of unhandled exceptions is enabled, if the same exception is rethrown after manual reporting and eventually terminates the process, a windows_crash will also be generated; avoid duplicate reporting based on business semantics.
Automatically collected .NET fatal exceptions use error_type=windows_crash, and Native SEH and C++ std::terminate use error_type=native_crash; the error_source for crashes is always logger. Native crash monitoring recovers crash Errors on the next launch; do not call the manual Error API inside a crash handler. For the complete type and field documentation, see Application Data Collection.
Long Task¶
When UI thread blocking monitoring is enabled, do not manually report the same blocking interval again.
Resource¶
var resourceId = GuanceSdk.StartResource(
"https://api.example.com/orders",
"GET");
GuanceSdk.StopResource(
resourceId,
statusCode: 200,
timing: RumResourceTiming.FromTotalElapsed(
TimeSpan.FromMilliseconds(120),
source: "manual"),
responseSize: 2048,
requestSize: 0,
resourceType: "http");
If the application has already measured DNS, TCP, TLS, and TTFB, you can use RumResourceTiming.FromPhases() to write phase timings; when no reliable data is available, write only the total elapsed time.
C++ applications can use ResourceScope to ensure the Resource is still completed on exceptions or early returns:
#include "guance_sdk.hpp"
guance::rum::ResourceScope resource(
rum,
"https://api.example.com/orders",
"GET",
"http");
const auto response = send_request();
resource.complete(
response.status_code,
response.body_size,
response.request_size);
Pure C applications can pair guance_rum_start_resource() with guance_rum_stop_resource(); use guance_rum_stop_resource_ext() when you need to write trace_id, span_id, request size, or the HTTP protocol.
Even when the request fails, you still need to complete the Resource and set the status code to 0. After enabling automatic HttpClient or WinHTTP Resources, do not call the manual API again for the same request.
Flush¶
Manual events enter a local queue first. To attempt reporting immediately after a critical flow:
On normal application exit, you should still call ShutdownAsync() or guance_sdk_shutdown(). For HTTP Trace propagation and application logs, see Trace Configuration and Log Configuration, respectively.
Session Replay¶
Experimental Capability
Windows Session Replay is disabled by default. It can be explicitly enabled and validated, but it is not yet in the stable release scope. Integrators must evaluate replay compatibility, privacy, performance, and data volume on their own, and current behavior should not be considered a stable compatibility commitment.
Explicitly enable it at initialization and set the Replay sampling and default privacy policy:
GuanceSdk.Init(new GuanceConfig
{
// DatawayUrl / ClientToken / RumAppId ...
SessionReplay = new RumSessionReplayConfig
{
Enabled = true,
SampleRate = 1.0,
OnErrorSampleRate = 0.0,
TextAndInputPrivacy = SessionReplayTextAndInputPrivacy.MaskAll,
TouchPrivacy = SessionReplayTouchPrivacy.Show,
ImagePrivacy = SessionReplayImagePrivacy.MaskAll
}
});
SampleRate and OnErrorSampleRate both range from 0.0 to 1.0. After initialization, recording can be controlled manually:
Manually starting recording cannot bypass Enabled = false; it must first be enabled in the initialization configuration. For element-level privacy APIs, see Windows Session Replay Privacy Overrides.
guance_sdk_config config;
guance_sdk_config_init(&config);
config.session_replay_enabled = 1;
config.session_replay_sample_rate = 1.0;
config.session_replay_on_error_sample_rate = 0.0;
guance_sdk_handle rum = guance_sdk_init(&config);
guance_rum_register_replay_window(
rum,
reinterpret_cast<uintptr_t>(main_window));
Native Replay uses a separate persistent queue and the v1/write/rum/replay upload channel. guance_rum_start_session_replay() and guance_rum_stop_session_replay() can control recording manually, but the start call likewise does not override a disabled initialization configuration.
Page recording from WebView2 and Electron enters the same native Session, segment, queue, and upload channel through the native Bridge. See WebView2 Monitoring and Electron Monitoring, respectively.