Skip to content

Log Configuration

The Log component of the Windows SDK uses a separate persistent queue and uploads to Logging Intake. C# and Native C/C++ share sampling, level filtering, RUM correlation, and queue semantics. Only application logs explicitly written by the application through the Log API enter this upload pipeline.

Log Initialization Configuration

TrueWatchSdk.Init(new TrueWatchConfig
{
    DatawayUrl = "https://openway.truewatch.com",
    ClientToken = "<client-token>",
    RumAppId = "<rum-app-id>",
    Logging = new LogConfig
    {
        EnableCustomLog = true,
        EnableLinkRumData = true,
        SampleRate = 1.0,
        LevelFilters = new[]
        {
            LogStatus.Info,
            LogStatus.Warning,
            LogStatus.Error,
            LogStatus.Critical
        },
        GlobalContext = new Dictionary<string, object?>
        {
            ["component"] = "desktop-ui"
        }
    }
});

C# Parameters

Parameter Default Description
EnableCustomLog false Whether to accept custom logs. When disabled, AddLog() is not enqueued.
EnableLinkRumData false Whether to correlate with the current RUM Session, View, and Action.
SampleRate 1.0 Independent sample rate for logs, ranging from 0.0 to 1.0.
LevelFilters null Standard log levels allowed for collection; null means no level filtering.
GlobalContext Empty dictionary Global attributes appended to each log.
DiscardStrategy DiscardNew Discard new or oldest data when the queue is full.
truewatch_log_property global_context[] = {
    {"component", "native-ui"}
};

truewatch_log_config logging;
truewatch_log_config_init(&logging);
logging.enable_custom_log = 1;
logging.enable_link_rum_data = 1;
logging.sample_rate = 1.0;
logging.level_filter_mask =
    TRUEWATCH_LOG_INFO |
    TRUEWATCH_LOG_WARNING |
    TRUEWATCH_LOG_ERROR |
    TRUEWATCH_LOG_CRITICAL;
logging.global_context = global_context;
logging.global_context_count = 1;

if (!truewatch_log_configure(rum, &logging)) {
    // The configuration is invalid; Log is not enabled.
}

Native C/C++ Parameters

All versioned structs must call truewatch_log_config_init() first.

Field Default Description
enable_custom_log 0 Whether to accept custom logs.
enable_link_rum_data 0 Whether to correlate with the current RUM context.
sample_rate 1.0 Independent sample rate for logs, ranging from 0.0 to 1.0.
level_filter_mask 0 Bitmask of standard levels; 0 accepts standard levels and custom statuses.
global_context NULL Array of truewatch_log_property. Strings are copied synchronously during configuration.
global_context_count 0 Number of global attributes, up to 1024.
discard_strategy TRUEWATCH_LOG_DISCARD_NEW Discard new or oldest data when the queue is full.

Log, RUM, and Session Replay share the SDK disk cache limit. The cache capacity, number of files, and batch size are all configured through SDK Initialization.

Logger Log Output

The supported standard statuses are debug, info, warning, error, critical, and ok.

TrueWatchSdk.AddLog(
    "saved settings",
    LogStatus.Info,
    new Dictionary<string, object?>
    {
        ["operation"] = "save"
    });

TrueWatchSdk.AddLogs(new[]
{
    new LogEntry("first", LogStatus.Info),
    new LogEntry("second", "audit")
});
truewatch_log_property properties[] = {
    {"operation", "save"}
};

truewatch_log_add(
    rum,
    "saved settings",
    "info",
    properties,
    1);

truewatch_log_entry entries[] = {
    {"first", "info", nullptr, 0},
    {"second", "audit", nullptr, 0}
};
const int accepted = truewatch_log_add_batch(rum, entries, 2);

A single log entry retains at most 30 KiB of UTF-8 data; any excess is truncated at a character boundary. Attributes must not contain tokens, authentication headers, cookies, or sensitive user information.

RUM Correlation

When RUM correlation is enabled for logs, the SDK writes the current session_id, view_id, and action_id to the log. Correlation only uses the active context at the time the log is written and does not retroactively modify already-enqueued data.

Queue and Diagnostics

Logs and RUM use separate queues and upload counters. Flush and normal shutdown process both queues.

var diagnostics = TrueWatchSdk.GetLogDiagnosticsSnapshot();
Console.WriteLine(
    $"enqueued={diagnostics.LogsEnqueued}, " +
    $"droppedByConfig={diagnostics.LogsDroppedByConfiguration}, " +
    $"droppedBySampling={diagnostics.LogsDroppedBySampling}, " +
    $"droppedByLevel={diagnostics.LogsDroppedByLevel}, " +
    $"droppedByCapacity={diagnostics.LogsDroppedByCapacity}, " +
    $"uploaded={diagnostics.UploadSuccessCount}, " +
    $"lastError={diagnostics.LastUploadError}");
truewatch_log_diagnostics diagnostics;
truewatch_log_diagnostics_init(&diagnostics);
if (truewatch_log_get_diagnostics(rum, &diagnostics)) {
    printf("enqueued=%lld dropped=%lld uploaded=%lld\n",
        static_cast<long long>(diagnostics.logs_enqueued),
        static_cast<long long>(diagnostics.logs_dropped),
        static_cast<long long>(diagnostics.upload_success_count));
}