From 384e8a07bcd92849605be1796cdeeb96f00bcd73 Mon Sep 17 00:00:00 2001
From: Omkar Kesarkhane <127078473+omkarK06@users.noreply.github.com>
Date: Fri, 5 Dec 2025 18:24:24 +0530
Subject: [PATCH] fix: changed trace precision from milliseconds to
microseconds (#9230)
---
web/src/plugins/traces/SpanBlock.spec.ts | 6 ++++--
web/src/plugins/traces/SpanBlock.vue | 13 ++++++++-----
web/src/plugins/traces/TraceDetails.vue | 15 ++++++++-------
.../plugins/traces/TraceDetailsSidebar.spec.ts | 8 ++++----
web/src/plugins/traces/TraceDetailsSidebar.vue | 11 +++++------
web/src/utils/zincutils.ts | 7 +++++++
6 files changed, 36 insertions(+), 24 deletions(-)
diff --git a/web/src/plugins/traces/SpanBlock.spec.ts b/web/src/plugins/traces/SpanBlock.spec.ts
index ad0edbe01b..ad181f43ca 100644
--- a/web/src/plugins/traces/SpanBlock.spec.ts
+++ b/web/src/plugins/traces/SpanBlock.spec.ts
@@ -32,8 +32,8 @@ const mockStore = createStore({
const mockSpan = {
_timestamp: 1752490492843047,
- startTimeMs: 1752490492843,
- endTimeMs: 1752490493164,
+ startTimeUs: 1752490492843000,
+ endTimeUs: 1752490493164000,
durationMs: 321.372,
durationUs: 321372,
idleMs: 321.33,
@@ -64,6 +64,8 @@ const mockSpan = {
const mockBaseTracePosition = {
durationMs: 350.372,
startTimeMs: 1752490492843,
+ startTimeUs: 1752490492843000,
+ durationUs: 350372,
tics: [
{
value: 0,
diff --git a/web/src/plugins/traces/SpanBlock.vue b/web/src/plugins/traces/SpanBlock.vue
index f1ad8df74a..6f0f9d6829 100644
--- a/web/src/plugins/traces/SpanBlock.vue
+++ b/web/src/plugins/traces/SpanBlock.vue
@@ -61,6 +61,7 @@ along with this program. If not, see .
ref="spanMarkerRef"
data-test="span-marker"
>
+ {{ leftPosition }} {{ spanWidth }}
{
+ console.log(props.span?.durationUs, props.baseTracePosition?.durationUs);
return Number(
(
- (props.span?.durationMs / props.baseTracePosition?.durationMs) *
+ (props.span?.durationUs / props.baseTracePosition?.durationUs) *
100
).toFixed(2),
);
@@ -205,7 +207,7 @@ export default defineComponent({
});
watch(
- () => props.span.startTimeMs,
+ () => props.span.startTimeUs,
() => {
leftPosition.value = getLeftPosition();
},
@@ -226,8 +228,9 @@ export default defineComponent({
);
watch(
- () => props.span?.durationMs + props.baseTracePosition?.durationMs,
+ () => props.span?.durationUs + props.baseTracePosition?.durationUs,
() => {
+ console.log("calculate width");
spanWidth.value = getSpanWidth();
},
{
diff --git a/web/src/plugins/traces/TraceDetails.vue b/web/src/plugins/traces/TraceDetails.vue
index 97749e10ce..fc214ea712 100644
--- a/web/src/plugins/traces/TraceDetails.vue
+++ b/web/src/plugins/traces/TraceDetails.vue
@@ -892,8 +892,9 @@ export default defineComponent({
const calculateTracePosition = () => {
const tics = [];
baseTracePosition.value["durationMs"] = timeRange.value.end;
- baseTracePosition.value["startTimeMs"] =
- traceTree.value[0].startTimeMs + timeRange.value.start;
+ baseTracePosition.value["durationUs"] = timeRange.value.end * 1000;
+ baseTracePosition.value["startTimeUs"] =
+ traceTree.value[0].startTimeUs + (timeRange.value.start * 1000);
const quarterMs = (timeRange.value.end - timeRange.value.start) / 4;
let time = timeRange.value.start;
for (let i = 0; i <= 4; i++) {
@@ -1088,8 +1089,8 @@ export default defineComponent({
return {
[store.state.zoConfig.timestamp_column]:
span[store.state.zoConfig.timestamp_column],
- startTimeMs: convertTimeFromNsToMs(span.start_time),
- endTimeMs: convertTimeFromNsToMs(span.end_time),
+ startTimeUs: convertTimeFromNsToUs(span.start_time),
+ endTimeUs: convertTimeFromNsToUs(span.end_time),
durationMs: Number((span.duration / 1000).toFixed(4)), // This key is standard, we use for calculating width of span block. This should always be in ms
durationUs: Number(span.duration.toFixed(4)), // This key is used for displaying duration in span block. We convert this us to ms, s in span block
idleMs: convertTime(span.idle_ns),
@@ -1110,7 +1111,7 @@ export default defineComponent({
};
const convertTime = (time: number) => {
- return Number((time / 1000000).toFixed(2));
+ return Number((time / 1000).toFixed(2));
};
const convertTimeFromNsToUs = (time: number) => {
@@ -1153,8 +1154,8 @@ export default defineComponent({
const data: any = [];
for (let i = spanPositionList.value.length - 1; i > -1; i--) {
const absoluteStartTime =
- spanPositionList.value[i].startTimeMs -
- convertTimeFromNsToMs(traceTree.value[0].lowestStartTime * 1000);
+ spanPositionList.value[i].startTimeUs -
+ convertTimeFromNsToUs(traceTree.value[0].lowestStartTime * 1000);
const x1 = Number(
(absoluteStartTime + spanPositionList.value[i].durationMs).toFixed(4),
diff --git a/web/src/plugins/traces/TraceDetailsSidebar.spec.ts b/web/src/plugins/traces/TraceDetailsSidebar.spec.ts
index c44aecbaab..8c017795b0 100644
--- a/web/src/plugins/traces/TraceDetailsSidebar.spec.ts
+++ b/web/src/plugins/traces/TraceDetailsSidebar.spec.ts
@@ -65,7 +65,7 @@ const mockLinks =
const mockSpan = {
_timestamp: 1752490492843047,
- start_time: 1752490492843047200,
+ start_time: 1752490492843000000,
end_time: 1752490493164419300,
duration: 321372,
span_id: "d9603ec7f76eb499",
@@ -92,8 +92,8 @@ const mockSpan = {
};
const mockBaseTracePosition = {
- durationMs: 350.372,
- startTimeMs: 1752490492843,
+ durationUs: 350.372,
+ startTimeUs: 1752490492843000,
tics: [
{
value: 0,
@@ -202,7 +202,7 @@ describe("TraceDetailsSidebar", async () => {
'[data-test="trace-details-sidebar-header-toolbar-start-time"]',
);
expect(startTime.exists()).toBe(true);
- expect(startTime.text()).toContain("Start Time: 0ms");
+ expect(startTime.text()).toContain("Start Time: 0us");
});
it("should display span ID", () => {
diff --git a/web/src/plugins/traces/TraceDetailsSidebar.vue b/web/src/plugins/traces/TraceDetailsSidebar.vue
index 9382948711..d7a6942730 100644
--- a/web/src/plugins/traces/TraceDetailsSidebar.vue
+++ b/web/src/plugins/traces/TraceDetailsSidebar.vue
@@ -472,7 +472,7 @@ import { defineComponent, onBeforeMount, ref, watch, type Ref } from "vue";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import { computed } from "vue";
-import { formatTimeWithSuffix, convertTimeFromNsToMs } from "@/utils/zincutils";
+import { formatTimeWithSuffix, convertTimeFromNsToUs } from "@/utils/zincutils";
import useTraces from "@/composables/useTraces";
import { useRouter } from "vue-router";
import { onMounted } from "vue";
@@ -865,9 +865,8 @@ export default defineComponent({
const getStartTime = computed(() => {
return (
- convertTimeFromNsToMs(props.span.start_time) -
- (props.baseTracePosition?.startTimeMs || 0) +
- "ms"
+ formatTimeWithSuffix(convertTimeFromNsToUs(props.span.start_time) -
+ (props.baseTracePosition?.startTimeUs || 0))
);
});
@@ -888,8 +887,8 @@ export default defineComponent({
trace_id: link.context.traceId,
span_id: link.context.spanId,
from:
- convertTimeFromNsToMs(props.span.start_time) * 1000 - 3600000000,
- to: convertTimeFromNsToMs(props.span.end_time) * 1000 + 3600000000,
+ convertTimeFromNsToUs(props.span.start_time) - 3600000000,
+ to: convertTimeFromNsToUs(props.span.end_time) + 3600000000,
org_identifier: store.state.selectedOrganization.identifier,
};
diff --git a/web/src/utils/zincutils.ts b/web/src/utils/zincutils.ts
index 5dc3facdf1..d75ab179ac 100644
--- a/web/src/utils/zincutils.ts
+++ b/web/src/utils/zincutils.ts
@@ -1063,6 +1063,13 @@ export const convertTimeFromNsToMs = (time: number) => {
return date.getTime();
};
+export const convertTimeFromNsToUs = (time: number) => {
+ const nanoseconds = time;
+ const microseconds = Math.floor(nanoseconds / 1000);
+ const date = new Date(microseconds);
+ return date.getTime();
+};
+
export const arraysMatch = (arr1: Array
, arr2: Array) => {
// Check if arrays have the same length
if (arr1.length !== arr2.length) return false;