From fd52fdd35bd87a876be3cae79431c89e3523ee24 Mon Sep 17 00:00:00 2001 From: Christoph Kluge Date: Mon, 5 May 2025 16:41:05 +0200 Subject: [PATCH] add job starttime to legend --- api/schema.graphqls | 1 + internal/graph/generated/generated.go | 64 ++++++++++++++++++- internal/graph/model/models_gen.go | 5 +- internal/graph/schema.resolvers.go | 5 +- web/frontend/src/generic/JobCompare.svelte | 11 +++- .../src/generic/plots/Comparogram.svelte | 3 +- 6 files changed, 80 insertions(+), 9 deletions(-) diff --git a/api/schema.graphqls b/api/schema.graphqls index 1942454..b911d07 100644 --- a/api/schema.graphqls +++ b/api/schema.graphqls @@ -172,6 +172,7 @@ type ScopedStats { type JobStats { jobId: Int! + startTime: Int! stats: [NamedStats!]! } diff --git a/internal/graph/generated/generated.go b/internal/graph/generated/generated.go index 14d1b57..0671d48 100644 --- a/internal/graph/generated/generated.go +++ b/internal/graph/generated/generated.go @@ -171,8 +171,9 @@ type ComplexityRoot struct { } JobStats struct { - JobID func(childComplexity int) int - Stats func(childComplexity int) int + JobID func(childComplexity int) int + StartTime func(childComplexity int) int + Stats func(childComplexity int) int } JobsStatistics struct { @@ -947,6 +948,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.JobStats.JobID(childComplexity), true + case "JobStats.startTime": + if e.complexity.JobStats.StartTime == nil { + break + } + + return e.complexity.JobStats.StartTime(childComplexity), true + case "JobStats.stats": if e.complexity.JobStats.Stats == nil { break @@ -2281,6 +2289,7 @@ type ScopedStats { type JobStats { jobId: Int! + startTime: Int! stats: [NamedStats!]! } @@ -7400,6 +7409,50 @@ func (ec *executionContext) fieldContext_JobStats_jobId(_ context.Context, field return fc, nil } +func (ec *executionContext) _JobStats_startTime(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_JobStats_startTime(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { + ctx = rctx // use context from middleware stack in children + return obj.StartTime, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_JobStats_startTime(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobStats", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _JobStats_stats(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) { fc, err := ec.fieldContext_JobStats_stats(ctx, field) if err != nil { @@ -11197,6 +11250,8 @@ func (ec *executionContext) fieldContext_Query_jobsMetricStats(ctx context.Conte switch field.Name { case "jobId": return ec.fieldContext_JobStats_jobId(ctx, field) + case "startTime": + return ec.fieldContext_JobStats_startTime(ctx, field) case "stats": return ec.fieldContext_JobStats_stats(ctx, field) } @@ -17527,6 +17582,11 @@ func (ec *executionContext) _JobStats(ctx context.Context, sel ast.SelectionSet, if out.Values[i] == graphql.Null { out.Invalids++ } + case "startTime": + out.Values[i] = ec._JobStats_startTime(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "stats": out.Values[i] = ec._JobStats_stats(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/model/models_gen.go b/internal/graph/model/models_gen.go index fdd3bf3..4cadf22 100644 --- a/internal/graph/model/models_gen.go +++ b/internal/graph/model/models_gen.go @@ -97,8 +97,9 @@ type JobResultList struct { } type JobStats struct { - JobID int `json:"jobId"` - Stats []*NamedStats `json:"stats"` + JobID int `json:"jobId"` + StartTime int `json:"startTime"` + Stats []*NamedStats `json:"stats"` } type JobsStatistics struct { diff --git a/internal/graph/schema.resolvers.go b/internal/graph/schema.resolvers.go index 2920e0e..a93a67e 100644 --- a/internal/graph/schema.resolvers.go +++ b/internal/graph/schema.resolvers.go @@ -616,8 +616,9 @@ func (r *queryResolver) JobsMetricStats(ctx context.Context, filter []*model.Job } res = append(res, &model.JobStats{ - JobID: int(job.JobID), - Stats: sres, + JobID: int(job.JobID), + StartTime: int(job.StartTime.Unix()), + Stats: sres, }) } return res, err diff --git a/web/frontend/src/generic/JobCompare.svelte b/web/frontend/src/generic/JobCompare.svelte index 345bfa8..9c1ff94 100644 --- a/web/frontend/src/generic/JobCompare.svelte +++ b/web/frontend/src/generic/JobCompare.svelte @@ -39,6 +39,7 @@ let filter = [...filterBuffer]; let comparePlotData = {}; let jobIds = []; + let jobStarts = []; const sorting = { field: "startTime", type: "col", order: "DESC" }; /* GQL */ @@ -49,6 +50,7 @@ query ($filter: [JobFilter!]!, $metrics: [String!]!) { jobsMetricStats(filter: $filter, metrics: $metrics) { jobId + startTime stats { name data { @@ -72,6 +74,7 @@ $: matchedCompareJobs = $compareData.data != null ? $compareData.data.jobsMetricStats.length : -1; $: if ($compareData.data != null) { jobIds = []; + jobStarts = []; comparePlotData = {} jobs2uplot($compareData.data.jobsMetricStats, metrics) } @@ -121,7 +124,9 @@ let plotIndex = 0 jobs.forEach((j) => { jobIds.push(j.jobId) + jobStarts.push(j.startTime) for (let s of j.stats) { + // comparePlotData[s.name].data[0].push(j.startTime) comparePlotData[s.name].data[0].push(plotIndex) comparePlotData[s.name].data[1].push(s.data.min) comparePlotData[s.name].data[2].push(s.data.avg) @@ -181,6 +186,7 @@ title={'Compare '+ m} xlabel="JobIds" xticks={jobIds} + xtimes={jobStarts} ylabel={m} metric={m} yunit={comparePlotData[m].unit} @@ -188,9 +194,10 @@ /> {/each}

- {#each $compareData.data.jobsMetricStats as job (job.jobId)} + {#each $compareData.data.jobsMetricStats as job, jindex (job.jobId)} - {job.jobId} + {jindex}: {job.jobId} + {new Date(job.startTime * 1000)} {#each job.stats as stat (stat.name)} {stat.name} Min {stat.data.min} diff --git a/web/frontend/src/generic/plots/Comparogram.svelte b/web/frontend/src/generic/plots/Comparogram.svelte index 92db086..386434d 100644 --- a/web/frontend/src/generic/plots/Comparogram.svelte +++ b/web/frontend/src/generic/plots/Comparogram.svelte @@ -24,6 +24,7 @@ export let data; export let xlabel; export let xticks; + export let xtimes; export let ylabel; export let yunit; export let title; @@ -120,7 +121,7 @@ { label: "JobID", value: (u, ts, sidx, didx) => { - return xticks[didx]; + return xticks[didx] + ' (' + new Date(xtimes[didx] * 1000).toLocaleString() + ')'; }, } ];