feat(observability): add toggle for request detail recording (#122)

* feat(frontend): add toggle logic for observability configuration

(cherry picked from commit 71cef26df6160290c980710ff4a0d6e7aa926105)

* feat(backend): add toggle logic for observability configuration

(cherry picked from commit fb1a8d90e24f041c41b3039f7189791458b87f87)

---------

Co-authored-by: zx <me@char.moe>
This commit is contained in:
zx07 2026-02-13 20:37:54 +08:00 committed by GitHub
parent 03ab554d1c
commit d9bf4c9e59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 62 additions and 8 deletions

View file

@ -51,6 +51,7 @@ const defaultData = {
cloudEnabled: false,
stickyRoundRobinLimit: 3,
requireLogin: true,
observabilityEnabled: true,
observabilityMaxRecords: 1000,
observabilityBatchSize: 20,
observabilityFlushIntervalMs: 5000,
@ -71,6 +72,7 @@ function cloneDefaultData() {
cloudEnabled: false,
stickyRoundRobinLimit: 3,
requireLogin: true,
observabilityEnabled: true,
observabilityMaxRecords: 1000,
observabilityBatchSize: 20,
observabilityFlushIntervalMs: 5000,

View file

@ -17,8 +17,13 @@ async function getObservabilityConfig() {
try {
const { getSettings } = await import("@/lib/localDb");
const settings = await getSettings();
const envEnabled = process.env.OBSERVABILITY_ENABLED !== "false";
const enabled = typeof settings.observabilityEnabled === "boolean"
? settings.observabilityEnabled
: envEnabled;
return {
enabled,
maxRecords: settings.observabilityMaxRecords || parseInt(process.env.OBSERVABILITY_MAX_RECORDS || '1000', 10),
batchSize: settings.observabilityBatchSize || parseInt(process.env.OBSERVABILITY_BATCH_SIZE || '20', 10),
flushIntervalMs: settings.observabilityFlushIntervalMs || parseInt(process.env.OBSERVABILITY_FLUSH_INTERVAL_MS || '5000', 10),
@ -27,6 +32,7 @@ async function getObservabilityConfig() {
} catch (error) {
console.error("[requestDetailsDb] Failed to load observability config:", error);
return {
enabled: true,
maxRecords: 1000,
batchSize: 20,
flushIntervalMs: 5000,
@ -37,6 +43,17 @@ async function getObservabilityConfig() {
// Cache config to avoid repeated database reads
let cachedConfig = null;
let cachedConfigTs = 0;
const CONFIG_CACHE_TTL_MS = 5000;
async function getCachedObservabilityConfig() {
if (!cachedConfig || (Date.now() - cachedConfigTs) > CONFIG_CACHE_TTL_MS) {
cachedConfig = await getObservabilityConfig();
cachedConfigTs = Date.now();
}
return cachedConfig;
}
let dbInstance = null;
@ -317,13 +334,14 @@ function sanitizeHeaders(headers) {
export async function saveRequestDetail(detail) {
if (isCloud) return;
if (!cachedConfig) {
cachedConfig = await getObservabilityConfig();
const config = await getCachedObservabilityConfig();
if (!config.enabled) {
return;
}
writeBuffer.push(detail);
if (writeBuffer.length >= cachedConfig.batchSize) {
if (writeBuffer.length >= config.batchSize) {
await flushToDatabase();
if (flushTimer) {
@ -334,7 +352,7 @@ export async function saveRequestDetail(detail) {
flushTimer = setTimeout(() => {
flushToDatabase().catch(() => {});
flushTimer = null;
}, cachedConfig.flushIntervalMs);
}, config.flushIntervalMs);
}
}