RUM Configuration¶
The Windows SDK collects the same View, Action, Resource, Error, and Long Task 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¶
| Semantic | .NET / C# | Native C/C++ | Default | Range |
|---|---|---|---|---|
| General Session Sampling | SampleRate |
sample_rate |
1.0 |
0.0–1.0 |
| Error Session Additional Sampling | SessionErrorSampleRate |
session_error_sample_rate |
0.0 |
0.0–1.0 |
The sampling decision remains consistent within the same session. It is recommended to first verify integration with 1.0, then adjust based on data volume.
Collection Boundaries¶
| Capability | .NET / C# | Native C/C++ |
|---|---|---|
| View | WPF, WinForms automatic; WinUI 3 explicit Window association | Invoke View C ABI within the window lifecycle |
| Action | Common UI controls and app launch automatic collection | App launch automatic collection; business operations invoke Action C ABI |
| Resource | HttpClient automatic collection |
WinHTTP adapter or manual Resource C ABI |
| Error | Unhandled exception automatic collection, supports manual Error | Native crash recovery or manual Error |
| Long Task | UI thread detection 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 collect WPF Windows and common controls. |
EnableWinForms |
true |
Automatically collect WinForms Forms and common controls. |
EnableWinUI |
true |
Enable WinUI 3 control collection; Windows still require explicit association. |
EnableWebView |
true |
Automatically discover supported WebView2 controls. |
EnableHttpClient |
true |
Collect Resources via .NET HTTP diagnostic events. |
EnableUnhandledException |
true |
Collect unhandled exceptions in the application domain and UI framework. |
EnableUiThreadBlock |
true |
Monitor UI thread blocking. |
EnableAppLaunch |
true |
Collect the application launch phase. |
UiThreadBlockThreshold |
500 ms |
Long Task threshold. |
UiThreadProbeInterval |
250 ms |
UI thread probe interval. |
UiThreadLongTaskCooldown |
5 s |
Cooldown interval for merging consecutive blocking reports. |
Repeated calls will not re-register the same set of collectors, but the application should still only call this once during the startup flow.
After initialization, the Native SDK automatically collects cold and hot launches by default, generating Actions with action_type=launch_cold and action_type=launch_hot respectively. guance_sdk_config_init() initializes enable_app_launch_tracking to 1; if the automatic launch Action is not needed, set it to 0 before calling guance_sdk_init():
Automatic collection observes the top-level window of the current process and the first composited frame. The cold launch Action includes three phases: before application code runs, application initialization, and the first frame. When the application returns from the background to the foreground, a hot launch Action is generated. The application can still use guance_rum_add_launch_action() to report launch phases measured by the host; after manually reporting a cold launch, the SDK will not generate a duplicate automatic cold launch 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 and must be initialized by calling 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 next-launch crash recovery. |
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 interval for persistent hang reports. |
crash_cache_path |
SDK default directory | Local directory for crash envelopes and optional dumps. |
enable_minidump |
0 |
Whether to retain 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 to let the host-side adapter correctly install and restore the std::terminate handler. The crashing process does not execute network or queue writes; the next initialization converts the limited crash envelope into a RUM Error.
Network Resources¶
With EnableHttpClient = true, the URL, method, status code, total duration, request/response size, and HTTP protocol are automatically recorded. When an explicit handler is required:
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 Header and RUM association, refer to Trace Configuration.
The application should only record DNS, TCP, TLS, or TTFB when the actual network phase timing is available; it should not estimate missing phases.
RUM Manual Instrumentation¶
When automatic collection cannot express business semantics, you can manually report Actions, Views, Errors, Long Tasks, and Resources. .NET / C# uses GuanceSdk, Native C/C++ uses the C ABI in guance_rum.h; both integration methods 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 automatically collected by windows, controls, HttpClient, WinHTTP, or WebView2.
Action¶
Auto-Terminated Action¶
Used to collect user operations and associate Resources, Errors, and Long Tasks generated during the operation:
The normal mode behaves consistently with the Android SDK: only one active Action is kept at a time; consecutive calls to StartAction within 100 ms will ignore the new call; after 100 ms, a subsequent call will end the previous Action and start a new one. An Action ends when the View changes and has a maximum duration of approximately 5 seconds.
Action Waiting for Business Completion¶
When a business operation must cover asynchronous logic, enable the needWait mode. Only this mode requires pairing with StopAction:
You can also save the ActionId and call GuanceSdk.StopAction(actionId) when the business operation completes.
A needWait Action will not be replaced by a new Action until it is explicitly ended, but it is still subject to the approximate 5-second maximum duration and View change restrictions. If an empty ID is returned when starting an Action, it means the call was not accepted, and StopAction should not be called.
Action with Known Duration¶
AddAction is used to directly report an independent Action that has already ended with a known duration. It is not subject to the 100 ms high-frequency protection or the 5-second limit, nor does it associate subsequent Resources, Errors, or Long Tasks.
View¶
Starting a new View automatically ends the current active View. View names should describe stable pages and should 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 non-Exception errors, you can use GuanceSdk.AddError(stack, message, errorType, source). When automatic unhandled exception collection is enabled, if the same exception is manually reported and then re-thrown, eventually causing the process to terminate, an additional windows_crash will be generated; avoid duplicate reporting based on business semantics.
Automatically collected .NET fatal exceptions use error_type=windows_crash, 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 from within a crash handler. For complete type and field descriptions, refer to Application Data Collection.
Long Task¶
When UI thread blocking monitoring is already enabled, do not manually report the same blocking 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 measured DNS, TCP, TLS, and TTFB, you can use RumResourceTiming.FromPhases() to write phase timings; only write the total duration when reliable data is unavailable.
C++ applications can use ResourceScope to ensure the Resource is still ended 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);
For pure C applications, pair guance_rum_start_resource() and guance_rum_stop_resource(); use guance_rum_stop_resource_ext() when writing trace_id, span_id, request size, or HTTP protocol.
The Resource still needs to be ended on request failure, with the status code set to 0. After enabling HttpClient or WinHTTP automatic Resources, do not call the manual API for the same request again.
Flush¶
Manual events are first placed in a local queue. To attempt an immediate upload after a critical flow:
The application should still call ShutdownAsync() or guance_sdk_shutdown() on normal exit. For HTTP Trace propagation and application logging, refer to Trace Configuration and Log Configuration respectively.
Session Replay¶
Experimental Capability
Windows Session Replay is disabled by default and can be explicitly enabled and verified, but it has not yet entered the stable release scope. Integrators must evaluate replay compatibility, privacy, performance, and data volume on their own; the current behavior should not be considered a stability compatibility commitment.
Enable explicitly during 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
}
});
The range for SampleRate and OnErrorSampleRate is 0.0–1.0. After initialization, recording can be controlled manually:
Manual start cannot bypass Enabled = false; it must be enabled in the initialization configuration. For element-level privacy APIs, refer to Windows Session Replay Privacy Override.
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 persisted queue and the v1/write/rum/replay upload channel. guance_rum_start_session_replay() and guance_rum_stop_session_replay() can manually control recording, but the start call will not override the disabled initialization configuration.
WebView2 and Electron page recording enters the same native session, segment, queue, and upload channel via the native Bridge. Refer to WebView2 Monitoring and Electron Monitoring respectively.