Skip to content

Using Custom Tags

Both C# and Native C/C++ support user information, SDK global context, and RUM global context. Log can also be configured with independent global attributes.

Adding at SDK Runtime

Anonymous User ID

Both C# and Native C/C++ generate an anonymous userid starting with ft.rd_ for unauthenticated users during initialization. The ID is isolated by RUM application ID and stored in the identity subdirectory of the SDK cache directory. The same RUM application ID and cache directory continue to use the same ID after process restarts, and the C++ host and Electron Bridge follow the same behavior.

When no user API is called, RUM data uses the anonymous userid; Logs with RUM association enabled also carry this ID. After calling SetUser() or truewatch_sdk_set_user(), subsequent data uses the explicit user ID. After calling the clear API, subsequent data reverts to the original anonymous ID. Deleting the corresponding cache directory resets this ID.

If the identity file is not writable or locking fails, the SDK uses a temporary anonymous ID for the current process and reports the persistence failure through C# DiagnosticListener or Native diagnostic output. Telemetry collection is not interrupted.

Set User

TrueWatchSdk.SetUser(
    id: "user-123",
    name: "Alice",
    email: "alice@example.com",
    extra: new Dictionary<string, object?>
    {
        ["plan"] = "enterprise"
    });
truewatch_sdk_set_user(
    rum,
    "user-123",
    "Alice",
    "alice@example.com");

Clear User:

TrueWatchSdk.ClearUser();
truewatch_sdk_clear_user(rum);

User switching only affects subsequent data and does not modify data that is already queued.

SDK Global Context

Applies to RUM and Logs with RUM association enabled:

TrueWatchSdk.AddGlobalContext("region", "cn-east-1");
TrueWatchSdk.AddGlobalContext("tenant", "tenant-a");
truewatch_sdk_add_global_context(rum, "region", "cn-east-1");
truewatch_sdk_add_global_context(rum, "tenant", "tenant-a");

RUM Global Context

Appended only to RUM data:

TrueWatchSdk.AddRumGlobalContext("ui.framework", "wpf");
truewatch_rum_add_rum_context(rum, "ui.framework", "win32");

Log Global Context

Log-specific tags are configured during Log initialization:

Logging = new LogConfig
{
    EnableCustomLog = true,
    GlobalContext = new Dictionary<string, object?>
    {
        ["logger_name"] = "desktop-client"
    }
}
truewatch_log_property context[] = {
    {"logger_name", "native-client"}
};
logging.global_context = context;
logging.global_context_count = 1;

See Log Configuration for the complete parameter list.

Event-Level Attributes

C# manual RUM and Log APIs accept event-level dictionaries. Native Log accepts truewatch_log_property; the Native RUM v1 manual event API does not provide an arbitrary event-level attribute structure.

TrueWatchSdk.AddAction(
    "Save",
    "click",
    TimeSpan.FromMilliseconds(25),
    new Dictionary<string, object?>
    {
        ["result"] = "success"
    });

Naming and Reserved Fields

  • Use lowercase, stable, aggregatable field names, for example feature.name.
  • Do not write tokens, cookies, passwords, or directly identifiable information.
  • app_id, service, env, version, sdk_name, session_id, view_id, action_id, and platform fields are managed by the SDK.
  • Custom context cannot override SDK reserved fields.
  • Native context APIs copy strings synchronously. Do not pass empty keys.