@bakery-framework/plugin-analytics 2.1.2 → 2.2.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/package.json +2 -2
- package/src/core.ts +1 -0
- package/src/endpoints/stats.ts +3 -2
- package/src/loop.ts +14 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bakery-framework/plugin-analytics",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Bakery analytics plugin.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bakery",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"!src/tests"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@bakery-framework/core": "^2.1
|
|
39
|
+
"@bakery-framework/core": "^2.2.1"
|
|
40
40
|
},
|
|
41
41
|
"engines": {
|
|
42
42
|
"bun": ">=1.4.0"
|
package/src/core.ts
CHANGED
package/src/endpoints/stats.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Bakery } from '@bakery-framework/core/core/bakery'
|
|
2
|
-
import { Session } from '@bakery-framework/core/session'
|
|
3
2
|
import type { JsonResponseData } from '@bakery-framework/core/utils/common'
|
|
4
3
|
import {
|
|
5
4
|
type AuthorizeFn,
|
|
@@ -61,7 +60,9 @@ export function computeStats(
|
|
|
61
60
|
platform: process.platform,
|
|
62
61
|
arch: process.arch,
|
|
63
62
|
activeLoggers: core.connectedLoggers.size,
|
|
64
|
-
|
|
63
|
+
// The tick's count, at most a second old: this runs synchronously, and
|
|
64
|
+
// a configured store can only be counted asynchronously.
|
|
65
|
+
activeSessions: latestHistory.activeSessions,
|
|
65
66
|
routeHits: latestHistory.routeHits,
|
|
66
67
|
apiHits: latestHistory.apiHits || 0,
|
|
67
68
|
pageHits: latestHistory.pageHits || 0,
|
package/src/loop.ts
CHANGED
|
@@ -15,6 +15,13 @@ export const ANALYTICS_TICK_MS = 1000
|
|
|
15
15
|
|
|
16
16
|
let lastSaveTime = 0
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* The last count a store gave. A store that cannot be read keeps it, rather
|
|
20
|
+
* than failing the tick: the requests that need the store already report
|
|
21
|
+
* it, and a gap in the telemetry would report nothing.
|
|
22
|
+
*/
|
|
23
|
+
let lastSessionCount = 0
|
|
24
|
+
|
|
18
25
|
/**
|
|
19
26
|
* Flush at most once per `SAVE_THROTTLE_MS`.
|
|
20
27
|
*
|
|
@@ -44,12 +51,16 @@ async function runAnalyticsTick(server: any) {
|
|
|
44
51
|
return res.status === 200 ? getElapsed(pingStart) : res.status
|
|
45
52
|
}, 0)
|
|
46
53
|
|
|
54
|
+
// Asked of whichever store holds the sessions: a COUNT(*) on the built-in
|
|
55
|
+
// one's SQLite file, one over the `expires_at` index on a database store.
|
|
56
|
+
lastSessionCount = await Try.return(() => Session.total(), lastSessionCount)
|
|
57
|
+
|
|
47
58
|
const mem = process.memoryUsage()
|
|
48
59
|
core.pushAnalyticsSnapshot({
|
|
49
60
|
timestamp: Date.now(),
|
|
50
61
|
memoryUsed: Math.round(mem.rss / 1024 / 1024),
|
|
51
62
|
activeLoggers: activeLoggersCount,
|
|
52
|
-
activeSessions:
|
|
63
|
+
activeSessions: lastSessionCount,
|
|
53
64
|
ping: pingVal,
|
|
54
65
|
})
|
|
55
66
|
|
|
@@ -128,7 +139,8 @@ let loopRunning = false
|
|
|
128
139
|
*
|
|
129
140
|
* A self-rescheduling `setTimeout`, not `setInterval`. The tick body makes a
|
|
130
141
|
* full round trip through the server (`MiddlewareHandler`, so `onRequest` and
|
|
131
|
-
* every app middleware) plus a `Session.
|
|
142
|
+
* every app middleware) plus a `Session.total()`: a SQLite `COUNT(*)` with the
|
|
143
|
+
* built-in store, a query to the database with a database one.
|
|
132
144
|
* `setInterval` does not wait for an async body, so once p50 exceeded one
|
|
133
145
|
* second the ticks overlapped and the in-flight pings accumulated, each adding
|
|
134
146
|
* load that lengthened the next: positive feedback, from the telemetry.
|