-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmetrics.ts
More file actions
122 lines (110 loc) · 3.19 KB
/
metrics.ts
File metadata and controls
122 lines (110 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* @fileoverview Read-side helpers — `getPerformanceMetrics` returns a
* shallow copy of the recorded rows, `getPerformanceSummary` rolls
* them up per operation (count / total / avg / min / max), and
* `clearPerformanceMetrics` empties the array in place.
*/
import { debugLog } from '../debug/output'
import { MathMax, MathMin, MathRound } from '../primordials/math'
import { ObjectEntries } from '../primordials/object'
import { performanceMetrics } from './_internal'
import type { PerformanceMetrics } from './types'
/**
* Clear all collected performance metrics.
*
* @example
* import { clearPerformanceMetrics } from '@socketsecurity/lib/perf/metrics'
*
* clearPerformanceMetrics()
*/
export function clearPerformanceMetrics(): void {
performanceMetrics.length = 0
debugLog('[perf] Cleared performance metrics')
}
/**
* Get all collected performance metrics.
* Only available when DEBUG=perf is enabled.
*
* @returns Array of performance metrics
*
* @example
* import { getPerformanceMetrics } from '@socketsecurity/lib/perf/metrics'
*
* const metrics = getPerformanceMetrics()
* console.log(metrics)
*/
export function getPerformanceMetrics(): PerformanceMetrics[] {
return [...performanceMetrics]
}
/**
* Get performance summary statistics.
*
* @returns Summary of metrics grouped by operation
*
* @example
* import { getPerformanceSummary } from '@socketsecurity/lib/perf/metrics'
*
* const summary = getPerformanceSummary()
* console.log(summary)
* // {
* // 'api-call': { count: 5, total: 1234, avg: 246.8, min: 100, max: 500 },
* // 'file-read': { count: 10, total: 50, avg: 5, min: 2, max: 15 }
* // }
*/
export function getPerformanceSummary(): Record<
string,
{
count: number
total: number
avg: number
min: number
max: number
}
> {
const summary: Record<
string,
{ count: number; total: number; min: number; max: number }
> = { __proto__: null } as unknown as Record<
string,
{ count: number; total: number; min: number; max: number }
>
for (const metric of performanceMetrics) {
const { duration, operation } = metric
if (!summary[operation]) {
summary[operation] = {
count: 0,
total: 0,
min: Number.POSITIVE_INFINITY,
max: Number.NEGATIVE_INFINITY,
}
}
const stats = summary[operation] as {
count: number
total: number
min: number
max: number
}
stats.count++
stats.total += duration
stats.min = MathMin(stats.min, duration)
stats.max = MathMax(stats.max, duration)
}
// Calculate averages and return with proper typing
const result: Record<
string,
{ count: number; total: number; avg: number; min: number; max: number }
> = { __proto__: null } as unknown as Record<
string,
{ count: number; total: number; avg: number; min: number; max: number }
>
for (const { 0: operation, 1: stats } of ObjectEntries(summary)) {
result[operation] = {
count: stats.count,
total: MathRound(stats.total * 100) / 100,
avg: MathRound((stats.total / stats.count) * 100) / 100,
min: MathRound(stats.min * 100) / 100,
max: MathRound(stats.max * 100) / 100,
}
}
return result
}