feat: move job metrics from ee to ce (#7608)

* open source job metrics

Signed-off-by: pyranota <pyra@duck.com>

* fix

Signed-off-by: pyranota <pyra@duck.com>

* update

Signed-off-by: pyranota <pyra@duck.com>

---------

Signed-off-by: pyranota <pyra@duck.com>
This commit is contained in:
Pyra
2026-01-19 15:48:50 +00:00
committed by GitHub
parent 1c8c7949fe
commit c04eb371cc
2 changed files with 21 additions and 34 deletions
+19 -28
View File
@@ -36,7 +36,6 @@ use std::{io, panic, time::Duration};
use tracing::{trace_span, Instrument};
use uuid::Uuid;
#[cfg(feature = "enterprise")]
use windmill_common::job_metrics;
#[cfg(target_os = "linux")]
@@ -696,7 +695,6 @@ where
let mut i = 0;
#[cfg(feature = "enterprise")]
let mut memory_metric_id: Result<String, Error> =
Err(Error::NotFound("not yet initialized".to_string()));
@@ -731,32 +729,26 @@ where
let update_job_row = i == 2 || (!*SLOW_LOGS && (i < 20 || (i < 120 && i % 5 == 0) || i % 10 == 0)) || i % 20 == 0;
if update_job_row {
#[cfg(feature = "enterprise")]
{
if job_id != Uuid::nil() {
if let Connection::Sql(ref db) = conn {
// tracking metric starting at i >= 2 b/c first point it useless and we don't want to track metric for super fast jobs
if i == 2 {
memory_metric_id = job_metrics::register_metric_for_job(
&db,
w_id.to_string(),
job_id,
"memory_kb".to_string(),
job_metrics::MetricKind::TimeseriesInt,
Some("Job Memory Footprint (kB)".to_string()),
)
.await;
}
if let Ok(ref metric_id) = memory_metric_id {
if let Err(err) = job_metrics::record_metric(&db, w_id.to_string(), job_id, metric_id.to_owned(), job_metrics::MetricNumericValue::Integer(current_mem)).await {
tracing::error!("Unable to save memory stat for job {} in workspace {}. Error was: {:?}", job_id, w_id, err);
}
if update_job_row && job_id != Uuid::nil() {
if let Connection::Sql(ref db) = conn {
// tracking metric starting at i >= 2 b/c first point it useless and we don't want to track metric for super fast jobs
if i == 2 {
memory_metric_id = job_metrics::register_metric_for_job(
&db,
w_id.to_string(),
job_id,
"memory_kb".to_string(),
job_metrics::MetricKind::TimeseriesInt,
Some("Job Memory Footprint (kB)".to_string()),
)
.await;
}
if let Ok(ref metric_id) = memory_metric_id {
if let Err(err) = job_metrics::record_metric(&db, w_id.to_string(), job_id, metric_id.to_owned(), job_metrics::MetricNumericValue::Integer(current_mem)).await {
tracing::error!("Unable to save memory stat for job {} in workspace {}. Error was: {:?}", job_id, w_id, err);
}
}
}
}
if job_id != Uuid::nil() {
if matches!(conn, Connection::Http(_)) {
if i % 4 != 0 {
// only ping every 4th time (2s) on http agent mode
@@ -764,8 +756,8 @@ where
}
}
let ping_job_status = ping_job_status(&conn, &job_id, Some(*mem_peak), if current_mem > 0 { Some(current_mem) } else { None }).await.unwrap_or_else(|e| {
tracing::error!("Unable to ping job status for job {job_id}. Error was: {:?}", e);
PingJobStatusResponse {
tracing::error!("Unable to ping job status for job {job_id}. Error was: {:?}", e);
PingJobStatusResponse {
canceled_by: None,
canceled_reason: None,
already_completed: false,
@@ -782,7 +774,6 @@ where
break
}
}
}
},
);
}
@@ -1,7 +1,7 @@
<script lang="ts">
import { type MetricDataPoint, MetricsService } from '$lib/gen'
import { displayTime } from '$lib/utils'
import { enterpriseLicense, workspaceStore } from '$lib/stores'
import { workspaceStore } from '$lib/stores'
import {
CategoryScale,
Chart as ChartJS,
@@ -70,11 +70,7 @@
</script>
<div class="relative max-h-100">
{#if !$enterpriseLicense}
<Alert type="warning" title="Enterprise Edition only feature">
Job metrics are only available on Windmill Enterprise Edition.
</Alert>
{:else if (jobMemoryStats?.length ?? 0) === 0}
{#if (jobMemoryStats?.length ?? 0) === 0}
<Alert type="info" title="No metric available"
>No data points available for this job. Metrics are recorded only for jobs running for more
than 500ms.</Alert