feat(proxy): proxy_logs telemetry — per-attempt provider/ban/latency tracking
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
One row per proxied upstream attempt (pcat call/capture/validate, emex http) written fire-and-forget by the new ProxyTelemetryService (buffered, capped, errors swallowed — telemetry can never hurt the request path). - banned = upstream 403/429 (IP-block signal), distinct from auth/data errors - sticky legs (pcat capture, emex floxy) carry a session_key; pcat capture also resolves the actual residential exit IP via a parallel ipify probe through the same sticky session → concrete banned-IP tracking - rotating legs log provider + outcome (ban *rate* instead of per-IP) - 30-day retention piggybacked on the query-cleanup job Feeds the Süper Panel /analytics/proxy page (provider grading + banned IPs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -617,3 +617,41 @@ export const emexCategoryTranslations = pgTable(
|
||||
},
|
||||
(table) => [uniqueIndex("emex_translations_original_name_idx").on(table.originalName)],
|
||||
);
|
||||
|
||||
// ─── Proxy Logs ──────────────────────────────────────
|
||||
// One row per proxied upstream attempt (pcat call/capture/validate, emex http).
|
||||
// Written fire-and-forget by ProxyTelemetryService so the Süper Panel can grade
|
||||
// proxy providers (success/ban/latency per service) and track banned exit IPs.
|
||||
// `banned` = HTTP 403/429 from the upstream (IP-level block signal); `session_key`
|
||||
// identifies a sticky Floxy session or a DataImpulse port so bans are attributable
|
||||
// even when the exact exit IP is unknown (rotating call legs).
|
||||
export const proxyLogs = pgTable(
|
||||
"proxy_logs",
|
||||
{
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
// Which integration leg made the request: pcat_call | pcat_capture |
|
||||
// pcat_validate | emex_http
|
||||
service: varchar("service", { length: 30 }).notNull(),
|
||||
// floxy | dataimpulse | none (direct)
|
||||
provider: varchar("provider", { length: 20 }).notNull(),
|
||||
// Sticky Floxy session id ("s-ab12cd34") or DataImpulse port ("di:10042");
|
||||
// null on per-request rotating legs (exit IP changes every call).
|
||||
sessionKey: varchar("session_key", { length: 60 }),
|
||||
// Resolved residential exit IP (sticky sessions only — one cheap ipify probe
|
||||
// per session). Null when rotation makes the IP unknowable.
|
||||
exitIp: varchar("exit_ip", { length: 45 }),
|
||||
targetHost: varchar("target_host", { length: 120 }),
|
||||
statusCode: integer("status_code"),
|
||||
// Transport failure class when no HTTP answer arrived:
|
||||
// timeout | connect | reset | dns | aborted | transport
|
||||
errorKind: varchar("error_kind", { length: 30 }),
|
||||
success: boolean("success").default(false).notNull(),
|
||||
banned: boolean("banned").default(false).notNull(),
|
||||
durationMs: integer("duration_ms"),
|
||||
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
||||
},
|
||||
(table) => [
|
||||
index("proxy_logs_created_at_idx").on(table.createdAt),
|
||||
index("proxy_logs_banned_created_at_idx").on(table.banned, table.createdAt),
|
||||
],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user