Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.4 kB · 78 lines
Go
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879// Package viewlog captures playback request events (manifest +// segment fetches) to a blob.Store as gzipped JSONL files, so a later// aggregation pass can derive view counts per place.stream.video.//// Goals at this layer: cheap to call from request handlers, non-// blocking, durable enough that a periodic flush survives a crash// with bounded data loss (the in-memory buffer between flushes).//// Privacy: IPs are HMAC'd with a daily-rotated salt held in localdb.// Same IP collides within a UTC day (useful for dedup); the salt// changes at midnight so cross-day correlation requires the original// salt, which the operator can prune to enforce a retention horizon.package viewlog
import "time"
// Event type tags.const ( EventTypeManifestRequest = "manifest_request" EventTypeSegmentRequest = "segment_request")
// Manifest kinds populated on ManifestRequest events.const ( ManifestKindMaster = "master" ManifestKindMedia = "media")
// Event is one line in the JSONL output. The Type field selects which// of the per-type field groups are meaningful — empty fields are// omitted on the wire to keep files small.type Event struct { // Ts is the server's UTC clock at request time. Ts time.Time `json:"ts"` // Type is one of EventType*. Aggregators dispatch on this. Type string `json:"type"` // SID is the playback session id (atproto TID) the player carries // across manifest + segment fetches. Generated by the server on // the master playlist response and threaded through sub-playlist // + segment URLs from there. SID string `json:"sid,omitempty"` // IPHash is hex(HMAC-SHA256(daily_salt, ip)). Same IP, same UTC // day, same hash; salt rotation at midnight breaks correlation // across days. Empty when no IP could be resolved. IPHash string `json:"ip_hash,omitempty"`
// --- manifest_request --- // VideoURI is the place.stream.video AT-URI the manifest is for. VideoURI string `json:"video_uri,omitempty"` // ManifestKind is "master" or "media". ManifestKind string `json:"manifest_kind,omitempty"` // Track is the muxlTrack id when ManifestKind == "media"; empty // for master playlists (those span every track). Track string `json:"track,omitempty"`
// --- segment_request --- // CID is the content-addressed blob requested. For a playback // segment this is the MUXL container blob shared across the // video's tracks; for init segments it's the per-track init // blob. Aggregators join CID → place.stream.video via the // MediaTrack index. CID string `json:"cid,omitempty"` // OwnerDID is the repo DID the segment URL claims as the owner. // Lets the aggregator attribute traffic to a creator without a // CID lookup; verified upstream at the playback handler. OwnerDID string `json:"owner_did,omitempty"` // RangeStart / RangeEnd capture the HTTP Range bytes, when the // request asked for one. End is inclusive (matches RFC 7233). // Zero values indicate "whole blob" / "open-ended" range. RangeStart int64 `json:"range_start,omitempty"` RangeEnd int64 `json:"range_end,omitempty"` // BytesSent is the response body size as reported by whoever // served the request. Set on events ingested from CDN access // logs, which carry no Range header: when it's present and the // Range fields are zero, the aggregator prorates it across the // blob's tracks by byte share instead of intersecting a range. BytesSent int64 `json:"bytes_sent,omitempty"`}