diff --git a/.pipelines/templates/stages/testing_common/scripts/upload_metrics.sh b/.pipelines/templates/stages/testing_common/scripts/upload_metrics.sh index ec4c5d4d83..31ab4b1b3d 100644 --- a/.pipelines/templates/stages/testing_common/scripts/upload_metrics.sh +++ b/.pipelines/templates/stages/testing_common/scripts/upload_metrics.sh @@ -23,6 +23,7 @@ python bmp-kusto-scripts/kusto_ingestor.py \ --database "$KUSTO_DATABASE_NAME" \ --table "$KUSTO_TABLE_NAME" \ --filepath "$METRICS_FILE" \ - --mapping "$KUSTO_TABLE_MAPPING" + --mapping "$KUSTO_TABLE_MAPPING" \ + --ignore-schema echo "Metrics uploaded successfully to Kusto." diff --git a/crates/trident/src/logging/tracestream.rs b/crates/trident/src/logging/tracestream.rs index 2b14cdbb59..947508ed45 100644 --- a/crates/trident/src/logging/tracestream.rs +++ b/crates/trident/src/logging/tracestream.rs @@ -49,7 +49,6 @@ pub(crate) fn clock_boottime_uptime_secs( } use osutils::{ - dmi, osrelease::{OsRelease, OS_RELEASE_PATH}, uname, virt, }; @@ -806,23 +805,6 @@ where } } -/// Obtain product uuid of the hardware Trident is running on. Falls back to -/// "unknown" (rather than failing) since this value is purely informational -/// metadata attached to trace entries. -/// -/// Takes the raw string from [`dmi::read_product_uuid_raw`], not the typed -/// [`OsUuid`] from [`dmi::read_product_uuid`]: `OsUuid`'s `Display` -/// canonicalizes a well-formed UUID to lowercase, which would silently -/// change this `asset_id`'s representation (and break continuity with prior -/// telemetry for the same asset) on any host whose BIOS reports -/// `product_uuid` in uppercase. -fn product_uuid_or_unknown(uuid: Result) -> String { - uuid.unwrap_or_else(|err| { - debug!("Failed to read product uuid: {err:#}"); - "unknown".into() - }) -} - fn correlation_fields( metric_name: &str, installation_id: &RwLock>, @@ -923,10 +905,6 @@ fn populate_platform_info() -> BTreeMap { let mut platform_info = BTreeMap::new(); let mut sys = System::new(); sys.refresh_all(); - platform_info.insert( - "asset_id".to_string(), - json!(product_uuid_or_unknown(dmi::read_product_uuid_raw())), - ); platform_info.insert("os_release".to_string(), json!(get_os_release())); platform_info.insert("total_cpu".to_string(), json!(sys.cpus().len())); platform_info.insert( @@ -1141,26 +1119,6 @@ mod tests { ); } - #[test] - fn test_read_product_uuid_unknown() { - let uuid = product_uuid_or_unknown(Err(anyhow!("UUID file unavailable"))); - assert_eq!(uuid, "unknown"); - } - - #[test] - fn test_read_product_uuid_exists() { - let uuid = product_uuid_or_unknown(Ok("test_uuid".to_string())); - assert_eq!(uuid, "test_uuid"); - } - - #[test] - fn test_read_product_uuid_preserves_case() { - // Regression test: must not canonicalize/lowercase a well-formed - // uppercase UUID, unlike OsUuid's Display. - let uuid = product_uuid_or_unknown(Ok("6BA7B810-9DAD-11D1-80B4-00C04FD430C8".to_string())); - assert_eq!(uuid, "6BA7B810-9DAD-11D1-80B4-00C04FD430C8"); - } - #[test] fn test_tracestream_write_metric_event_to_file() { let temp_dir = tempfile::tempdir().unwrap(); @@ -1692,7 +1650,7 @@ mod functional_test { // These two remain functional tests (VM-only) because they assert // against the actual host's hardware/platform info (CPU count, memory, - // product UUID, os-release, kernel version) -- unlike the metrics-file + // os-release, kernel version) -- unlike the metrics-file // tests above, there's no way to inject a fake value here, so the // result is inherently host-dependent. @@ -1708,10 +1666,6 @@ mod functional_test { #[functional_test] fn test_populate_platform_info() { let mut expected_platform_info = BTreeMap::new(); - expected_platform_info.insert( - "asset_id".to_string(), - json!(product_uuid_or_unknown(dmi::read_product_uuid_raw())), - ); expected_platform_info.insert("os_release".to_string(), json!(get_os_release())); expected_platform_info.insert("total_cpu".to_string(), json!(4)); expected_platform_info.insert("total_memory_gib".to_string(), json!(6)); diff --git a/docs/Reference/Telemetry.md b/docs/Reference/Telemetry.md index 99bf290d49..45c0a7d28f 100644 --- a/docs/Reference/Telemetry.md +++ b/docs/Reference/Telemetry.md @@ -30,12 +30,16 @@ other commands, including `diagnose` and the gRPC client, append instead. A daemon can accumulate records from multiple gRPC requests in one file. `diagnose` packages the existing metrics file. +The local metrics file can be found here: `/var/log/trident-metrics.jsonl`. +Servicing paths later copy the current file beside the configured +datastore as `trident-metrics--.jsonl` +(under `/var/lib/trident` when using the default datastore path). + ## Host Metadata Every recorded event also includes as much of the following host metadata as is available at the time: -- `asset_id`: the host's DMI product UUID (a stable hardware identifier). - `os_release`: the `VERSION` field from `/etc/os-release`. - `kernel_version`: the running kernel release (`uname -r`). - `total_cpu`: the number of CPUs. @@ -81,7 +85,7 @@ Later events include the persistent IDs when available. ## Correlation ID Lifecycle -The four correlation-style fields above have deliberately different +The three correlation-style fields above have deliberately different lifetimes -- some outlive many servicing operations, some are recreated on every reinstall, and some exist only for a single command invocation. The diagram below shows how each behaves across a representative sequence of @@ -131,18 +135,10 @@ gantt section installation_id installation_id #1 (since install #1) :done, inst1, 2024-01-01, 9d installation_id #2 (since install #2) :done, inst2, 2024-01-10, 2d - - section asset_id - asset_id (never recreated) :active, asset1, 2024-01-01, 11d ``` Reading the diagram by row, from most to least stable: -- **`asset_id`**: identifies the physical machine itself, via its DMI - product UUID. The most stable of the four -- read directly from - hardware rather than the datastore, so it survives every reinstall, - including the second `install` (day 10) that recreates - `installation_id`. - **`installation_id`**: normally created once at the first `install` and shared by its multiboot environments. A multiboot install inherits the running OS's installation ID, persisting it in the staging datastore @@ -159,7 +155,7 @@ Reading the diagram by row, from most to least stable: invocation that stages something new (`install`, `update`, `update-stage`, `rollback`) -- note `update-finalize` does *not* regenerate it, since finalize-only invocations only read the value back. -- **`operation_id`**: the shortest-lived of the four, minted fresh for +- **`operation_id`**: the shortest-lived of the three, minted fresh for every single command invocation and never reused. ## Command Errors