@wtfalch/reporting 0.5.1 → 0.8.1
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 +115 -15
- package/dist/analytics/write.js +3 -0
- package/dist/deploy.d.ts +11 -0
- package/dist/deploy.js +13 -0
- package/dist/errors/capture.js +46 -7
- package/dist/errors/reader.d.ts +22 -3
- package/dist/errors/reader.js +84 -21
- package/dist/errors/redact.d.ts +1 -0
- package/dist/errors/redact.js +63 -0
- package/dist/errors/tasks.d.ts +15 -0
- package/dist/errors/tasks.js +47 -0
- package/dist/housekeeping/index.d.ts +2 -0
- package/dist/housekeeping/index.js +2 -0
- package/dist/index.js +13 -1
- package/dist/migrations/0001_reporting.sql +6 -20
- package/dist/migrations/0002_analytics.sql +6 -20
- package/dist/migrations/0003_errors.sql +4 -16
- package/dist/migrations/0006_tenant_settings.sql +3 -21
- package/dist/migrations/0007_errors_open_cap.sql +42 -0
- package/dist/migrations/0008_error_tenants.sql +35 -0
- package/dist/migrations/0009_release_color.sql +33 -0
- package/dist/migrations/0010_requests.sql +27 -0
- package/dist/migrations-dir.d.ts +11 -0
- package/dist/migrations-dir.js +12 -0
- package/dist/next/index.d.ts +1 -0
- package/dist/next/index.js +1 -0
- package/dist/next/release-health.d.ts +22 -0
- package/dist/next/release-health.js +122 -0
- package/dist/react/errors.d.ts +2 -2
- package/dist/react/errors.js +1 -1
- package/dist/requests.d.ts +22 -0
- package/dist/requests.js +72 -0
- package/dist/tables.d.ts +609 -16
- package/dist/tables.js +32 -0
- package/dist/types.d.ts +12 -4
- package/dist/writer.js +2 -0
- package/package.json +8 -8
- package/dist/fake/index.d.ts +0 -22
- package/dist/fake/index.js +0 -157
package/dist/requests.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { sql } from 'drizzle-orm';
|
|
2
|
+
import { deployTags } from './deploy.js';
|
|
3
|
+
import { reportingRequests } from './tables.js';
|
|
4
|
+
/**
|
|
5
|
+
* Counts responses in memory and writes one upsert per minute bucket, so a
|
|
6
|
+
* request costs a map increment and the database sees a handful of rows a
|
|
7
|
+
* minute. `errors` is status >= 500. A failed write puts its counts back for
|
|
8
|
+
* the next one; the process dying loses at most `flushEveryMs` of counts.
|
|
9
|
+
*/
|
|
10
|
+
export class RequestCounter {
|
|
11
|
+
o;
|
|
12
|
+
buckets = new Map();
|
|
13
|
+
timer = null;
|
|
14
|
+
constructor(o) {
|
|
15
|
+
this.o = o;
|
|
16
|
+
}
|
|
17
|
+
record(status) {
|
|
18
|
+
const minute = Math.floor(this.o.now().getTime() / 60_000) * 60_000;
|
|
19
|
+
const b = this.buckets.get(minute) ?? { requests: 0, errors: 0 };
|
|
20
|
+
b.requests += 1;
|
|
21
|
+
if (status >= 500)
|
|
22
|
+
b.errors += 1;
|
|
23
|
+
this.buckets.set(minute, b);
|
|
24
|
+
if (!this.timer) {
|
|
25
|
+
this.timer = setTimeout(() => {
|
|
26
|
+
this.timer = null;
|
|
27
|
+
void this.flush();
|
|
28
|
+
}, this.o.flushEveryMs);
|
|
29
|
+
this.timer.unref?.();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async flush() {
|
|
33
|
+
if (this.buckets.size === 0)
|
|
34
|
+
return;
|
|
35
|
+
const taken = [...this.buckets];
|
|
36
|
+
this.buckets.clear();
|
|
37
|
+
const { color, release } = deployTags();
|
|
38
|
+
try {
|
|
39
|
+
await this.o.db
|
|
40
|
+
.insert(reportingRequests)
|
|
41
|
+
.values(taken.map(([minute, c]) => ({
|
|
42
|
+
bucket: new Date(minute),
|
|
43
|
+
site: this.o.site,
|
|
44
|
+
color: color ?? '',
|
|
45
|
+
release: release ?? '',
|
|
46
|
+
requests: c.requests,
|
|
47
|
+
errors: c.errors,
|
|
48
|
+
})))
|
|
49
|
+
.onConflictDoUpdate({
|
|
50
|
+
target: [
|
|
51
|
+
reportingRequests.bucket,
|
|
52
|
+
reportingRequests.site,
|
|
53
|
+
reportingRequests.color,
|
|
54
|
+
reportingRequests.release,
|
|
55
|
+
],
|
|
56
|
+
set: {
|
|
57
|
+
requests: sql `${reportingRequests.requests} + excluded.requests`,
|
|
58
|
+
errors: sql `${reportingRequests.errors} + excluded.errors`,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
for (const [minute, c] of taken) {
|
|
64
|
+
const b = this.buckets.get(minute) ?? { requests: 0, errors: 0 };
|
|
65
|
+
b.requests += c.requests;
|
|
66
|
+
b.errors += c.errors;
|
|
67
|
+
this.buckets.set(minute, b);
|
|
68
|
+
}
|
|
69
|
+
this.o.log.error({ err: error instanceof Error ? error.name : 'unknown' }, 'reporting: request counter flush failed');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|