zen: log ip prefix
This commit is contained in:
parent
bcc345ff82
commit
51a9b0baad
@ -21,6 +21,7 @@ export default {
|
||||
)
|
||||
continue
|
||||
|
||||
const ip = event.event.request.headers["x-real-ip"]
|
||||
let data: Record<string, unknown> = {
|
||||
"cf.continent": event.event.request.cf?.continent,
|
||||
"cf.country": event.event.request.cf?.country,
|
||||
@ -32,7 +33,8 @@ export default {
|
||||
duration: event.wallTime,
|
||||
request_length: parseInt(event.event.request.headers["content-length"] ?? "0"),
|
||||
status: event.event.response?.status ?? 0,
|
||||
ip: event.event.request.headers["x-real-ip"],
|
||||
ip,
|
||||
"ip.prefix": ipPrefix(ip),
|
||||
}
|
||||
const time = new Date(event.eventTimestamp ?? Date.now()).toISOString()
|
||||
const events = [
|
||||
@ -110,6 +112,7 @@ function toLakeEvent(time: string, data: Record<string, unknown>) {
|
||||
request_length: integer(data, "request_length"),
|
||||
status: integer(data, "status"),
|
||||
ip: string(data, "ip"),
|
||||
ip_prefix: string(data, "ip.prefix"),
|
||||
is_stream: boolean(data, "is_stream"),
|
||||
session: string(data, "session"),
|
||||
request: string(data, "request"),
|
||||
@ -146,15 +149,32 @@ function toLakeEvent(time: string, data: Record<string, unknown>) {
|
||||
cost_cache_read_microcents: integer(data, "cost.cache_read.microcents"),
|
||||
cost_cache_write_microcents: integer(data, "cost.cache_write.microcents"),
|
||||
cost_total_microcents: integer(data, "cost.total.microcents"),
|
||||
cost_input: integer(data, "cost.input"),
|
||||
cost_output: integer(data, "cost.output"),
|
||||
cost_cache_read: integer(data, "cost.cache_read"),
|
||||
cost_cache_write_5m: integer(data, "cost.cache_write_5m"),
|
||||
cost_cache_write_1h: integer(data, "cost.cache_write_1h"),
|
||||
cost_total: integer(data, "cost.total"),
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a stable lookup key for an IP address.
|
||||
// IPv4: full address as /32 (e.g. "203.0.113.45/32").
|
||||
// IPv6: the /64 network prefix (e.g. "2001:db8:abcd:1234::/64"). ISPs commonly
|
||||
// rotate the lower 64 host bits via SLAAC privacy extensions (RFC 8981), so
|
||||
// grouping by /64 collapses those rotations into one key.
|
||||
function ipPrefix(ip: string | undefined) {
|
||||
if (!ip) return undefined
|
||||
if (ip.includes(".") && !ip.includes(":")) return `${ip}/32`
|
||||
if (!ip.includes(":")) return undefined
|
||||
|
||||
// Expand "::" to its full form, then keep the first 4 hextets.
|
||||
const [head, tail] = ip.split("::") as [string, string | undefined]
|
||||
const headParts = head ? head.split(":") : []
|
||||
const tailParts = tail !== undefined ? tail.split(":") : []
|
||||
const missing = 8 - headParts.length - tailParts.length
|
||||
if (missing < 0) return undefined
|
||||
const full = [...headParts, ...new Array(missing).fill("0"), ...tailParts]
|
||||
if (full.length !== 8) return undefined
|
||||
|
||||
const prefix = full.slice(0, 4).map((part) => part.toLowerCase().replace(/^0+(?=.)/, "")).join(":")
|
||||
return `${prefix}::/64`
|
||||
}
|
||||
|
||||
function string(data: Record<string, unknown>, key: string) {
|
||||
const value = data[key]
|
||||
if (typeof value === "string") return value
|
||||
|
||||
Loading…
Reference in New Issue
Block a user