package models import "time" // All timestamps in the metrics tables are int64 unix seconds (events: unix // milliseconds) so range queries behave the same on SQLite and Postgres. // MetricSeries identifies one time series: a metric name plus a fixed label set // reported by one service instance. type MetricSeries struct { ID uint `gorm:"primaryKey" json:"id"` Service string `gorm:"size:64;not null;uniqueIndex:ux_metric_series,priority:1" json:"service"` Instance string `gorm:"size:128;not null;uniqueIndex:ux_metric_series,priority:2" json:"instance"` Name string `gorm:"size:96;not null;uniqueIndex:ux_metric_series,priority:3;index" json:"name"` Labels string `gorm:"size:512;not null;uniqueIndex:ux_metric_series,priority:4" json:"labels"` // canonical JSON object Kind string `gorm:"size:16;not null" json:"kind"` // counter|gauge|summary|histogram Bounds string `gorm:"type:text" json:"bounds"` // JSON []float64, histograms only Help string `gorm:"size:256" json:"help"` CreatedAt time.Time LastSeen int64 `gorm:"index" json:"lastSeen"` } // MetricPoint is one aggregated bucket of a series. Resolution is the bucket // width in seconds (60 = raw minute data, 3600 = hourly rollup). type MetricPoint struct { SeriesID uint `gorm:"primaryKey;autoIncrement:false"` Resolution int `gorm:"primaryKey;autoIncrement:false;index:idx_metric_points_res_bucket,priority:1"` Bucket int64 `gorm:"primaryKey;autoIncrement:false;index:idx_metric_points_res_bucket,priority:2"` Count int64 `gorm:"not null;default:0"` Sum float64 `gorm:"not null;default:0"` Min float64 `gorm:"not null;default:0"` Max float64 `gorm:"not null;default:0"` Last float64 `gorm:"not null;default:0"` Hist string `gorm:"type:text"` // JSON []uint64, histograms only } // ServiceInstance is one running process (indexer, scraper, the API itself) // that reports telemetry. Every telemetry push counts as a heartbeat. type ServiceInstance struct { ID uint `gorm:"primaryKey" json:"id"` Service string `gorm:"size:64;not null;uniqueIndex:ux_service_instance,priority:1" json:"service"` Instance string `gorm:"size:128;not null;uniqueIndex:ux_service_instance,priority:2" json:"instance"` Version string `gorm:"size:64" json:"version"` Status string `gorm:"size:16" json:"status"` // self-reported: ok|degraded|error StatusMessage string `gorm:"size:512" json:"statusMessage"` StartedAt int64 `json:"startedAt"` LastSeen int64 `gorm:"index" json:"lastSeen"` HeartbeatIntervalSec int `json:"heartbeatIntervalSec"` RemoteAddr string `gorm:"size:64" json:"remoteAddr"` Meta string `gorm:"type:text" json:"meta"` // JSON object CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } // ServiceEvent is a log line reported by a service. Admin actions are recorded // here too (service "main", fields.kind "audit"). type ServiceEvent struct { ID uint `gorm:"primaryKey" json:"id"` Service string `gorm:"size:64;index:idx_service_events_svc_ts,priority:1" json:"service"` Instance string `gorm:"size:128" json:"instance"` Level string `gorm:"size:8;index" json:"level"` // debug|info|warn|error Message string `gorm:"size:1024" json:"message"` Fields string `gorm:"type:text" json:"fields"` // JSON object TS int64 `gorm:"index:idx_service_events_svc_ts,priority:2;index" json:"ts"` // unix ms } // DailyTopItem counts how often something was requested on one UTC day // (Kind "addon": addon lookups, Kind "search": search queries). type DailyTopItem struct { Day string `gorm:"primaryKey;size:10"` // YYYY-MM-DD Kind string `gorm:"primaryKey;size:16"` Item string `gorm:"primaryKey;size:128"` Count int64 }