Ingest live 3proxy traffic from access logs

This commit is contained in:
2026-04-02 02:03:37 +03:00
parent 1141622f86
commit 9a3785deb9
10 changed files with 408 additions and 37 deletions

View File

@@ -4,6 +4,7 @@ import type {
ControlPlaneState,
CreateUserInput,
DashboardSnapshot,
DailyTrafficBucket,
ProxyServiceRecord,
ProxyUserRecord,
} from '../../src/shared/contracts';
@@ -19,6 +20,14 @@ export interface RuntimeSnapshot {
lastError: string | null;
}
export interface ObservedRuntimeState {
totalBytes: number;
liveConnections: number;
activeUsers: number;
daily: DailyTrafficBucket[];
userRecords: ProxyUserRecord[];
}
export interface RuntimePaths {
rootDir: string;
configPath: string;
@@ -73,7 +82,7 @@ export function render3proxyConfig(state: ControlPlaneState, paths: RuntimePaths
lines.push(`users ${activeUsers.map(renderUserCredential).join(' ')}`);
}
const quotaUsers = activeUsers.filter((user) => user.quotaBytes !== null);
const quotaUsers = state.userRecords.filter((user) => user.quotaBytes !== null);
if (quotaUsers.length > 0) {
lines.push(
`counter ${normalizePath(paths.counterPath)} D ${normalizePath(
@@ -112,13 +121,14 @@ export function render3proxyConfig(state: ControlPlaneState, paths: RuntimePaths
export function deriveDashboardSnapshot(
state: ControlPlaneState,
runtime: RuntimeSnapshot,
observed: ObservedRuntimeState,
previewConfig: string,
): DashboardSnapshot {
const liveUsers = state.userRecords.filter((user) => !user.paused && user.status === 'live').length;
const exceededUsers = state.userRecords.filter(
const liveUsers = observed.userRecords.filter((user) => !user.paused && user.status === 'live').length;
const exceededUsers = observed.userRecords.filter(
(user) => user.quotaBytes !== null && user.usedBytes >= user.quotaBytes,
).length;
const nearQuotaUsers = state.userRecords.filter((user) => {
const nearQuotaUsers = observed.userRecords.filter((user) => {
if (user.paused || user.quotaBytes === null || user.usedBytes >= user.quotaBytes) {
return false;
}
@@ -175,17 +185,19 @@ export function deriveDashboardSnapshot(
lastEvent: state.service.lastEvent,
},
traffic: {
...state.traffic,
activeUsers: state.userRecords.filter((user) => !user.paused).length,
totalBytes: observed.totalBytes,
liveConnections: observed.liveConnections,
activeUsers: observed.activeUsers,
daily: observed.daily,
},
users: {
total: state.userRecords.length,
total: observed.userRecords.length,
live: liveUsers,
nearQuota: nearQuotaUsers,
exceeded: exceededUsers,
},
attention,
userRecords: state.userRecords,
userRecords: observed.userRecords,
system: {
...state.system,
previewConfig,