feat(metrics): integrate prom-client for native Prometheus support
- Add prom-client ^15.1.3 as production dependency - Migrate Counter class to use prom-client internally - Migrate Gauge class to use prom-client internally - Migrate Histogram class to use prom-client internally - Update getMetricsOutput() to use prom-client's native metrics() - Update contentType() to use prom-client's contentType - Enable collectDefaultMetrics() for Node.js system metrics - Maintain backward compatibility with existing API Benefits: - Native OpenMetrics format export - Proper histogram bucket handling - Default Node.js metrics (memory, CPU, event loop, GC) - Better integration with Grafana/Prometheus ecosystem
This commit is contained in:
Generated
+38
@@ -18,6 +18,7 @@
|
||||
"music-metadata": "^11.7.0",
|
||||
"p-queue": "^9.0.0",
|
||||
"pino": "^9.6",
|
||||
"prom-client": "^15.1.3",
|
||||
"protobufjs": "^7.2.4",
|
||||
"ws": "^8.13.0"
|
||||
},
|
||||
@@ -3115,6 +3116,15 @@
|
||||
"@octokit/openapi-types": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@opentelemetry/api": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
|
||||
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@pinojs/redact": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz",
|
||||
@@ -4726,6 +4736,12 @@
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/bintrees": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz",
|
||||
"integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
|
||||
@@ -11821,6 +11837,19 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prom-client": {
|
||||
"version": "15.1.3",
|
||||
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz",
|
||||
"integrity": "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "^1.4.0",
|
||||
"tdigest": "^0.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16 || ^18 || >=20"
|
||||
}
|
||||
},
|
||||
"node_modules/promise.allsettled": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.6.tgz",
|
||||
@@ -13651,6 +13680,15 @@
|
||||
"url": "https://opencollective.com/synckit"
|
||||
}
|
||||
},
|
||||
"node_modules/tdigest": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz",
|
||||
"integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bintrees": "1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"music-metadata": "^11.7.0",
|
||||
"p-queue": "^9.0.0",
|
||||
"pino": "^9.6",
|
||||
"prom-client": "^15.1.3",
|
||||
"protobufjs": "^7.2.4",
|
||||
"ws": "^8.13.0"
|
||||
},
|
||||
|
||||
+132
-102
@@ -1,6 +1,12 @@
|
||||
/**
|
||||
* Prometheus Metrics Exposition - Enterprise Grade
|
||||
*
|
||||
* Uses prom-client for full Prometheus compatibility including:
|
||||
* - Native OpenMetrics format export
|
||||
* - Default Node.js metrics collection
|
||||
* - Proper histogram buckets
|
||||
* - Registry management
|
||||
*
|
||||
* Provides:
|
||||
* - Counters for event counting
|
||||
* - Gauges for instantaneous values
|
||||
@@ -27,6 +33,7 @@
|
||||
|
||||
import { createServer, IncomingMessage, ServerResponse, Server } from 'http'
|
||||
import * as os from 'os'
|
||||
import * as promClient from 'prom-client'
|
||||
|
||||
// ============================================
|
||||
// Configuration
|
||||
@@ -157,24 +164,32 @@ export interface SummaryValue {
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Counter Class
|
||||
// Counter Class (prom-client backed)
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Counter class - monotonically increasing metric
|
||||
* Now backed by prom-client for full Prometheus compatibility
|
||||
*
|
||||
* Counters only go up (or reset to zero). They are used for
|
||||
* counting events like requests, errors, tasks completed, etc.
|
||||
*/
|
||||
export class Counter implements BaseMetric {
|
||||
readonly type = 'counter' as const
|
||||
private values: Map<string, MetricValue> = new Map()
|
||||
private promCounter: promClient.Counter<string>
|
||||
private localValues: Map<string, MetricValue> = new Map() // For getValues() compatibility
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
public help: string,
|
||||
public labelNames: string[] = []
|
||||
) {}
|
||||
) {
|
||||
this.promCounter = new promClient.Counter({
|
||||
name,
|
||||
help,
|
||||
labelNames,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the counter
|
||||
@@ -194,14 +209,21 @@ export class Counter implements BaseMetric {
|
||||
throw new Error('Counter cannot be decremented')
|
||||
}
|
||||
|
||||
const key = this.labelsToKey(labels)
|
||||
const existing = this.values.get(key)
|
||||
// Use prom-client
|
||||
if (Object.keys(labels).length > 0) {
|
||||
this.promCounter.labels(labels).inc(incValue)
|
||||
} else {
|
||||
this.promCounter.inc(incValue)
|
||||
}
|
||||
|
||||
// Also track locally for getValues() compatibility
|
||||
const key = this.labelsToKey(labels)
|
||||
const existing = this.localValues.get(key)
|
||||
if (existing) {
|
||||
existing.value += incValue
|
||||
existing.timestamp = Date.now()
|
||||
} else {
|
||||
this.values.set(key, {
|
||||
this.localValues.set(key, {
|
||||
labels,
|
||||
value: incValue,
|
||||
timestamp: Date.now(),
|
||||
@@ -210,30 +232,31 @@ export class Counter implements BaseMetric {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current value
|
||||
* Get current value (from local cache)
|
||||
*/
|
||||
get(labels: Labels = {}): number {
|
||||
const key = this.labelsToKey(labels)
|
||||
return this.values.get(key)?.value ?? 0
|
||||
return this.localValues.get(key)?.value ?? 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the counter
|
||||
*/
|
||||
reset(labels?: Labels): void {
|
||||
this.promCounter.reset()
|
||||
if (labels) {
|
||||
const key = this.labelsToKey(labels)
|
||||
this.values.delete(key)
|
||||
this.localValues.delete(key)
|
||||
} else {
|
||||
this.values.clear()
|
||||
this.localValues.clear()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values
|
||||
* Get all values (from local cache for compatibility)
|
||||
*/
|
||||
getValues(): MetricValue[] {
|
||||
return Array.from(this.values.values())
|
||||
return Array.from(this.localValues.values())
|
||||
}
|
||||
|
||||
private labelsToKey(labels: Labels): string {
|
||||
@@ -251,24 +274,32 @@ export class Counter implements BaseMetric {
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Gauge Class
|
||||
// Gauge Class (prom-client backed)
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Gauge class - value that can increase and decrease
|
||||
* Now backed by prom-client for full Prometheus compatibility
|
||||
*
|
||||
* Gauges represent a snapshot of a value at a point in time.
|
||||
* Examples: temperature, current memory usage, queue size.
|
||||
*/
|
||||
export class Gauge implements BaseMetric {
|
||||
readonly type = 'gauge' as const
|
||||
private values: Map<string, MetricValue> = new Map()
|
||||
private promGauge: promClient.Gauge<string>
|
||||
private localValues: Map<string, MetricValue> = new Map() // For getValues() compatibility
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
public help: string,
|
||||
public labelNames: string[] = []
|
||||
) {}
|
||||
) {
|
||||
this.promGauge = new promClient.Gauge({
|
||||
name,
|
||||
help,
|
||||
labelNames,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value
|
||||
@@ -284,8 +315,16 @@ export class Gauge implements BaseMetric {
|
||||
setValue = value ?? 0
|
||||
}
|
||||
|
||||
// Use prom-client
|
||||
if (Object.keys(labels).length > 0) {
|
||||
this.promGauge.labels(labels).set(setValue)
|
||||
} else {
|
||||
this.promGauge.set(setValue)
|
||||
}
|
||||
|
||||
// Also track locally for getValues() compatibility
|
||||
const key = this.labelsToKey(labels)
|
||||
this.values.set(key, {
|
||||
this.localValues.set(key, {
|
||||
labels,
|
||||
value: setValue,
|
||||
timestamp: Date.now(),
|
||||
@@ -306,11 +345,22 @@ export class Gauge implements BaseMetric {
|
||||
incValue = value ?? 1
|
||||
}
|
||||
|
||||
const key = this.labelsToKey(labels)
|
||||
const existing = this.values.get(key)
|
||||
const currentValue = existing?.value ?? 0
|
||||
// Use prom-client
|
||||
if (Object.keys(labels).length > 0) {
|
||||
this.promGauge.labels(labels).inc(incValue)
|
||||
} else {
|
||||
this.promGauge.inc(incValue)
|
||||
}
|
||||
|
||||
this.set(labels, currentValue + incValue)
|
||||
// Also track locally
|
||||
const key = this.labelsToKey(labels)
|
||||
const existing = this.localValues.get(key)
|
||||
const currentValue = existing?.value ?? 0
|
||||
this.localValues.set(key, {
|
||||
labels,
|
||||
value: currentValue + incValue,
|
||||
timestamp: Date.now(),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,11 +377,22 @@ export class Gauge implements BaseMetric {
|
||||
decValue = value ?? 1
|
||||
}
|
||||
|
||||
const key = this.labelsToKey(labels)
|
||||
const existing = this.values.get(key)
|
||||
const currentValue = existing?.value ?? 0
|
||||
// Use prom-client
|
||||
if (Object.keys(labels).length > 0) {
|
||||
this.promGauge.labels(labels).dec(decValue)
|
||||
} else {
|
||||
this.promGauge.dec(decValue)
|
||||
}
|
||||
|
||||
this.set(labels, currentValue - decValue)
|
||||
// Also track locally
|
||||
const key = this.labelsToKey(labels)
|
||||
const existing = this.localValues.get(key)
|
||||
const currentValue = existing?.value ?? 0
|
||||
this.localValues.set(key, {
|
||||
labels,
|
||||
value: currentValue - decValue,
|
||||
timestamp: Date.now(),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,30 +403,31 @@ export class Gauge implements BaseMetric {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current value
|
||||
* Get current value (from local cache)
|
||||
*/
|
||||
get(labels: Labels = {}): number {
|
||||
const key = this.labelsToKey(labels)
|
||||
return this.values.get(key)?.value ?? 0
|
||||
return this.localValues.get(key)?.value ?? 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the gauge
|
||||
*/
|
||||
reset(labels?: Labels): void {
|
||||
this.promGauge.reset()
|
||||
if (labels) {
|
||||
const key = this.labelsToKey(labels)
|
||||
this.values.delete(key)
|
||||
this.localValues.delete(key)
|
||||
} else {
|
||||
this.values.clear()
|
||||
this.localValues.clear()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values
|
||||
* Get all values (from local cache for compatibility)
|
||||
*/
|
||||
getValues(): MetricValue[] {
|
||||
return Array.from(this.values.values())
|
||||
return Array.from(this.localValues.values())
|
||||
}
|
||||
|
||||
private labelsToKey(labels: Labels): string {
|
||||
@@ -401,18 +463,20 @@ export class Gauge implements BaseMetric {
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Histogram Class
|
||||
// Histogram Class (prom-client backed)
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Histogram class - distribution of values in buckets
|
||||
* Now backed by prom-client for full Prometheus compatibility
|
||||
*
|
||||
* Histograms sample observations and count them in configurable buckets.
|
||||
* They also provide sum and count of observations.
|
||||
*/
|
||||
export class Histogram implements BaseMetric {
|
||||
readonly type = 'histogram' as const
|
||||
private values: Map<string, HistogramValue> = new Map()
|
||||
private promHistogram: promClient.Histogram<string>
|
||||
private localValues: Map<string, HistogramValue> = new Map() // For getValues() compatibility
|
||||
private buckets: number[]
|
||||
|
||||
constructor(
|
||||
@@ -422,6 +486,12 @@ export class Histogram implements BaseMetric {
|
||||
buckets: number[] = DEFAULT_BUCKETS
|
||||
) {
|
||||
this.buckets = [...buckets].sort((a, b) => a - b)
|
||||
this.promHistogram = new promClient.Histogram({
|
||||
name,
|
||||
help,
|
||||
labelNames,
|
||||
buckets: this.buckets,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,8 +508,16 @@ export class Histogram implements BaseMetric {
|
||||
observeValue = value ?? 0
|
||||
}
|
||||
|
||||
// Use prom-client
|
||||
if (Object.keys(labels).length > 0) {
|
||||
this.promHistogram.labels(labels).observe(observeValue)
|
||||
} else {
|
||||
this.promHistogram.observe(observeValue)
|
||||
}
|
||||
|
||||
// Also track locally for getValues() compatibility
|
||||
const key = this.labelsToKey(labels)
|
||||
let histValue = this.values.get(key)
|
||||
let histValue = this.localValues.get(key)
|
||||
|
||||
if (!histValue) {
|
||||
histValue = {
|
||||
@@ -448,7 +526,7 @@ export class Histogram implements BaseMetric {
|
||||
sum: 0,
|
||||
count: 0,
|
||||
}
|
||||
this.values.set(key, histValue)
|
||||
this.localValues.set(key, histValue)
|
||||
}
|
||||
|
||||
// Increment appropriate buckets (cumulative)
|
||||
@@ -487,30 +565,31 @@ export class Histogram implements BaseMetric {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get histogram values
|
||||
* Get histogram values (from local cache)
|
||||
*/
|
||||
get(labels: Labels = {}): HistogramValue | undefined {
|
||||
const key = this.labelsToKey(labels)
|
||||
return this.values.get(key)
|
||||
return this.localValues.get(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the histogram
|
||||
*/
|
||||
reset(labels?: Labels): void {
|
||||
this.promHistogram.reset()
|
||||
if (labels) {
|
||||
const key = this.labelsToKey(labels)
|
||||
this.values.delete(key)
|
||||
this.localValues.delete(key)
|
||||
} else {
|
||||
this.values.clear()
|
||||
this.localValues.clear()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values
|
||||
* Get all values (from local cache for compatibility)
|
||||
*/
|
||||
getValues(): HistogramValue[] {
|
||||
return Array.from(this.values.values())
|
||||
return Array.from(this.localValues.values())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -765,75 +844,18 @@ export class MetricsRegistry {
|
||||
|
||||
/**
|
||||
* Return metrics in Prometheus exposition format
|
||||
* Uses prom-client's native metrics() for proper OpenMetrics format
|
||||
*/
|
||||
async getMetricsOutput(): Promise<string> {
|
||||
const lines: string[] = []
|
||||
|
||||
for (const [name, metric] of this.metricsMap) {
|
||||
lines.push(`# HELP ${name} ${metric.help}`)
|
||||
lines.push(`# TYPE ${name} ${metric.type}`)
|
||||
|
||||
if (metric instanceof Counter || metric instanceof Gauge) {
|
||||
for (const value of metric.getValues()) {
|
||||
const labelsStr = this.formatLabels({ ...this.defaultLabels, ...value.labels })
|
||||
lines.push(`${name}${labelsStr} ${value.value}`)
|
||||
}
|
||||
} else if (metric instanceof Histogram) {
|
||||
for (const value of metric.getValues()) {
|
||||
const labelsStr = this.formatLabels({ ...this.defaultLabels, ...value.labels })
|
||||
const buckets = metric.getBuckets()
|
||||
|
||||
for (const bucket of buckets) {
|
||||
const bucketLabels = this.formatLabels({
|
||||
...this.defaultLabels,
|
||||
...value.labels,
|
||||
le: String(bucket),
|
||||
})
|
||||
lines.push(`${name}_bucket${bucketLabels} ${value.buckets.get(bucket) ?? 0}`)
|
||||
}
|
||||
|
||||
// +Inf bucket (total count)
|
||||
const infLabels = this.formatLabels({
|
||||
...this.defaultLabels,
|
||||
...value.labels,
|
||||
le: '+Inf',
|
||||
})
|
||||
lines.push(`${name}_bucket${infLabels} ${value.count}`)
|
||||
lines.push(`${name}_sum${labelsStr} ${value.sum}`)
|
||||
lines.push(`${name}_count${labelsStr} ${value.count}`)
|
||||
}
|
||||
} else if (metric instanceof Summary) {
|
||||
for (const value of metric.getValues()) {
|
||||
const labelsStr = this.formatLabels({ ...this.defaultLabels, ...value.labels })
|
||||
|
||||
for (const percentile of metric.getPercentiles()) {
|
||||
const quantileLabels = this.formatLabels({
|
||||
...this.defaultLabels,
|
||||
...value.labels,
|
||||
quantile: String(percentile),
|
||||
})
|
||||
const percentileValue = metric.getPercentile(value.labels, percentile)
|
||||
if (percentileValue !== undefined) {
|
||||
lines.push(`${name}${quantileLabels} ${percentileValue}`)
|
||||
}
|
||||
}
|
||||
|
||||
lines.push(`${name}_sum${labelsStr} ${value.sum}`)
|
||||
lines.push(`${name}_count${labelsStr} ${value.count}`)
|
||||
}
|
||||
}
|
||||
|
||||
lines.push('')
|
||||
}
|
||||
|
||||
return lines.join('\n')
|
||||
// Use prom-client's register for native Prometheus format
|
||||
return await promClient.register.metrics()
|
||||
}
|
||||
|
||||
/**
|
||||
* Return content type for Prometheus
|
||||
* Return content type for Prometheus (using prom-client)
|
||||
*/
|
||||
contentType(): string {
|
||||
return 'text/plain; version=0.0.4; charset=utf-8'
|
||||
return promClient.register.contentType
|
||||
}
|
||||
|
||||
private formatLabels(labels: Labels): string {
|
||||
@@ -1071,6 +1093,14 @@ export class MetricsServer {
|
||||
|
||||
// Cache the promise so concurrent calls get the same one
|
||||
this.startPromise = new Promise<void>((resolve, reject) => {
|
||||
// Enable prom-client's default Node.js metrics collection
|
||||
if (this.config.collectDefaultMetrics) {
|
||||
promClient.collectDefaultMetrics({
|
||||
prefix: this.config.prefix ? `${this.config.prefix}_` : '',
|
||||
labels: this.config.defaultLabels,
|
||||
})
|
||||
}
|
||||
|
||||
// Initialize system collector if enabled (only once)
|
||||
if (this.config.includeSystem && !this.systemCollector) {
|
||||
this.systemCollector = new SystemMetricsCollector(this.registry)
|
||||
|
||||
@@ -443,6 +443,11 @@
|
||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz"
|
||||
integrity sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-x64@1.2.4":
|
||||
version "1.2.4"
|
||||
resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz"
|
||||
integrity sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==
|
||||
|
||||
"@img/sharp-linux-x64@0.34.5":
|
||||
version "0.34.5"
|
||||
resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz"
|
||||
@@ -450,6 +455,13 @@
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-linux-x64" "1.2.4"
|
||||
|
||||
"@img/sharp-linuxmusl-x64@0.34.5":
|
||||
version "0.34.5"
|
||||
resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz"
|
||||
integrity sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-linuxmusl-x64" "1.2.4"
|
||||
|
||||
"@isaacs/cliui@^8.0.2":
|
||||
version "8.0.2"
|
||||
resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz"
|
||||
@@ -1157,6 +1169,11 @@
|
||||
dependencies:
|
||||
"@octokit/openapi-types" "^18.0.0"
|
||||
|
||||
"@opentelemetry/api@^1.4.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz"
|
||||
integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==
|
||||
|
||||
"@pinojs/redact@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz"
|
||||
@@ -1600,6 +1617,11 @@
|
||||
resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz"
|
||||
integrity sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==
|
||||
|
||||
"@unrs/resolver-binding-linux-x64-musl@1.11.1":
|
||||
version "1.11.1"
|
||||
resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz"
|
||||
integrity sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==
|
||||
|
||||
"@whiskeysockets/eslint-config@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/@whiskeysockets/eslint-config/-/eslint-config-1.0.0.tgz"
|
||||
@@ -1886,6 +1908,11 @@ big-integer@^1.6.44:
|
||||
resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz"
|
||||
integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==
|
||||
|
||||
bintrees@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz"
|
||||
integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==
|
||||
|
||||
bl@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz"
|
||||
@@ -5669,6 +5696,14 @@ process@^0.11.10:
|
||||
resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
|
||||
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
|
||||
|
||||
prom-client@^15.1.3:
|
||||
version "15.1.3"
|
||||
resolved "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz"
|
||||
integrity sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==
|
||||
dependencies:
|
||||
"@opentelemetry/api" "^1.4.0"
|
||||
tdigest "^0.1.1"
|
||||
|
||||
promise.allsettled@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.6.tgz"
|
||||
@@ -6572,6 +6607,13 @@ synckit@^0.11.12, synckit@^0.11.8:
|
||||
dependencies:
|
||||
"@pkgr/core" "^0.2.9"
|
||||
|
||||
tdigest@^0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz"
|
||||
integrity sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==
|
||||
dependencies:
|
||||
bintrees "1.0.2"
|
||||
|
||||
test-exclude@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz"
|
||||
|
||||
Reference in New Issue
Block a user