@wise-old-man/utils 3.3.12 → 3.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +3 -229
- package/dist/es/index.js +3 -229
- package/dist/es/index.mjs +3 -229
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var axios = require('axios');
|
|
4
|
-
var prometheus = require('prom-client');
|
|
5
|
-
var zod = require('zod');
|
|
6
|
-
require('dotenv/config');
|
|
7
|
-
var fetchable = require('@attio/fetchable');
|
|
8
|
-
|
|
9
3
|
var config = {
|
|
10
4
|
defaultUserAgent: `WiseOldMan JS Client v${process.env.npm_package_version}`,
|
|
11
5
|
baseAPIUrl: 'https://api.wiseoldman.net/v2'
|
|
@@ -75,7 +69,7 @@ function handleError(status, path, data) {
|
|
|
75
69
|
throw new BadRequestError(path, data.message, data.data);
|
|
76
70
|
}
|
|
77
71
|
if (status === 403) {
|
|
78
|
-
throw new ForbiddenError(path, data.message);
|
|
72
|
+
throw new ForbiddenError(path, data.message, data.data);
|
|
79
73
|
}
|
|
80
74
|
if (status === 404) {
|
|
81
75
|
throw new NotFoundError(path, data.message);
|
|
@@ -97,11 +91,12 @@ class BadRequestError extends Error {
|
|
|
97
91
|
}
|
|
98
92
|
}
|
|
99
93
|
class ForbiddenError extends Error {
|
|
100
|
-
constructor(resource, message) {
|
|
94
|
+
constructor(resource, message, data) {
|
|
101
95
|
super(message);
|
|
102
96
|
this.name = 'ForbiddenError';
|
|
103
97
|
this.resource = resource;
|
|
104
98
|
this.statusCode = 403;
|
|
99
|
+
this.data = data;
|
|
105
100
|
}
|
|
106
101
|
}
|
|
107
102
|
class NotFoundError extends Error {
|
|
@@ -2067,226 +2062,6 @@ function getParentEfficiencyMetric(metric) {
|
|
|
2067
2062
|
return null;
|
|
2068
2063
|
}
|
|
2069
2064
|
|
|
2070
|
-
/**
|
|
2071
|
-
* This file has been created as a way to force any usage
|
|
2072
|
-
* of process.env to go through a dotenv.config first.
|
|
2073
|
-
*/
|
|
2074
|
-
/**
|
|
2075
|
-
* This ensures that an env var is required in prod but optional in dev/test.
|
|
2076
|
-
*/
|
|
2077
|
-
function prodOnly(varSchema) {
|
|
2078
|
-
if (process.env.NODE_ENV === 'production') {
|
|
2079
|
-
return varSchema;
|
|
2080
|
-
}
|
|
2081
|
-
return zod.z.optional(varSchema);
|
|
2082
|
-
}
|
|
2083
|
-
const envVariablesSchema = zod.z.object({
|
|
2084
|
-
// Prisma Database URL
|
|
2085
|
-
CORE_DATABASE_URL: zod.z.string().trim().min(1),
|
|
2086
|
-
// Redis Configs
|
|
2087
|
-
REDIS_HOST: zod.z.string().trim().min(1),
|
|
2088
|
-
REDIS_PORT: zod.z.coerce.number().positive().int(),
|
|
2089
|
-
// Node Environment
|
|
2090
|
-
NODE_ENV: zod.z.enum(['development', 'production', 'test']),
|
|
2091
|
-
// Port for the API to run on
|
|
2092
|
-
API_PORT: zod.z.optional(zod.z.coerce.number().positive().int()),
|
|
2093
|
-
// Admin Password (For mod+ operations)
|
|
2094
|
-
ADMIN_PASSWORD: prodOnly(zod.z.string().trim().min(1)),
|
|
2095
|
-
// Sentry (for error tracking)
|
|
2096
|
-
API_SENTRY_DSN: prodOnly(zod.z.string().trim().min(1)),
|
|
2097
|
-
// Patreon Token (to access their API)
|
|
2098
|
-
PATREON_BEARER_TOKEN: prodOnly(zod.z.string().trim().min(1)),
|
|
2099
|
-
// Discord Bot API URL (to send events to)
|
|
2100
|
-
DISCORD_BOT_API_URL: prodOnly(zod.z.string().trim().min(1).url()),
|
|
2101
|
-
// Our Prometheus metrics aggregator service URL
|
|
2102
|
-
PROMETHEUS_METRICS_SERVICE_URL: prodOnly(zod.z.string().trim().min(1).url()),
|
|
2103
|
-
// Discord Monitoring Webhooks
|
|
2104
|
-
DISCORD_PATREON_WEBHOOK_URL: prodOnly(zod.z.string().trim().min(1).url()),
|
|
2105
|
-
DISCORD_MONITORING_WEBHOOK_URL: prodOnly(zod.z.string().trim().min(1).url()),
|
|
2106
|
-
// Proxy Configs
|
|
2107
|
-
PROXY_LIST: prodOnly(zod.z.string().trim().min(1)),
|
|
2108
|
-
PROXY_USER: prodOnly(zod.z.string().trim().min(1)),
|
|
2109
|
-
PROXY_PASSWORD: prodOnly(zod.z.string().trim().min(1)),
|
|
2110
|
-
PROXY_PORT: prodOnly(zod.z.coerce.number().positive().int()),
|
|
2111
|
-
CPU_COUNT: prodOnly(zod.z.coerce.number().positive().int()),
|
|
2112
|
-
// Openai API Key
|
|
2113
|
-
OPENAI_API_KEY: prodOnly(zod.z.string().trim().min(1).startsWith('sk-'))
|
|
2114
|
-
});
|
|
2115
|
-
// This will load env vars from a .env file, type check them,and throw an error
|
|
2116
|
-
// (interrupting the process) if they're required and missing, or of an invalid type.
|
|
2117
|
-
try {
|
|
2118
|
-
envVariablesSchema.parse(process.env);
|
|
2119
|
-
}
|
|
2120
|
-
catch (error) {
|
|
2121
|
-
const errorPayload = JSON.stringify(error, null, 2);
|
|
2122
|
-
throw new Error(`Invalid environment variables. Please check env.ts for more info.\n${errorPayload}`);
|
|
2123
|
-
}
|
|
2124
|
-
function getThreadIndex() {
|
|
2125
|
-
if (process.env.pm_id === undefined) {
|
|
2126
|
-
return null;
|
|
2127
|
-
}
|
|
2128
|
-
return parseInt(process.env.pm_id, 10);
|
|
2129
|
-
}
|
|
2130
|
-
|
|
2131
|
-
class PrometheusService {
|
|
2132
|
-
constructor() {
|
|
2133
|
-
this.pushInterval = null;
|
|
2134
|
-
this.registry = new prometheus.Registry();
|
|
2135
|
-
this.registry.setDefaultLabels({ app: 'wise-old-man', threadIndex: getThreadIndex() });
|
|
2136
|
-
prometheus.collectDefaultMetrics({ register: this.registry });
|
|
2137
|
-
this.effectHistogram = new prometheus.Histogram({
|
|
2138
|
-
name: 'effect_duration_seconds',
|
|
2139
|
-
help: 'Duration of effects in microseconds',
|
|
2140
|
-
labelNames: ['effectName', 'status'],
|
|
2141
|
-
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10, 30]
|
|
2142
|
-
});
|
|
2143
|
-
this.httpHistogram = new prometheus.Histogram({
|
|
2144
|
-
name: 'http_request_duration_seconds',
|
|
2145
|
-
help: 'Duration of HTTP requests in microseconds',
|
|
2146
|
-
labelNames: ['method', 'route', 'status', 'userAgent'],
|
|
2147
|
-
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10, 30]
|
|
2148
|
-
});
|
|
2149
|
-
this.jobHistogram = new prometheus.Histogram({
|
|
2150
|
-
name: 'job_duration_seconds',
|
|
2151
|
-
help: 'Duration of jobs in microseconds',
|
|
2152
|
-
labelNames: ['jobName', 'status'],
|
|
2153
|
-
buckets: [0.1, 0.5, 1, 5, 10, 30, 60]
|
|
2154
|
-
});
|
|
2155
|
-
this.jobQueueGauge = new prometheus.Gauge({
|
|
2156
|
-
name: 'job_queue_size',
|
|
2157
|
-
help: 'Number of jobs in different states for each queue',
|
|
2158
|
-
labelNames: ['queueName', 'state']
|
|
2159
|
-
});
|
|
2160
|
-
this.eventCounter = new prometheus.Counter({
|
|
2161
|
-
name: 'event_counter',
|
|
2162
|
-
help: 'Count of events emitted',
|
|
2163
|
-
labelNames: ['eventType']
|
|
2164
|
-
});
|
|
2165
|
-
this.customPeriodCounter = new prometheus.Counter({
|
|
2166
|
-
name: 'custom_period_counter',
|
|
2167
|
-
help: 'Count of custom period expressions used',
|
|
2168
|
-
labelNames: ['customPeriod']
|
|
2169
|
-
});
|
|
2170
|
-
this.updatePlayerJobSourceCounter = new prometheus.Counter({
|
|
2171
|
-
name: 'update_player_job_source_counter',
|
|
2172
|
-
help: 'Count of update player jobs dispatched',
|
|
2173
|
-
labelNames: ['source']
|
|
2174
|
-
});
|
|
2175
|
-
this.runeMetricsHistogram = new prometheus.Histogram({
|
|
2176
|
-
name: 'runemetrics_duration_seconds',
|
|
2177
|
-
help: 'Duration of RuneMetrics requests in microseconds',
|
|
2178
|
-
labelNames: ['status'],
|
|
2179
|
-
buckets: [0.1, 0.3, 0.5, 1, 5, 10, 30]
|
|
2180
|
-
});
|
|
2181
|
-
this.hiscoresHistogram = new prometheus.Histogram({
|
|
2182
|
-
name: 'hiscores_duration_seconds',
|
|
2183
|
-
help: 'Duration of hiscores requests in microseconds',
|
|
2184
|
-
labelNames: ['status'],
|
|
2185
|
-
buckets: [0.1, 0.3, 0.5, 1, 5, 10, 30]
|
|
2186
|
-
});
|
|
2187
|
-
this.registry.registerMetric(this.jobHistogram);
|
|
2188
|
-
this.registry.registerMetric(this.jobQueueGauge);
|
|
2189
|
-
this.registry.registerMetric(this.httpHistogram);
|
|
2190
|
-
this.registry.registerMetric(this.effectHistogram);
|
|
2191
|
-
this.registry.registerMetric(this.eventCounter);
|
|
2192
|
-
this.registry.registerMetric(this.customPeriodCounter);
|
|
2193
|
-
this.registry.registerMetric(this.updatePlayerJobSourceCounter);
|
|
2194
|
-
this.registry.registerMetric(this.runeMetricsHistogram);
|
|
2195
|
-
this.registry.registerMetric(this.hiscoresHistogram);
|
|
2196
|
-
}
|
|
2197
|
-
init() {
|
|
2198
|
-
this.pushInterval = setInterval(() => {
|
|
2199
|
-
this.pushMetrics();
|
|
2200
|
-
}, 60000);
|
|
2201
|
-
}
|
|
2202
|
-
shutdown() {
|
|
2203
|
-
if (this.pushInterval !== null) {
|
|
2204
|
-
clearInterval(this.pushInterval);
|
|
2205
|
-
}
|
|
2206
|
-
}
|
|
2207
|
-
pushMetrics() {
|
|
2208
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2209
|
-
if (process.env.NODE_ENV === 'test') {
|
|
2210
|
-
return fetchable.errored({ code: 'NOT_ALLOWED_IN_TEST_ENV' });
|
|
2211
|
-
}
|
|
2212
|
-
if (!process.env.PROMETHEUS_METRICS_SERVICE_URL) {
|
|
2213
|
-
return fetchable.errored({ code: 'MISSING_METRICS_URL' });
|
|
2214
|
-
}
|
|
2215
|
-
const metricsResult = yield fetchable.fromPromise(this.registry.getMetricsAsJSON());
|
|
2216
|
-
if (fetchable.isErrored(metricsResult)) {
|
|
2217
|
-
return fetchable.errored({
|
|
2218
|
-
code: 'FAILED_TO_GET_PROMETHEUS_METRICS',
|
|
2219
|
-
subError: metricsResult.error
|
|
2220
|
-
});
|
|
2221
|
-
}
|
|
2222
|
-
const requestResult = yield fetchable.fromPromise(axios.post(process.env.PROMETHEUS_METRICS_SERVICE_URL, {
|
|
2223
|
-
source: 'api',
|
|
2224
|
-
data: metricsResult.value,
|
|
2225
|
-
threadIndex: getThreadIndex()
|
|
2226
|
-
}));
|
|
2227
|
-
if (fetchable.isErrored(requestResult)) {
|
|
2228
|
-
return fetchable.errored({
|
|
2229
|
-
code: 'FAILED_TO_PUSH_PROMETHEUS_METRICS',
|
|
2230
|
-
subError: requestResult.error
|
|
2231
|
-
});
|
|
2232
|
-
}
|
|
2233
|
-
return fetchable.complete(true);
|
|
2234
|
-
});
|
|
2235
|
-
}
|
|
2236
|
-
trackHttpRequest() {
|
|
2237
|
-
return this.httpHistogram.startTimer();
|
|
2238
|
-
}
|
|
2239
|
-
trackRuneMetricsRequest() {
|
|
2240
|
-
return this.runeMetricsHistogram.startTimer();
|
|
2241
|
-
}
|
|
2242
|
-
trackHiscoresRequest() {
|
|
2243
|
-
return this.hiscoresHistogram.startTimer();
|
|
2244
|
-
}
|
|
2245
|
-
trackEffect(effectName, fn) {
|
|
2246
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2247
|
-
const endTimer = this.effectHistogram.startTimer();
|
|
2248
|
-
try {
|
|
2249
|
-
yield fn();
|
|
2250
|
-
endTimer({ effectName, status: 1 });
|
|
2251
|
-
}
|
|
2252
|
-
catch (error) {
|
|
2253
|
-
endTimer({ effectName, status: 0 });
|
|
2254
|
-
throw error;
|
|
2255
|
-
}
|
|
2256
|
-
});
|
|
2257
|
-
}
|
|
2258
|
-
trackJob(jobName, handler) {
|
|
2259
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2260
|
-
const endTimer = this.jobHistogram.startTimer();
|
|
2261
|
-
try {
|
|
2262
|
-
yield handler();
|
|
2263
|
-
endTimer({ jobName, status: 1 });
|
|
2264
|
-
}
|
|
2265
|
-
catch (error) {
|
|
2266
|
-
endTimer({ jobName, status: 0 });
|
|
2267
|
-
throw error;
|
|
2268
|
-
}
|
|
2269
|
-
});
|
|
2270
|
-
}
|
|
2271
|
-
trackEventEmitted(eventType) {
|
|
2272
|
-
this.eventCounter.inc({ eventType });
|
|
2273
|
-
}
|
|
2274
|
-
trackCustomPeriodExpression(customPeriod) {
|
|
2275
|
-
this.customPeriodCounter.inc({ customPeriod });
|
|
2276
|
-
}
|
|
2277
|
-
trackUpdatePlayerJobSource(source) {
|
|
2278
|
-
this.updatePlayerJobSourceCounter.inc({ source });
|
|
2279
|
-
}
|
|
2280
|
-
updateQueueMetrics(queueName, counts) {
|
|
2281
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2282
|
-
for (const [state, count] of Object.entries(counts)) {
|
|
2283
|
-
this.jobQueueGauge.set({ queueName, state }, count);
|
|
2284
|
-
}
|
|
2285
|
-
});
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
var prometheusService = new PrometheusService();
|
|
2289
|
-
|
|
2290
2065
|
const CUSTOM_PERIOD_REGEX = /(\d+y)?(\d+m)?(\d+w)?(\d+d)?(\d+h)?/;
|
|
2291
2066
|
const PeriodProps = {
|
|
2292
2067
|
[Period.FIVE_MIN]: { name: '5 Min', milliseconds: 300000 },
|
|
@@ -2314,7 +2089,6 @@ function parsePeriodExpression(periodExpression) {
|
|
|
2314
2089
|
durationMs: PeriodProps[fixed].milliseconds
|
|
2315
2090
|
};
|
|
2316
2091
|
}
|
|
2317
|
-
prometheusService.trackCustomPeriodExpression(fixed);
|
|
2318
2092
|
const result = fixed.match(CUSTOM_PERIOD_REGEX);
|
|
2319
2093
|
if (!result || result.length === 0 || result[0] !== fixed)
|
|
2320
2094
|
return null;
|
package/dist/es/index.js
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import prometheus from 'prom-client';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
import 'dotenv/config';
|
|
5
|
-
import { errored, fromPromise, isErrored, complete } from '@attio/fetchable';
|
|
6
|
-
|
|
7
1
|
var config = {
|
|
8
2
|
defaultUserAgent: `WiseOldMan JS Client v${process.env.npm_package_version}`,
|
|
9
3
|
baseAPIUrl: 'https://api.wiseoldman.net/v2'
|
|
@@ -73,7 +67,7 @@ function handleError(status, path, data) {
|
|
|
73
67
|
throw new BadRequestError(path, data.message, data.data);
|
|
74
68
|
}
|
|
75
69
|
if (status === 403) {
|
|
76
|
-
throw new ForbiddenError(path, data.message);
|
|
70
|
+
throw new ForbiddenError(path, data.message, data.data);
|
|
77
71
|
}
|
|
78
72
|
if (status === 404) {
|
|
79
73
|
throw new NotFoundError(path, data.message);
|
|
@@ -95,11 +89,12 @@ class BadRequestError extends Error {
|
|
|
95
89
|
}
|
|
96
90
|
}
|
|
97
91
|
class ForbiddenError extends Error {
|
|
98
|
-
constructor(resource, message) {
|
|
92
|
+
constructor(resource, message, data) {
|
|
99
93
|
super(message);
|
|
100
94
|
this.name = 'ForbiddenError';
|
|
101
95
|
this.resource = resource;
|
|
102
96
|
this.statusCode = 403;
|
|
97
|
+
this.data = data;
|
|
103
98
|
}
|
|
104
99
|
}
|
|
105
100
|
class NotFoundError extends Error {
|
|
@@ -2065,226 +2060,6 @@ function getParentEfficiencyMetric(metric) {
|
|
|
2065
2060
|
return null;
|
|
2066
2061
|
}
|
|
2067
2062
|
|
|
2068
|
-
/**
|
|
2069
|
-
* This file has been created as a way to force any usage
|
|
2070
|
-
* of process.env to go through a dotenv.config first.
|
|
2071
|
-
*/
|
|
2072
|
-
/**
|
|
2073
|
-
* This ensures that an env var is required in prod but optional in dev/test.
|
|
2074
|
-
*/
|
|
2075
|
-
function prodOnly(varSchema) {
|
|
2076
|
-
if (process.env.NODE_ENV === 'production') {
|
|
2077
|
-
return varSchema;
|
|
2078
|
-
}
|
|
2079
|
-
return z.optional(varSchema);
|
|
2080
|
-
}
|
|
2081
|
-
const envVariablesSchema = z.object({
|
|
2082
|
-
// Prisma Database URL
|
|
2083
|
-
CORE_DATABASE_URL: z.string().trim().min(1),
|
|
2084
|
-
// Redis Configs
|
|
2085
|
-
REDIS_HOST: z.string().trim().min(1),
|
|
2086
|
-
REDIS_PORT: z.coerce.number().positive().int(),
|
|
2087
|
-
// Node Environment
|
|
2088
|
-
NODE_ENV: z.enum(['development', 'production', 'test']),
|
|
2089
|
-
// Port for the API to run on
|
|
2090
|
-
API_PORT: z.optional(z.coerce.number().positive().int()),
|
|
2091
|
-
// Admin Password (For mod+ operations)
|
|
2092
|
-
ADMIN_PASSWORD: prodOnly(z.string().trim().min(1)),
|
|
2093
|
-
// Sentry (for error tracking)
|
|
2094
|
-
API_SENTRY_DSN: prodOnly(z.string().trim().min(1)),
|
|
2095
|
-
// Patreon Token (to access their API)
|
|
2096
|
-
PATREON_BEARER_TOKEN: prodOnly(z.string().trim().min(1)),
|
|
2097
|
-
// Discord Bot API URL (to send events to)
|
|
2098
|
-
DISCORD_BOT_API_URL: prodOnly(z.string().trim().min(1).url()),
|
|
2099
|
-
// Our Prometheus metrics aggregator service URL
|
|
2100
|
-
PROMETHEUS_METRICS_SERVICE_URL: prodOnly(z.string().trim().min(1).url()),
|
|
2101
|
-
// Discord Monitoring Webhooks
|
|
2102
|
-
DISCORD_PATREON_WEBHOOK_URL: prodOnly(z.string().trim().min(1).url()),
|
|
2103
|
-
DISCORD_MONITORING_WEBHOOK_URL: prodOnly(z.string().trim().min(1).url()),
|
|
2104
|
-
// Proxy Configs
|
|
2105
|
-
PROXY_LIST: prodOnly(z.string().trim().min(1)),
|
|
2106
|
-
PROXY_USER: prodOnly(z.string().trim().min(1)),
|
|
2107
|
-
PROXY_PASSWORD: prodOnly(z.string().trim().min(1)),
|
|
2108
|
-
PROXY_PORT: prodOnly(z.coerce.number().positive().int()),
|
|
2109
|
-
CPU_COUNT: prodOnly(z.coerce.number().positive().int()),
|
|
2110
|
-
// Openai API Key
|
|
2111
|
-
OPENAI_API_KEY: prodOnly(z.string().trim().min(1).startsWith('sk-'))
|
|
2112
|
-
});
|
|
2113
|
-
// This will load env vars from a .env file, type check them,and throw an error
|
|
2114
|
-
// (interrupting the process) if they're required and missing, or of an invalid type.
|
|
2115
|
-
try {
|
|
2116
|
-
envVariablesSchema.parse(process.env);
|
|
2117
|
-
}
|
|
2118
|
-
catch (error) {
|
|
2119
|
-
const errorPayload = JSON.stringify(error, null, 2);
|
|
2120
|
-
throw new Error(`Invalid environment variables. Please check env.ts for more info.\n${errorPayload}`);
|
|
2121
|
-
}
|
|
2122
|
-
function getThreadIndex() {
|
|
2123
|
-
if (process.env.pm_id === undefined) {
|
|
2124
|
-
return null;
|
|
2125
|
-
}
|
|
2126
|
-
return parseInt(process.env.pm_id, 10);
|
|
2127
|
-
}
|
|
2128
|
-
|
|
2129
|
-
class PrometheusService {
|
|
2130
|
-
constructor() {
|
|
2131
|
-
this.pushInterval = null;
|
|
2132
|
-
this.registry = new prometheus.Registry();
|
|
2133
|
-
this.registry.setDefaultLabels({ app: 'wise-old-man', threadIndex: getThreadIndex() });
|
|
2134
|
-
prometheus.collectDefaultMetrics({ register: this.registry });
|
|
2135
|
-
this.effectHistogram = new prometheus.Histogram({
|
|
2136
|
-
name: 'effect_duration_seconds',
|
|
2137
|
-
help: 'Duration of effects in microseconds',
|
|
2138
|
-
labelNames: ['effectName', 'status'],
|
|
2139
|
-
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10, 30]
|
|
2140
|
-
});
|
|
2141
|
-
this.httpHistogram = new prometheus.Histogram({
|
|
2142
|
-
name: 'http_request_duration_seconds',
|
|
2143
|
-
help: 'Duration of HTTP requests in microseconds',
|
|
2144
|
-
labelNames: ['method', 'route', 'status', 'userAgent'],
|
|
2145
|
-
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10, 30]
|
|
2146
|
-
});
|
|
2147
|
-
this.jobHistogram = new prometheus.Histogram({
|
|
2148
|
-
name: 'job_duration_seconds',
|
|
2149
|
-
help: 'Duration of jobs in microseconds',
|
|
2150
|
-
labelNames: ['jobName', 'status'],
|
|
2151
|
-
buckets: [0.1, 0.5, 1, 5, 10, 30, 60]
|
|
2152
|
-
});
|
|
2153
|
-
this.jobQueueGauge = new prometheus.Gauge({
|
|
2154
|
-
name: 'job_queue_size',
|
|
2155
|
-
help: 'Number of jobs in different states for each queue',
|
|
2156
|
-
labelNames: ['queueName', 'state']
|
|
2157
|
-
});
|
|
2158
|
-
this.eventCounter = new prometheus.Counter({
|
|
2159
|
-
name: 'event_counter',
|
|
2160
|
-
help: 'Count of events emitted',
|
|
2161
|
-
labelNames: ['eventType']
|
|
2162
|
-
});
|
|
2163
|
-
this.customPeriodCounter = new prometheus.Counter({
|
|
2164
|
-
name: 'custom_period_counter',
|
|
2165
|
-
help: 'Count of custom period expressions used',
|
|
2166
|
-
labelNames: ['customPeriod']
|
|
2167
|
-
});
|
|
2168
|
-
this.updatePlayerJobSourceCounter = new prometheus.Counter({
|
|
2169
|
-
name: 'update_player_job_source_counter',
|
|
2170
|
-
help: 'Count of update player jobs dispatched',
|
|
2171
|
-
labelNames: ['source']
|
|
2172
|
-
});
|
|
2173
|
-
this.runeMetricsHistogram = new prometheus.Histogram({
|
|
2174
|
-
name: 'runemetrics_duration_seconds',
|
|
2175
|
-
help: 'Duration of RuneMetrics requests in microseconds',
|
|
2176
|
-
labelNames: ['status'],
|
|
2177
|
-
buckets: [0.1, 0.3, 0.5, 1, 5, 10, 30]
|
|
2178
|
-
});
|
|
2179
|
-
this.hiscoresHistogram = new prometheus.Histogram({
|
|
2180
|
-
name: 'hiscores_duration_seconds',
|
|
2181
|
-
help: 'Duration of hiscores requests in microseconds',
|
|
2182
|
-
labelNames: ['status'],
|
|
2183
|
-
buckets: [0.1, 0.3, 0.5, 1, 5, 10, 30]
|
|
2184
|
-
});
|
|
2185
|
-
this.registry.registerMetric(this.jobHistogram);
|
|
2186
|
-
this.registry.registerMetric(this.jobQueueGauge);
|
|
2187
|
-
this.registry.registerMetric(this.httpHistogram);
|
|
2188
|
-
this.registry.registerMetric(this.effectHistogram);
|
|
2189
|
-
this.registry.registerMetric(this.eventCounter);
|
|
2190
|
-
this.registry.registerMetric(this.customPeriodCounter);
|
|
2191
|
-
this.registry.registerMetric(this.updatePlayerJobSourceCounter);
|
|
2192
|
-
this.registry.registerMetric(this.runeMetricsHistogram);
|
|
2193
|
-
this.registry.registerMetric(this.hiscoresHistogram);
|
|
2194
|
-
}
|
|
2195
|
-
init() {
|
|
2196
|
-
this.pushInterval = setInterval(() => {
|
|
2197
|
-
this.pushMetrics();
|
|
2198
|
-
}, 60000);
|
|
2199
|
-
}
|
|
2200
|
-
shutdown() {
|
|
2201
|
-
if (this.pushInterval !== null) {
|
|
2202
|
-
clearInterval(this.pushInterval);
|
|
2203
|
-
}
|
|
2204
|
-
}
|
|
2205
|
-
pushMetrics() {
|
|
2206
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2207
|
-
if (process.env.NODE_ENV === 'test') {
|
|
2208
|
-
return errored({ code: 'NOT_ALLOWED_IN_TEST_ENV' });
|
|
2209
|
-
}
|
|
2210
|
-
if (!process.env.PROMETHEUS_METRICS_SERVICE_URL) {
|
|
2211
|
-
return errored({ code: 'MISSING_METRICS_URL' });
|
|
2212
|
-
}
|
|
2213
|
-
const metricsResult = yield fromPromise(this.registry.getMetricsAsJSON());
|
|
2214
|
-
if (isErrored(metricsResult)) {
|
|
2215
|
-
return errored({
|
|
2216
|
-
code: 'FAILED_TO_GET_PROMETHEUS_METRICS',
|
|
2217
|
-
subError: metricsResult.error
|
|
2218
|
-
});
|
|
2219
|
-
}
|
|
2220
|
-
const requestResult = yield fromPromise(axios.post(process.env.PROMETHEUS_METRICS_SERVICE_URL, {
|
|
2221
|
-
source: 'api',
|
|
2222
|
-
data: metricsResult.value,
|
|
2223
|
-
threadIndex: getThreadIndex()
|
|
2224
|
-
}));
|
|
2225
|
-
if (isErrored(requestResult)) {
|
|
2226
|
-
return errored({
|
|
2227
|
-
code: 'FAILED_TO_PUSH_PROMETHEUS_METRICS',
|
|
2228
|
-
subError: requestResult.error
|
|
2229
|
-
});
|
|
2230
|
-
}
|
|
2231
|
-
return complete(true);
|
|
2232
|
-
});
|
|
2233
|
-
}
|
|
2234
|
-
trackHttpRequest() {
|
|
2235
|
-
return this.httpHistogram.startTimer();
|
|
2236
|
-
}
|
|
2237
|
-
trackRuneMetricsRequest() {
|
|
2238
|
-
return this.runeMetricsHistogram.startTimer();
|
|
2239
|
-
}
|
|
2240
|
-
trackHiscoresRequest() {
|
|
2241
|
-
return this.hiscoresHistogram.startTimer();
|
|
2242
|
-
}
|
|
2243
|
-
trackEffect(effectName, fn) {
|
|
2244
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2245
|
-
const endTimer = this.effectHistogram.startTimer();
|
|
2246
|
-
try {
|
|
2247
|
-
yield fn();
|
|
2248
|
-
endTimer({ effectName, status: 1 });
|
|
2249
|
-
}
|
|
2250
|
-
catch (error) {
|
|
2251
|
-
endTimer({ effectName, status: 0 });
|
|
2252
|
-
throw error;
|
|
2253
|
-
}
|
|
2254
|
-
});
|
|
2255
|
-
}
|
|
2256
|
-
trackJob(jobName, handler) {
|
|
2257
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2258
|
-
const endTimer = this.jobHistogram.startTimer();
|
|
2259
|
-
try {
|
|
2260
|
-
yield handler();
|
|
2261
|
-
endTimer({ jobName, status: 1 });
|
|
2262
|
-
}
|
|
2263
|
-
catch (error) {
|
|
2264
|
-
endTimer({ jobName, status: 0 });
|
|
2265
|
-
throw error;
|
|
2266
|
-
}
|
|
2267
|
-
});
|
|
2268
|
-
}
|
|
2269
|
-
trackEventEmitted(eventType) {
|
|
2270
|
-
this.eventCounter.inc({ eventType });
|
|
2271
|
-
}
|
|
2272
|
-
trackCustomPeriodExpression(customPeriod) {
|
|
2273
|
-
this.customPeriodCounter.inc({ customPeriod });
|
|
2274
|
-
}
|
|
2275
|
-
trackUpdatePlayerJobSource(source) {
|
|
2276
|
-
this.updatePlayerJobSourceCounter.inc({ source });
|
|
2277
|
-
}
|
|
2278
|
-
updateQueueMetrics(queueName, counts) {
|
|
2279
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2280
|
-
for (const [state, count] of Object.entries(counts)) {
|
|
2281
|
-
this.jobQueueGauge.set({ queueName, state }, count);
|
|
2282
|
-
}
|
|
2283
|
-
});
|
|
2284
|
-
}
|
|
2285
|
-
}
|
|
2286
|
-
var prometheusService = new PrometheusService();
|
|
2287
|
-
|
|
2288
2063
|
const CUSTOM_PERIOD_REGEX = /(\d+y)?(\d+m)?(\d+w)?(\d+d)?(\d+h)?/;
|
|
2289
2064
|
const PeriodProps = {
|
|
2290
2065
|
[Period.FIVE_MIN]: { name: '5 Min', milliseconds: 300000 },
|
|
@@ -2312,7 +2087,6 @@ function parsePeriodExpression(periodExpression) {
|
|
|
2312
2087
|
durationMs: PeriodProps[fixed].milliseconds
|
|
2313
2088
|
};
|
|
2314
2089
|
}
|
|
2315
|
-
prometheusService.trackCustomPeriodExpression(fixed);
|
|
2316
2090
|
const result = fixed.match(CUSTOM_PERIOD_REGEX);
|
|
2317
2091
|
if (!result || result.length === 0 || result[0] !== fixed)
|
|
2318
2092
|
return null;
|
package/dist/es/index.mjs
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import prometheus from 'prom-client';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
import 'dotenv/config';
|
|
5
|
-
import { errored, fromPromise, isErrored, complete } from '@attio/fetchable';
|
|
6
|
-
|
|
7
1
|
var config = {
|
|
8
2
|
defaultUserAgent: `WiseOldMan JS Client v${process.env.npm_package_version}`,
|
|
9
3
|
baseAPIUrl: 'https://api.wiseoldman.net/v2'
|
|
@@ -73,7 +67,7 @@ function handleError(status, path, data) {
|
|
|
73
67
|
throw new BadRequestError(path, data.message, data.data);
|
|
74
68
|
}
|
|
75
69
|
if (status === 403) {
|
|
76
|
-
throw new ForbiddenError(path, data.message);
|
|
70
|
+
throw new ForbiddenError(path, data.message, data.data);
|
|
77
71
|
}
|
|
78
72
|
if (status === 404) {
|
|
79
73
|
throw new NotFoundError(path, data.message);
|
|
@@ -95,11 +89,12 @@ class BadRequestError extends Error {
|
|
|
95
89
|
}
|
|
96
90
|
}
|
|
97
91
|
class ForbiddenError extends Error {
|
|
98
|
-
constructor(resource, message) {
|
|
92
|
+
constructor(resource, message, data) {
|
|
99
93
|
super(message);
|
|
100
94
|
this.name = 'ForbiddenError';
|
|
101
95
|
this.resource = resource;
|
|
102
96
|
this.statusCode = 403;
|
|
97
|
+
this.data = data;
|
|
103
98
|
}
|
|
104
99
|
}
|
|
105
100
|
class NotFoundError extends Error {
|
|
@@ -2065,226 +2060,6 @@ function getParentEfficiencyMetric(metric) {
|
|
|
2065
2060
|
return null;
|
|
2066
2061
|
}
|
|
2067
2062
|
|
|
2068
|
-
/**
|
|
2069
|
-
* This file has been created as a way to force any usage
|
|
2070
|
-
* of process.env to go through a dotenv.config first.
|
|
2071
|
-
*/
|
|
2072
|
-
/**
|
|
2073
|
-
* This ensures that an env var is required in prod but optional in dev/test.
|
|
2074
|
-
*/
|
|
2075
|
-
function prodOnly(varSchema) {
|
|
2076
|
-
if (process.env.NODE_ENV === 'production') {
|
|
2077
|
-
return varSchema;
|
|
2078
|
-
}
|
|
2079
|
-
return z.optional(varSchema);
|
|
2080
|
-
}
|
|
2081
|
-
const envVariablesSchema = z.object({
|
|
2082
|
-
// Prisma Database URL
|
|
2083
|
-
CORE_DATABASE_URL: z.string().trim().min(1),
|
|
2084
|
-
// Redis Configs
|
|
2085
|
-
REDIS_HOST: z.string().trim().min(1),
|
|
2086
|
-
REDIS_PORT: z.coerce.number().positive().int(),
|
|
2087
|
-
// Node Environment
|
|
2088
|
-
NODE_ENV: z.enum(['development', 'production', 'test']),
|
|
2089
|
-
// Port for the API to run on
|
|
2090
|
-
API_PORT: z.optional(z.coerce.number().positive().int()),
|
|
2091
|
-
// Admin Password (For mod+ operations)
|
|
2092
|
-
ADMIN_PASSWORD: prodOnly(z.string().trim().min(1)),
|
|
2093
|
-
// Sentry (for error tracking)
|
|
2094
|
-
API_SENTRY_DSN: prodOnly(z.string().trim().min(1)),
|
|
2095
|
-
// Patreon Token (to access their API)
|
|
2096
|
-
PATREON_BEARER_TOKEN: prodOnly(z.string().trim().min(1)),
|
|
2097
|
-
// Discord Bot API URL (to send events to)
|
|
2098
|
-
DISCORD_BOT_API_URL: prodOnly(z.string().trim().min(1).url()),
|
|
2099
|
-
// Our Prometheus metrics aggregator service URL
|
|
2100
|
-
PROMETHEUS_METRICS_SERVICE_URL: prodOnly(z.string().trim().min(1).url()),
|
|
2101
|
-
// Discord Monitoring Webhooks
|
|
2102
|
-
DISCORD_PATREON_WEBHOOK_URL: prodOnly(z.string().trim().min(1).url()),
|
|
2103
|
-
DISCORD_MONITORING_WEBHOOK_URL: prodOnly(z.string().trim().min(1).url()),
|
|
2104
|
-
// Proxy Configs
|
|
2105
|
-
PROXY_LIST: prodOnly(z.string().trim().min(1)),
|
|
2106
|
-
PROXY_USER: prodOnly(z.string().trim().min(1)),
|
|
2107
|
-
PROXY_PASSWORD: prodOnly(z.string().trim().min(1)),
|
|
2108
|
-
PROXY_PORT: prodOnly(z.coerce.number().positive().int()),
|
|
2109
|
-
CPU_COUNT: prodOnly(z.coerce.number().positive().int()),
|
|
2110
|
-
// Openai API Key
|
|
2111
|
-
OPENAI_API_KEY: prodOnly(z.string().trim().min(1).startsWith('sk-'))
|
|
2112
|
-
});
|
|
2113
|
-
// This will load env vars from a .env file, type check them,and throw an error
|
|
2114
|
-
// (interrupting the process) if they're required and missing, or of an invalid type.
|
|
2115
|
-
try {
|
|
2116
|
-
envVariablesSchema.parse(process.env);
|
|
2117
|
-
}
|
|
2118
|
-
catch (error) {
|
|
2119
|
-
const errorPayload = JSON.stringify(error, null, 2);
|
|
2120
|
-
throw new Error(`Invalid environment variables. Please check env.ts for more info.\n${errorPayload}`);
|
|
2121
|
-
}
|
|
2122
|
-
function getThreadIndex() {
|
|
2123
|
-
if (process.env.pm_id === undefined) {
|
|
2124
|
-
return null;
|
|
2125
|
-
}
|
|
2126
|
-
return parseInt(process.env.pm_id, 10);
|
|
2127
|
-
}
|
|
2128
|
-
|
|
2129
|
-
class PrometheusService {
|
|
2130
|
-
constructor() {
|
|
2131
|
-
this.pushInterval = null;
|
|
2132
|
-
this.registry = new prometheus.Registry();
|
|
2133
|
-
this.registry.setDefaultLabels({ app: 'wise-old-man', threadIndex: getThreadIndex() });
|
|
2134
|
-
prometheus.collectDefaultMetrics({ register: this.registry });
|
|
2135
|
-
this.effectHistogram = new prometheus.Histogram({
|
|
2136
|
-
name: 'effect_duration_seconds',
|
|
2137
|
-
help: 'Duration of effects in microseconds',
|
|
2138
|
-
labelNames: ['effectName', 'status'],
|
|
2139
|
-
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10, 30]
|
|
2140
|
-
});
|
|
2141
|
-
this.httpHistogram = new prometheus.Histogram({
|
|
2142
|
-
name: 'http_request_duration_seconds',
|
|
2143
|
-
help: 'Duration of HTTP requests in microseconds',
|
|
2144
|
-
labelNames: ['method', 'route', 'status', 'userAgent'],
|
|
2145
|
-
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10, 30]
|
|
2146
|
-
});
|
|
2147
|
-
this.jobHistogram = new prometheus.Histogram({
|
|
2148
|
-
name: 'job_duration_seconds',
|
|
2149
|
-
help: 'Duration of jobs in microseconds',
|
|
2150
|
-
labelNames: ['jobName', 'status'],
|
|
2151
|
-
buckets: [0.1, 0.5, 1, 5, 10, 30, 60]
|
|
2152
|
-
});
|
|
2153
|
-
this.jobQueueGauge = new prometheus.Gauge({
|
|
2154
|
-
name: 'job_queue_size',
|
|
2155
|
-
help: 'Number of jobs in different states for each queue',
|
|
2156
|
-
labelNames: ['queueName', 'state']
|
|
2157
|
-
});
|
|
2158
|
-
this.eventCounter = new prometheus.Counter({
|
|
2159
|
-
name: 'event_counter',
|
|
2160
|
-
help: 'Count of events emitted',
|
|
2161
|
-
labelNames: ['eventType']
|
|
2162
|
-
});
|
|
2163
|
-
this.customPeriodCounter = new prometheus.Counter({
|
|
2164
|
-
name: 'custom_period_counter',
|
|
2165
|
-
help: 'Count of custom period expressions used',
|
|
2166
|
-
labelNames: ['customPeriod']
|
|
2167
|
-
});
|
|
2168
|
-
this.updatePlayerJobSourceCounter = new prometheus.Counter({
|
|
2169
|
-
name: 'update_player_job_source_counter',
|
|
2170
|
-
help: 'Count of update player jobs dispatched',
|
|
2171
|
-
labelNames: ['source']
|
|
2172
|
-
});
|
|
2173
|
-
this.runeMetricsHistogram = new prometheus.Histogram({
|
|
2174
|
-
name: 'runemetrics_duration_seconds',
|
|
2175
|
-
help: 'Duration of RuneMetrics requests in microseconds',
|
|
2176
|
-
labelNames: ['status'],
|
|
2177
|
-
buckets: [0.1, 0.3, 0.5, 1, 5, 10, 30]
|
|
2178
|
-
});
|
|
2179
|
-
this.hiscoresHistogram = new prometheus.Histogram({
|
|
2180
|
-
name: 'hiscores_duration_seconds',
|
|
2181
|
-
help: 'Duration of hiscores requests in microseconds',
|
|
2182
|
-
labelNames: ['status'],
|
|
2183
|
-
buckets: [0.1, 0.3, 0.5, 1, 5, 10, 30]
|
|
2184
|
-
});
|
|
2185
|
-
this.registry.registerMetric(this.jobHistogram);
|
|
2186
|
-
this.registry.registerMetric(this.jobQueueGauge);
|
|
2187
|
-
this.registry.registerMetric(this.httpHistogram);
|
|
2188
|
-
this.registry.registerMetric(this.effectHistogram);
|
|
2189
|
-
this.registry.registerMetric(this.eventCounter);
|
|
2190
|
-
this.registry.registerMetric(this.customPeriodCounter);
|
|
2191
|
-
this.registry.registerMetric(this.updatePlayerJobSourceCounter);
|
|
2192
|
-
this.registry.registerMetric(this.runeMetricsHistogram);
|
|
2193
|
-
this.registry.registerMetric(this.hiscoresHistogram);
|
|
2194
|
-
}
|
|
2195
|
-
init() {
|
|
2196
|
-
this.pushInterval = setInterval(() => {
|
|
2197
|
-
this.pushMetrics();
|
|
2198
|
-
}, 60000);
|
|
2199
|
-
}
|
|
2200
|
-
shutdown() {
|
|
2201
|
-
if (this.pushInterval !== null) {
|
|
2202
|
-
clearInterval(this.pushInterval);
|
|
2203
|
-
}
|
|
2204
|
-
}
|
|
2205
|
-
pushMetrics() {
|
|
2206
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2207
|
-
if (process.env.NODE_ENV === 'test') {
|
|
2208
|
-
return errored({ code: 'NOT_ALLOWED_IN_TEST_ENV' });
|
|
2209
|
-
}
|
|
2210
|
-
if (!process.env.PROMETHEUS_METRICS_SERVICE_URL) {
|
|
2211
|
-
return errored({ code: 'MISSING_METRICS_URL' });
|
|
2212
|
-
}
|
|
2213
|
-
const metricsResult = yield fromPromise(this.registry.getMetricsAsJSON());
|
|
2214
|
-
if (isErrored(metricsResult)) {
|
|
2215
|
-
return errored({
|
|
2216
|
-
code: 'FAILED_TO_GET_PROMETHEUS_METRICS',
|
|
2217
|
-
subError: metricsResult.error
|
|
2218
|
-
});
|
|
2219
|
-
}
|
|
2220
|
-
const requestResult = yield fromPromise(axios.post(process.env.PROMETHEUS_METRICS_SERVICE_URL, {
|
|
2221
|
-
source: 'api',
|
|
2222
|
-
data: metricsResult.value,
|
|
2223
|
-
threadIndex: getThreadIndex()
|
|
2224
|
-
}));
|
|
2225
|
-
if (isErrored(requestResult)) {
|
|
2226
|
-
return errored({
|
|
2227
|
-
code: 'FAILED_TO_PUSH_PROMETHEUS_METRICS',
|
|
2228
|
-
subError: requestResult.error
|
|
2229
|
-
});
|
|
2230
|
-
}
|
|
2231
|
-
return complete(true);
|
|
2232
|
-
});
|
|
2233
|
-
}
|
|
2234
|
-
trackHttpRequest() {
|
|
2235
|
-
return this.httpHistogram.startTimer();
|
|
2236
|
-
}
|
|
2237
|
-
trackRuneMetricsRequest() {
|
|
2238
|
-
return this.runeMetricsHistogram.startTimer();
|
|
2239
|
-
}
|
|
2240
|
-
trackHiscoresRequest() {
|
|
2241
|
-
return this.hiscoresHistogram.startTimer();
|
|
2242
|
-
}
|
|
2243
|
-
trackEffect(effectName, fn) {
|
|
2244
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2245
|
-
const endTimer = this.effectHistogram.startTimer();
|
|
2246
|
-
try {
|
|
2247
|
-
yield fn();
|
|
2248
|
-
endTimer({ effectName, status: 1 });
|
|
2249
|
-
}
|
|
2250
|
-
catch (error) {
|
|
2251
|
-
endTimer({ effectName, status: 0 });
|
|
2252
|
-
throw error;
|
|
2253
|
-
}
|
|
2254
|
-
});
|
|
2255
|
-
}
|
|
2256
|
-
trackJob(jobName, handler) {
|
|
2257
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2258
|
-
const endTimer = this.jobHistogram.startTimer();
|
|
2259
|
-
try {
|
|
2260
|
-
yield handler();
|
|
2261
|
-
endTimer({ jobName, status: 1 });
|
|
2262
|
-
}
|
|
2263
|
-
catch (error) {
|
|
2264
|
-
endTimer({ jobName, status: 0 });
|
|
2265
|
-
throw error;
|
|
2266
|
-
}
|
|
2267
|
-
});
|
|
2268
|
-
}
|
|
2269
|
-
trackEventEmitted(eventType) {
|
|
2270
|
-
this.eventCounter.inc({ eventType });
|
|
2271
|
-
}
|
|
2272
|
-
trackCustomPeriodExpression(customPeriod) {
|
|
2273
|
-
this.customPeriodCounter.inc({ customPeriod });
|
|
2274
|
-
}
|
|
2275
|
-
trackUpdatePlayerJobSource(source) {
|
|
2276
|
-
this.updatePlayerJobSourceCounter.inc({ source });
|
|
2277
|
-
}
|
|
2278
|
-
updateQueueMetrics(queueName, counts) {
|
|
2279
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2280
|
-
for (const [state, count] of Object.entries(counts)) {
|
|
2281
|
-
this.jobQueueGauge.set({ queueName, state }, count);
|
|
2282
|
-
}
|
|
2283
|
-
});
|
|
2284
|
-
}
|
|
2285
|
-
}
|
|
2286
|
-
var prometheusService = new PrometheusService();
|
|
2287
|
-
|
|
2288
2063
|
const CUSTOM_PERIOD_REGEX = /(\d+y)?(\d+m)?(\d+w)?(\d+d)?(\d+h)?/;
|
|
2289
2064
|
const PeriodProps = {
|
|
2290
2065
|
[Period.FIVE_MIN]: { name: '5 Min', milliseconds: 300000 },
|
|
@@ -2312,7 +2087,6 @@ function parsePeriodExpression(periodExpression) {
|
|
|
2312
2087
|
durationMs: PeriodProps[fixed].milliseconds
|
|
2313
2088
|
};
|
|
2314
2089
|
}
|
|
2315
|
-
prometheusService.trackCustomPeriodExpression(fixed);
|
|
2316
2090
|
const result = fixed.match(CUSTOM_PERIOD_REGEX);
|
|
2317
2091
|
if (!result || result.length === 0 || result[0] !== fixed)
|
|
2318
2092
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wise-old-man/utils",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.14",
|
|
4
4
|
"description": "A JavaScript/TypeScript client that interfaces and consumes the Wise Old Man API, an API that tracks and measures players' progress in Old School Runescape.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wiseoldman",
|