Add stats
Just adding this early version for now so I can iterate.
This commit is contained in:
@@ -0,0 +1,85 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const {defineEventHandler, getValidatedQuery, H3Event, setResponseHeader} = require("h3")
|
||||||
|
const {as, db, sync} = require("../../passthrough")
|
||||||
|
const {reg} = require("../../matrix/read-registration")
|
||||||
|
|
||||||
|
/** @type {import("../../discord/utils")} */
|
||||||
|
const dUtils = sync.require("../../discord/utils")
|
||||||
|
|
||||||
|
// Calculation takes time and is single-threaded. I could add database indexes, but this is simpler and doesn't need storage.
|
||||||
|
const STATS_CACHE_TIME = 10 * 60 * 1000 // 10 minutes
|
||||||
|
|
||||||
|
function getMessageCountLastDuration(duration) {
|
||||||
|
const snowflake = dUtils.timestampToSnowflakeInexact(Date.now() - duration)
|
||||||
|
return db.prepare("select count(*) from message_room where message_id >= ? and length(message_id) = ?").pluck().get(snowflake, snowflake.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStats() {
|
||||||
|
const durations = [
|
||||||
|
["week", 7 * 24 * 60 * 60 * 1000],
|
||||||
|
["day", 1 * 24 * 60 * 60 * 1000],
|
||||||
|
["hour", 1 * 60 * 60 * 1000]
|
||||||
|
]
|
||||||
|
|
||||||
|
// console.time("get stats")
|
||||||
|
let temp = {
|
||||||
|
guilds: db.prepare("select count(*) from guild_space").pluck().get(),
|
||||||
|
channels: db.prepare("select count(*) from channel_room").pluck().get(),
|
||||||
|
messages: db.prepare("select count(*) from message_room").pluck().get(),
|
||||||
|
...durations.reduce((a, c) => (a[`messages_last_${c[0]}`] = getMessageCountLastDuration(c[1]), a), {}),
|
||||||
|
message_sources: db.prepare("select count(*) from event_message where part = 0 group by source order by source").pluck().all(),
|
||||||
|
oldest_message: new Date(dUtils.snowflakeToTimestampExact(db.prepare("select min(message_id) from event_message where source = 0").pluck().get())), // good until 2090
|
||||||
|
discord_users: db.prepare("select count(*) from sim").pluck().get(),
|
||||||
|
matrix_users: db.prepare("select count(distinct mxid) from member_cache where mxid not like ?").pluck().get(reg.namespaces.users[0].regex.replace(/\.\*.*/, "%")),
|
||||||
|
}
|
||||||
|
// console.timeEnd("get stats")
|
||||||
|
return temp
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {ReturnType<typeof getStats>} */
|
||||||
|
let stats
|
||||||
|
let statsUpdatedAt = 0
|
||||||
|
|
||||||
|
function updateStatsIfOld() {
|
||||||
|
if (statsUpdatedAt < Date.now() - STATS_CACHE_TIME) {
|
||||||
|
stats = getStats()
|
||||||
|
statsUpdatedAt = Date.now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
as.router.get("/api/stats", defineEventHandler(async event => {
|
||||||
|
updateStatsIfOld()
|
||||||
|
return {
|
||||||
|
...stats,
|
||||||
|
oldest_message: stats.oldest_message.toISOString(),
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
as.router.get("/metrics", defineEventHandler(async event => {
|
||||||
|
updateStatsIfOld()
|
||||||
|
setResponseHeader(event, "content-type", "text/plain")
|
||||||
|
return `
|
||||||
|
# HELP guilds Total number of guilds
|
||||||
|
# TYPE guilds gauge
|
||||||
|
ooye_guilds_total ${stats.guilds}
|
||||||
|
|
||||||
|
# HELP channels Total number of channels
|
||||||
|
# TYPE channels gauge
|
||||||
|
ooye_channels_total ${stats.channels}
|
||||||
|
|
||||||
|
# HELP messages_total Total number of messages sent from each side
|
||||||
|
# TYPE messages_total gauge
|
||||||
|
ooye_messages_total{type="matrix"} ${stats.message_sources[0]}
|
||||||
|
ooye_messages_total{type="discord"} ${stats.message_sources[1]}
|
||||||
|
|
||||||
|
# HELP oldest_message_timestamp Unix timestamp of the oldest message
|
||||||
|
# TYPE oldest_message_timestamp gauge
|
||||||
|
ooye_oldest_message_timestamp_seconds ${stats.oldest_message.getTime() / 1000}
|
||||||
|
|
||||||
|
# HELP ooye_users_total Total number of users on each side
|
||||||
|
# TYPE ooye_users_total gauge
|
||||||
|
ooye_users_total{type="matrix"} ${stats.matrix_users}
|
||||||
|
ooye_users_total{type="discord"} ${stats.discord_users}
|
||||||
|
`.trimStart()
|
||||||
|
}))
|
||||||
@@ -135,3 +135,4 @@ sync.require("./routes/link")
|
|||||||
sync.require("./routes/log-in-with-matrix")
|
sync.require("./routes/log-in-with-matrix")
|
||||||
sync.require("./routes/oauth")
|
sync.require("./routes/oauth")
|
||||||
sync.require("./routes/password")
|
sync.require("./routes/password")
|
||||||
|
sync.require("./routes/stats")
|
||||||
|
|||||||
Reference in New Issue
Block a user