apitally 0.11.4 → 0.12.0
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/README.md +27 -14
- package/dist/common/client.cjs +130 -110
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.d.cts +2 -0
- package/dist/common/client.d.ts +2 -0
- package/dist/common/client.js +125 -105
- package/dist/common/client.js.map +1 -1
- package/dist/common/consumerRegistry.cjs.map +1 -1
- package/dist/common/consumerRegistry.js.map +1 -1
- package/dist/common/logging.cjs.map +1 -1
- package/dist/common/logging.js.map +1 -1
- package/dist/common/packageVersions.cjs.map +1 -1
- package/dist/common/packageVersions.js.map +1 -1
- package/dist/common/paramValidation.cjs.map +1 -1
- package/dist/common/paramValidation.js.map +1 -1
- package/dist/common/requestCounter.cjs.map +1 -1
- package/dist/common/requestCounter.js.map +1 -1
- package/dist/common/requestLogger.cjs +63 -7
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.d.cts +3 -1
- package/dist/common/requestLogger.d.ts +3 -1
- package/dist/common/requestLogger.js +63 -7
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/sentry.cjs +55 -0
- package/dist/common/sentry.cjs.map +1 -0
- package/dist/common/sentry.d.cts +6 -0
- package/dist/common/sentry.d.ts +6 -0
- package/dist/common/sentry.js +22 -0
- package/dist/common/sentry.js.map +1 -0
- package/dist/common/serverErrorCounter.cjs +58 -45
- package/dist/common/serverErrorCounter.cjs.map +1 -1
- package/dist/common/serverErrorCounter.d.cts +3 -6
- package/dist/common/serverErrorCounter.d.ts +3 -6
- package/dist/common/serverErrorCounter.js +53 -45
- package/dist/common/serverErrorCounter.js.map +1 -1
- package/dist/common/tempGzipFile.cjs +2 -2
- package/dist/common/tempGzipFile.cjs.map +1 -1
- package/dist/common/tempGzipFile.js +2 -2
- package/dist/common/tempGzipFile.js.map +1 -1
- package/dist/common/types.cjs.map +1 -1
- package/dist/common/validationErrorCounter.cjs.map +1 -1
- package/dist/common/validationErrorCounter.js.map +1 -1
- package/dist/express/index.cjs +139 -112
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +134 -107
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +139 -112
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.js +134 -107
- package/dist/express/middleware.js.map +1 -1
- package/dist/express/utils.cjs.map +1 -1
- package/dist/express/utils.js.map +1 -1
- package/dist/fastify/index.cjs +136 -113
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.js +131 -108
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +136 -113
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.js +131 -108
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/hono/index.cjs +137 -112
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.js +132 -107
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +137 -112
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +132 -107
- package/dist/hono/middleware.js.map +1 -1
- package/dist/koa/index.cjs +137 -111
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.js +132 -106
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +137 -111
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.js +132 -106
- package/dist/koa/middleware.js.map +1 -1
- package/dist/nestjs/index.cjs +139 -112
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +134 -107
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<a href="https://apitally.io" target="_blank">
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://assets.apitally.io/logos/logo-vertical-dark.png">
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="https://assets.apitally.io/logos/logo-vertical-light.png">
|
|
6
|
+
<img alt="Apitally logo" src="https://assets.apitally.io/logos/logo-vertical-light.png" width="150">
|
|
7
|
+
</picture>
|
|
8
|
+
</a>
|
|
7
9
|
</p>
|
|
8
10
|
|
|
9
|
-
<p align="center"><b>
|
|
11
|
+
<p align="center"><b>Simple, privacy-focused API monitoring & analytics</b></p>
|
|
10
12
|
|
|
11
|
-
<p align="center"><i>Apitally helps you understand how your APIs are being used and alerts you when things go wrong.<br>
|
|
12
|
-
|
|
13
|
-
<p align="center">🔗 <b><a href="https://apitally.io" target="_blank">apitally.io</a></b></p>
|
|
13
|
+
<p align="center"><i>Apitally helps you understand how your APIs are being used and alerts you when things go wrong.<br>Just add two lines of code to your project to get started.</i></p>
|
|
14
|
+
<br>
|
|
14
15
|
|
|
15
16
|

|
|
16
17
|
|
|
17
18
|
---
|
|
18
19
|
|
|
19
|
-
# Apitally
|
|
20
|
+
# Apitally SDK for Node.js
|
|
20
21
|
|
|
21
22
|
[](https://github.com/apitally/apitally-js/actions)
|
|
22
23
|
[](https://codecov.io/gh/apitally/apitally-js)
|
|
23
24
|
[](https://www.npmjs.com/package/apitally)
|
|
24
25
|
|
|
25
|
-
This
|
|
26
|
+
This SDK for Apitally currently supports the following Node.js web
|
|
26
27
|
frameworks:
|
|
27
28
|
|
|
28
29
|
- [Express](https://docs.apitally.io/frameworks/express)
|
|
@@ -36,9 +37,21 @@ the 📚 [documentation](https://docs.apitally.io).
|
|
|
36
37
|
|
|
37
38
|
## Key features
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
### API analytics
|
|
41
|
+
|
|
42
|
+
Track traffic, error and performance metrics for your API, each endpoint and individual API consumers, allowing you to make informed, data-driven engineering and product decisions.
|
|
43
|
+
|
|
44
|
+
### Error tracking
|
|
45
|
+
|
|
46
|
+
Understand which validation rules in your endpoints cause client errors. Capture error details and stack traces for 500 error responses, and have them linked to Sentry issues automatically.
|
|
47
|
+
|
|
48
|
+
### Request logging
|
|
49
|
+
|
|
50
|
+
Drill down from insights to individual requests or use powerful filtering to understand how consumers have interacted with your API. Configure exactly what is included in the logs to meet your requirements.
|
|
51
|
+
|
|
52
|
+
### API monitoring & alerting
|
|
53
|
+
|
|
54
|
+
Get notified immediately if something isn't right using custom alerts, synthetic uptime checks and heartbeat monitoring. Notifications can be delivered via email, Slack or Microsoft Teams.
|
|
42
55
|
|
|
43
56
|
## Installation
|
|
44
57
|
|
package/dist/common/client.cjs
CHANGED
|
@@ -194,14 +194,116 @@ var RequestCounter = _RequestCounter;
|
|
|
194
194
|
// src/common/requestLogger.ts
|
|
195
195
|
var import_async_lock = __toESM(require("async-lock"), 1);
|
|
196
196
|
var import_buffer2 = require("buffer");
|
|
197
|
-
var
|
|
197
|
+
var import_crypto3 = require("crypto");
|
|
198
198
|
var import_fs2 = require("fs");
|
|
199
199
|
var import_os2 = require("os");
|
|
200
200
|
var import_path2 = require("path");
|
|
201
201
|
|
|
202
|
+
// src/common/sentry.ts
|
|
203
|
+
var sentry;
|
|
204
|
+
(async () => {
|
|
205
|
+
try {
|
|
206
|
+
sentry = await import("@sentry/node");
|
|
207
|
+
} catch (e) {
|
|
208
|
+
}
|
|
209
|
+
})();
|
|
210
|
+
function getSentryEventId() {
|
|
211
|
+
if (sentry && sentry.lastEventId) {
|
|
212
|
+
return sentry.lastEventId();
|
|
213
|
+
}
|
|
214
|
+
return void 0;
|
|
215
|
+
}
|
|
216
|
+
__name(getSentryEventId, "getSentryEventId");
|
|
217
|
+
|
|
218
|
+
// src/common/serverErrorCounter.ts
|
|
219
|
+
var import_crypto = require("crypto");
|
|
220
|
+
var MAX_MSG_LENGTH = 2048;
|
|
221
|
+
var MAX_STACKTRACE_LENGTH = 65536;
|
|
222
|
+
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
223
|
+
errorCounts;
|
|
224
|
+
errorDetails;
|
|
225
|
+
sentryEventIds;
|
|
226
|
+
constructor() {
|
|
227
|
+
this.errorCounts = /* @__PURE__ */ new Map();
|
|
228
|
+
this.errorDetails = /* @__PURE__ */ new Map();
|
|
229
|
+
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
230
|
+
}
|
|
231
|
+
addServerError(serverError) {
|
|
232
|
+
const key = this.getKey(serverError);
|
|
233
|
+
if (!this.errorDetails.has(key)) {
|
|
234
|
+
this.errorDetails.set(key, serverError);
|
|
235
|
+
}
|
|
236
|
+
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
237
|
+
const sentryEventId = getSentryEventId();
|
|
238
|
+
if (sentryEventId) {
|
|
239
|
+
this.sentryEventIds.set(key, sentryEventId);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
getAndResetServerErrors() {
|
|
243
|
+
const data = [];
|
|
244
|
+
this.errorCounts.forEach((count, key) => {
|
|
245
|
+
const serverError = this.errorDetails.get(key);
|
|
246
|
+
if (serverError) {
|
|
247
|
+
data.push({
|
|
248
|
+
consumer: serverError.consumer || null,
|
|
249
|
+
method: serverError.method,
|
|
250
|
+
path: serverError.path,
|
|
251
|
+
type: serverError.type,
|
|
252
|
+
msg: truncateExceptionMessage(serverError.msg),
|
|
253
|
+
traceback: truncateExceptionStackTrace(serverError.traceback),
|
|
254
|
+
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
255
|
+
error_count: count
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
this.errorCounts.clear();
|
|
260
|
+
this.errorDetails.clear();
|
|
261
|
+
return data;
|
|
262
|
+
}
|
|
263
|
+
getKey(serverError) {
|
|
264
|
+
const hashInput = [
|
|
265
|
+
serverError.consumer || "",
|
|
266
|
+
serverError.method.toUpperCase(),
|
|
267
|
+
serverError.path,
|
|
268
|
+
serverError.type,
|
|
269
|
+
serverError.msg.trim(),
|
|
270
|
+
serverError.traceback.trim()
|
|
271
|
+
].join("|");
|
|
272
|
+
return (0, import_crypto.createHash)("md5").update(hashInput).digest("hex");
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
276
|
+
var ServerErrorCounter = _ServerErrorCounter;
|
|
277
|
+
function truncateExceptionMessage(msg) {
|
|
278
|
+
if (msg.length <= MAX_MSG_LENGTH) {
|
|
279
|
+
return msg;
|
|
280
|
+
}
|
|
281
|
+
const suffix = "... (truncated)";
|
|
282
|
+
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
283
|
+
return msg.substring(0, cutoff) + suffix;
|
|
284
|
+
}
|
|
285
|
+
__name(truncateExceptionMessage, "truncateExceptionMessage");
|
|
286
|
+
function truncateExceptionStackTrace(stack) {
|
|
287
|
+
const suffix = "... (truncated) ...";
|
|
288
|
+
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
289
|
+
const lines = stack.trim().split("\n");
|
|
290
|
+
const truncatedLines = [];
|
|
291
|
+
let length = 0;
|
|
292
|
+
for (const line of lines) {
|
|
293
|
+
if (length + line.length + 1 > cutoff) {
|
|
294
|
+
truncatedLines.push(suffix);
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
truncatedLines.push(line);
|
|
298
|
+
length += line.length + 1;
|
|
299
|
+
}
|
|
300
|
+
return truncatedLines.join("\n");
|
|
301
|
+
}
|
|
302
|
+
__name(truncateExceptionStackTrace, "truncateExceptionStackTrace");
|
|
303
|
+
|
|
202
304
|
// src/common/tempGzipFile.ts
|
|
203
305
|
var import_buffer = require("buffer");
|
|
204
|
-
var
|
|
306
|
+
var import_crypto2 = require("crypto");
|
|
205
307
|
var import_fs = require("fs");
|
|
206
308
|
var import_os = require("os");
|
|
207
309
|
var import_path = require("path");
|
|
@@ -214,16 +316,16 @@ var _TempGzipFile = class _TempGzipFile {
|
|
|
214
316
|
readyPromise;
|
|
215
317
|
closedPromise;
|
|
216
318
|
constructor() {
|
|
217
|
-
this.uuid = (0,
|
|
319
|
+
this.uuid = (0, import_crypto2.randomUUID)();
|
|
218
320
|
this.filePath = (0, import_path.join)((0, import_os.tmpdir)(), `apitally-${this.uuid}.gz`);
|
|
219
321
|
this.writeStream = (0, import_fs.createWriteStream)(this.filePath);
|
|
220
322
|
this.readyPromise = new Promise((resolve, reject) => {
|
|
221
323
|
this.writeStream.once("ready", resolve);
|
|
222
324
|
this.writeStream.once("error", reject);
|
|
223
325
|
});
|
|
224
|
-
this.closedPromise = new Promise((resolve) => {
|
|
326
|
+
this.closedPromise = new Promise((resolve, reject) => {
|
|
225
327
|
this.writeStream.once("close", resolve);
|
|
226
|
-
this.writeStream.once("error",
|
|
328
|
+
this.writeStream.once("error", reject);
|
|
227
329
|
});
|
|
228
330
|
this.gzip = (0, import_zlib.createGzip)();
|
|
229
331
|
this.gzip.pipe(this.writeStream);
|
|
@@ -321,6 +423,7 @@ var DEFAULT_CONFIG = {
|
|
|
321
423
|
logRequestBody: false,
|
|
322
424
|
logResponseHeaders: true,
|
|
323
425
|
logResponseBody: false,
|
|
426
|
+
logException: true,
|
|
324
427
|
maskQueryParams: [],
|
|
325
428
|
maskHeaders: [],
|
|
326
429
|
excludePaths: []
|
|
@@ -373,7 +476,10 @@ var _RequestLogger = class _RequestLogger {
|
|
|
373
476
|
hasSupportedContentType(headers) {
|
|
374
477
|
var _a2;
|
|
375
478
|
const contentType = (_a2 = headers.find(([k]) => k.toLowerCase() === "content-type")) == null ? void 0 : _a2[1];
|
|
376
|
-
return
|
|
479
|
+
return this.isSupportedContentType(contentType);
|
|
480
|
+
}
|
|
481
|
+
isSupportedContentType(contentType) {
|
|
482
|
+
return typeof contentType === "string" && ALLOWED_CONTENT_TYPES.some((t) => contentType.startsWith(t));
|
|
377
483
|
}
|
|
378
484
|
maskQueryParams(search) {
|
|
379
485
|
const params = new URLSearchParams(search);
|
|
@@ -390,7 +496,7 @@ var _RequestLogger = class _RequestLogger {
|
|
|
390
496
|
this.shouldMaskHeader(k) ? MASKED : v
|
|
391
497
|
]);
|
|
392
498
|
}
|
|
393
|
-
logRequest(request, response) {
|
|
499
|
+
logRequest(request, response, error) {
|
|
394
500
|
var _a2, _b, _c;
|
|
395
501
|
if (!this.enabled || this.suspendUntil !== null) return;
|
|
396
502
|
const url = new URL(request.url);
|
|
@@ -401,8 +507,6 @@ var _RequestLogger = class _RequestLogger {
|
|
|
401
507
|
}
|
|
402
508
|
url.search = this.config.logQueryParams ? this.maskQueryParams(url.search) : "";
|
|
403
509
|
request.url = url.toString();
|
|
404
|
-
request.headers = this.config.logRequestHeaders ? this.maskHeaders(request.headers) : [];
|
|
405
|
-
response.headers = this.config.logResponseHeaders ? this.maskHeaders(response.headers) : [];
|
|
406
510
|
if (!this.config.logRequestBody || !this.hasSupportedContentType(request.headers)) {
|
|
407
511
|
request.body = void 0;
|
|
408
512
|
} else if (request.body) {
|
|
@@ -435,10 +539,18 @@ var _RequestLogger = class _RequestLogger {
|
|
|
435
539
|
}
|
|
436
540
|
}
|
|
437
541
|
}
|
|
542
|
+
request.headers = this.config.logRequestHeaders ? this.maskHeaders(request.headers) : [];
|
|
543
|
+
response.headers = this.config.logResponseHeaders ? this.maskHeaders(response.headers) : [];
|
|
438
544
|
const item = {
|
|
439
|
-
uuid: (0,
|
|
545
|
+
uuid: (0, import_crypto3.randomUUID)(),
|
|
440
546
|
request: skipEmptyValues(request),
|
|
441
|
-
response: skipEmptyValues(response)
|
|
547
|
+
response: skipEmptyValues(response),
|
|
548
|
+
exception: error && this.config.logException ? {
|
|
549
|
+
type: error.name,
|
|
550
|
+
message: truncateExceptionMessage(error.message),
|
|
551
|
+
stacktrace: truncateExceptionStackTrace(error.stack || ""),
|
|
552
|
+
sentryEventId: getSentryEventId()
|
|
553
|
+
} : null
|
|
442
554
|
};
|
|
443
555
|
[
|
|
444
556
|
item.request.body,
|
|
@@ -535,7 +647,7 @@ function skipEmptyValues(data) {
|
|
|
535
647
|
__name(skipEmptyValues, "skipEmptyValues");
|
|
536
648
|
function checkWritableFs() {
|
|
537
649
|
try {
|
|
538
|
-
const testPath = (0, import_path2.join)((0, import_os2.tmpdir)(), `apitally-${(0,
|
|
650
|
+
const testPath = (0, import_path2.join)((0, import_os2.tmpdir)(), `apitally-${(0, import_crypto3.randomUUID)()}`);
|
|
539
651
|
(0, import_fs2.writeFileSync)(testPath, "test");
|
|
540
652
|
(0, import_fs2.unlinkSync)(testPath);
|
|
541
653
|
return true;
|
|
@@ -545,104 +657,6 @@ function checkWritableFs() {
|
|
|
545
657
|
}
|
|
546
658
|
__name(checkWritableFs, "checkWritableFs");
|
|
547
659
|
|
|
548
|
-
// src/common/serverErrorCounter.ts
|
|
549
|
-
var import_crypto3 = require("crypto");
|
|
550
|
-
var MAX_MSG_LENGTH = 2048;
|
|
551
|
-
var MAX_STACKTRACE_LENGTH = 65536;
|
|
552
|
-
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
553
|
-
errorCounts;
|
|
554
|
-
errorDetails;
|
|
555
|
-
sentryEventIds;
|
|
556
|
-
sentry;
|
|
557
|
-
constructor() {
|
|
558
|
-
this.errorCounts = /* @__PURE__ */ new Map();
|
|
559
|
-
this.errorDetails = /* @__PURE__ */ new Map();
|
|
560
|
-
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
561
|
-
this.tryImportSentry();
|
|
562
|
-
}
|
|
563
|
-
addServerError(serverError) {
|
|
564
|
-
const key = this.getKey(serverError);
|
|
565
|
-
if (!this.errorDetails.has(key)) {
|
|
566
|
-
this.errorDetails.set(key, serverError);
|
|
567
|
-
}
|
|
568
|
-
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
569
|
-
this.captureSentryEventId(key);
|
|
570
|
-
}
|
|
571
|
-
getAndResetServerErrors() {
|
|
572
|
-
const data = [];
|
|
573
|
-
this.errorCounts.forEach((count, key) => {
|
|
574
|
-
const serverError = this.errorDetails.get(key);
|
|
575
|
-
if (serverError) {
|
|
576
|
-
data.push({
|
|
577
|
-
consumer: serverError.consumer || null,
|
|
578
|
-
method: serverError.method,
|
|
579
|
-
path: serverError.path,
|
|
580
|
-
type: serverError.type,
|
|
581
|
-
msg: this.getTruncatedMessage(serverError.msg),
|
|
582
|
-
traceback: this.getTruncatedStack(serverError.traceback),
|
|
583
|
-
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
584
|
-
error_count: count
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
|
-
});
|
|
588
|
-
this.errorCounts.clear();
|
|
589
|
-
this.errorDetails.clear();
|
|
590
|
-
return data;
|
|
591
|
-
}
|
|
592
|
-
getKey(serverError) {
|
|
593
|
-
const hashInput = [
|
|
594
|
-
serverError.consumer || "",
|
|
595
|
-
serverError.method.toUpperCase(),
|
|
596
|
-
serverError.path,
|
|
597
|
-
serverError.type,
|
|
598
|
-
serverError.msg.trim(),
|
|
599
|
-
serverError.traceback.trim()
|
|
600
|
-
].join("|");
|
|
601
|
-
return (0, import_crypto3.createHash)("md5").update(hashInput).digest("hex");
|
|
602
|
-
}
|
|
603
|
-
getTruncatedMessage(msg) {
|
|
604
|
-
msg = msg.trim();
|
|
605
|
-
if (msg.length <= MAX_MSG_LENGTH) {
|
|
606
|
-
return msg;
|
|
607
|
-
}
|
|
608
|
-
const suffix = "... (truncated)";
|
|
609
|
-
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
610
|
-
return msg.substring(0, cutoff) + suffix;
|
|
611
|
-
}
|
|
612
|
-
getTruncatedStack(stack) {
|
|
613
|
-
const suffix = "... (truncated) ...";
|
|
614
|
-
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
615
|
-
const lines = stack.trim().split("\n");
|
|
616
|
-
const truncatedLines = [];
|
|
617
|
-
let length = 0;
|
|
618
|
-
for (const line of lines) {
|
|
619
|
-
if (length + line.length + 1 > cutoff) {
|
|
620
|
-
truncatedLines.push(suffix);
|
|
621
|
-
break;
|
|
622
|
-
}
|
|
623
|
-
truncatedLines.push(line);
|
|
624
|
-
length += line.length + 1;
|
|
625
|
-
}
|
|
626
|
-
return truncatedLines.join("\n");
|
|
627
|
-
}
|
|
628
|
-
captureSentryEventId(serverErrorKey) {
|
|
629
|
-
if (this.sentry && this.sentry.lastEventId) {
|
|
630
|
-
const eventId = this.sentry.lastEventId();
|
|
631
|
-
if (eventId) {
|
|
632
|
-
this.sentryEventIds.set(serverErrorKey, eventId);
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
async tryImportSentry() {
|
|
637
|
-
try {
|
|
638
|
-
this.sentry = await import("@sentry/node");
|
|
639
|
-
} catch (e) {
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
};
|
|
643
|
-
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
644
|
-
var ServerErrorCounter = _ServerErrorCounter;
|
|
645
|
-
|
|
646
660
|
// src/common/validationErrorCounter.ts
|
|
647
661
|
var import_crypto4 = require("crypto");
|
|
648
662
|
var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
@@ -716,6 +730,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
716
730
|
syncIntervalId;
|
|
717
731
|
startupData;
|
|
718
732
|
startupDataSent = false;
|
|
733
|
+
enabled = true;
|
|
719
734
|
requestCounter;
|
|
720
735
|
requestLogger;
|
|
721
736
|
validationErrorCounter;
|
|
@@ -752,12 +767,16 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
752
767
|
}
|
|
753
768
|
return _ApitallyClient.instance;
|
|
754
769
|
}
|
|
770
|
+
isEnabled() {
|
|
771
|
+
return this.enabled;
|
|
772
|
+
}
|
|
755
773
|
static async shutdown() {
|
|
756
774
|
if (_ApitallyClient.instance) {
|
|
757
775
|
await _ApitallyClient.instance.handleShutdown();
|
|
758
776
|
}
|
|
759
777
|
}
|
|
760
778
|
async handleShutdown() {
|
|
779
|
+
this.enabled = false;
|
|
761
780
|
this.stopSync();
|
|
762
781
|
await this.sendSyncData();
|
|
763
782
|
await this.sendLogData();
|
|
@@ -941,6 +960,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
941
960
|
if (error instanceof HTTPError) {
|
|
942
961
|
if (error.response.status === 404) {
|
|
943
962
|
this.logger.error(`Invalid Apitally client ID: '${this.clientId}'`);
|
|
963
|
+
this.enabled = false;
|
|
944
964
|
this.stopSync();
|
|
945
965
|
return true;
|
|
946
966
|
}
|