refactor(db): port metrics storage + service domains to sqlc

First tranche of the ~300-site raw SQL port. Metrics: node/service/
instance rows via generated queries; aggregation moved off TimescaleDB's
time_bucket onto portable date_bin (PG14+); interval uptime returns epoch
seconds; per-container writes dropped (container_metrics FKs a different
model — collector shape never matched). Domains: all reads/writes through
sqlcdb including the create transaction via WithTx; default-domain and
services.domain invariants unchanged. Both paths covered by live
Postgres tests gated on METRICS_TEST_DSN.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-10-10 03:06:42 +02:00
1 parent ca8eab4a65
commit c4f36e4953
12 files changed
+1825 -385

No files matched your search

@@ -0,0 +1,242 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: domains.sql
package sqlcdb
import (
"context"
"database/sql"
"time"
"github.com/google/uuid"
)
const clearServiceDomainDefault = `-- name: ClearServiceDomainDefault :exec
UPDATE service_domains SET is_default = false WHERE service_id = $1
`
func (q *Queries) ClearServiceDomainDefault(ctx context.Context, serviceID uuid.UUID) error {
_, err := q.db.ExecContext(ctx, clearServiceDomainDefault, serviceID)
return err
}
const countServiceDomains = `-- name: CountServiceDomains :one
SELECT COUNT(*) FROM service_domains WHERE service_id = $1
`
func (q *Queries) CountServiceDomains(ctx context.Context, serviceID uuid.UUID) (int64, error) {
row := q.db.QueryRowContext(ctx, countServiceDomains, serviceID)
var count int64
err := row.Scan(&count)
return count, err
}
const createServiceDomain = `-- name: CreateServiceDomain :one
INSERT INTO service_domains (service_id, domain, is_default)
VALUES ($1, $2, $3)
RETURNING id, service_id, domain, is_default, cert_type, cert_status, created_at
`
type CreateServiceDomainParams struct {
ServiceID uuid.UUID `json:"service_id"`
Domain string `json:"domain"`
IsDefault bool `json:"is_default"`
}
type CreateServiceDomainRow struct {
ID uuid.UUID `json:"id"`
ServiceID uuid.UUID `json:"service_id"`
Domain string `json:"domain"`
IsDefault bool `json:"is_default"`
CertType string `json:"cert_type"`
CertStatus string `json:"cert_status"`
CreatedAt time.Time `json:"created_at"`
}
func (q *Queries) CreateServiceDomain(ctx context.Context, arg CreateServiceDomainParams) (CreateServiceDomainRow, error) {
row := q.db.QueryRowContext(ctx, createServiceDomain, arg.ServiceID, arg.Domain, arg.IsDefault)
var i CreateServiceDomainRow
err := row.Scan(
&i.ID,
&i.ServiceID,
&i.Domain,
&i.IsDefault,
&i.CertType,
&i.CertStatus,
&i.CreatedAt,
)
return i, err
}
const deleteServiceDomain = `-- name: DeleteServiceDomain :execrows
DELETE FROM service_domains WHERE id = $1 AND service_id = $2
`
type DeleteServiceDomainParams struct {
ID uuid.UUID `json:"id"`
ServiceID uuid.UUID `json:"service_id"`
}
func (q *Queries) DeleteServiceDomain(ctx context.Context, arg DeleteServiceDomainParams) (int64, error) {
result, err := q.db.ExecContext(ctx, deleteServiceDomain, arg.ID, arg.ServiceID)
if err != nil {
return 0, err
}
return result.RowsAffected()
}
const getServiceAccess = `-- name: GetServiceAccess :one
SELECT maintenance_mode, basic_auth_users FROM services WHERE id = $1
`
type GetServiceAccessRow struct {
MaintenanceMode bool `json:"maintenance_mode"`
BasicAuthUsers string `json:"basic_auth_users"`
}
func (q *Queries) GetServiceAccess(ctx context.Context, id uuid.UUID) (GetServiceAccessRow, error) {
row := q.db.QueryRowContext(ctx, getServiceAccess, id)
var i GetServiceAccessRow
err := row.Scan(&i.MaintenanceMode, &i.BasicAuthUsers)
return i, err
}
const getServiceDomainDefault = `-- name: GetServiceDomainDefault :one
SELECT domain FROM service_domains WHERE service_id = $1 AND is_default
`
func (q *Queries) GetServiceDomainDefault(ctx context.Context, serviceID uuid.UUID) (string, error) {
row := q.db.QueryRowContext(ctx, getServiceDomainDefault, serviceID)
var domain string
err := row.Scan(&domain)
return domain, err
}
const getServiceDomainFirst = `-- name: GetServiceDomainFirst :one
SELECT domain FROM service_domains WHERE service_id = $1 ORDER BY created_at ASC LIMIT 1
`
func (q *Queries) GetServiceDomainFirst(ctx context.Context, serviceID uuid.UUID) (string, error) {
row := q.db.QueryRowContext(ctx, getServiceDomainFirst, serviceID)
var domain string
err := row.Scan(&domain)
return domain, err
}
const getServicePlacementBrief = `-- name: GetServicePlacementBrief :one
SELECT name, node_id, COALESCE(spread, false) AS spread FROM services WHERE id = $1
`
type GetServicePlacementBriefRow struct {
Name string `json:"name"`
NodeID sql.NullString `json:"node_id"`
Spread bool `json:"spread"`
}
func (q *Queries) GetServicePlacementBrief(ctx context.Context, id uuid.UUID) (GetServicePlacementBriefRow, error) {
row := q.db.QueryRowContext(ctx, getServicePlacementBrief, id)
var i GetServicePlacementBriefRow
err := row.Scan(&i.Name, &i.NodeID, &i.Spread)
return i, err
}
const listServiceDomains = `-- name: ListServiceDomains :many
SELECT id, service_id, domain, is_default, cert_type, cert_status, last_checked_at, created_at
FROM service_domains
WHERE service_id = $1
ORDER BY is_default DESC, created_at ASC
`
func (q *Queries) ListServiceDomains(ctx context.Context, serviceID uuid.UUID) ([]ServiceDomain, error) {
rows, err := q.db.QueryContext(ctx, listServiceDomains, serviceID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ServiceDomain{}
for rows.Next() {
var i ServiceDomain
if err := rows.Scan(
&i.ID,
&i.ServiceID,
&i.Domain,
&i.IsDefault,
&i.CertType,
&i.CertStatus,
&i.LastCheckedAt,
&i.CreatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const serviceWriteAccess = `-- name: ServiceWriteAccess :one
SELECT EXISTS(
SELECT 1 FROM services s JOIN projects p ON s.project_id = p.id
WHERE s.id = $1 AND (p.owner_id = $2 OR $3::bool)
) AS allowed
`
type ServiceWriteAccessParams struct {
ID uuid.UUID `json:"id"`
OwnerID uuid.UUID `json:"owner_id"`
Column3 bool `json:"column_3"`
}
func (q *Queries) ServiceWriteAccess(ctx context.Context, arg ServiceWriteAccessParams) (bool, error) {
row := q.db.QueryRowContext(ctx, serviceWriteAccess, arg.ID, arg.OwnerID, arg.Column3)
var allowed bool
err := row.Scan(&allowed)
return allowed, err
}
const setServiceDomainDefault = `-- name: SetServiceDomainDefault :execrows
UPDATE service_domains SET is_default = (id = $1) WHERE service_id = $2
`
type SetServiceDomainDefaultParams struct {
ID uuid.UUID `json:"id"`
ServiceID uuid.UUID `json:"service_id"`
}
func (q *Queries) SetServiceDomainDefault(ctx context.Context, arg SetServiceDomainDefaultParams) (int64, error) {
result, err := q.db.ExecContext(ctx, setServiceDomainDefault, arg.ID, arg.ServiceID)
if err != nil {
return 0, err
}
return result.RowsAffected()
}
const setServiceLegacyDomain = `-- name: SetServiceLegacyDomain :exec
UPDATE services SET domain = $1 WHERE id = $2
`
type SetServiceLegacyDomainParams struct {
Domain string `json:"domain"`
ID uuid.UUID `json:"id"`
}
func (q *Queries) SetServiceLegacyDomain(ctx context.Context, arg SetServiceLegacyDomainParams) error {
_, err := q.db.ExecContext(ctx, setServiceLegacyDomain, arg.Domain, arg.ID)
return err
}
const touchServiceDomainChecked = `-- name: TouchServiceDomainChecked :exec
UPDATE service_domains SET last_checked_at = NOW() WHERE id = $1
`
func (q *Queries) TouchServiceDomainChecked(ctx context.Context, id uuid.UUID) error {
_, err := q.db.ExecContext(ctx, touchServiceDomainChecked, id)
return err
}
@@ -0,0 +1,623 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: metrics.sql
package sqlcdb
import (
"context"
"database/sql"
"time"
)
const aggregateNodeMetrics = `-- name: AggregateNodeMetrics :many
SELECT date_bin($1::interval, timestamp, '2000-01-01'::timestamptz) AS bucket,
AVG(cpu_usage)::float8 AS avg_cpu,
AVG(memory_usage_percent)::float8 AS avg_memory,
AVG(storage_usage_percent)::float8 AS avg_storage
FROM node_metrics
WHERE node_id = $2 AND timestamp BETWEEN $3 AND $4
GROUP BY bucket
ORDER BY bucket ASC
`
type AggregateNodeMetricsParams struct {
Column1 int64 `json:"column_1"`
NodeID string `json:"node_id"`
Timestamp time.Time `json:"timestamp"`
Timestamp_2 time.Time `json:"timestamp_2"`
}
type AggregateNodeMetricsRow struct {
Bucket interface{} `json:"bucket"`
AvgCpu float64 `json:"avg_cpu"`
AvgMemory float64 `json:"avg_memory"`
AvgStorage float64 `json:"avg_storage"`
}
// Portable bucket bucketing (no TimescaleDB): floor epoch seconds into
// bucket-sized buckets, then back to timestamptz.
func (q *Queries) AggregateNodeMetrics(ctx context.Context, arg AggregateNodeMetricsParams) ([]AggregateNodeMetricsRow, error) {
rows, err := q.db.QueryContext(ctx, aggregateNodeMetrics,
arg.Column1,
arg.NodeID,
arg.Timestamp,
arg.Timestamp_2,
)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AggregateNodeMetricsRow{}
for rows.Next() {
var i AggregateNodeMetricsRow
if err := rows.Scan(
&i.Bucket,
&i.AvgCpu,
&i.AvgMemory,
&i.AvgStorage,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listInstanceMetrics = `-- name: ListInstanceMetrics :many
SELECT instance_id, node_id, status, cpu, memory,
network_bytes_in, network_bytes_out, network_packets_in, network_packets_out,
network_connections_in, network_connections_out, network_errors_in, network_errors_out,
start_time, last_seen, health_status, health_last_check, health_check_count, health_failure_count
FROM instance_metrics
WHERE service_id = $1 AND timestamp = $2
`
type ListInstanceMetricsParams struct {
ServiceID string `json:"service_id"`
Timestamp time.Time `json:"timestamp"`
}
type ListInstanceMetricsRow struct {
InstanceID string `json:"instance_id"`
NodeID sql.NullString `json:"node_id"`
Status sql.NullString `json:"status"`
Cpu sql.NullString `json:"cpu"`
Memory sql.NullInt64 `json:"memory"`
NetworkBytesIn sql.NullInt64 `json:"network_bytes_in"`
NetworkBytesOut sql.NullInt64 `json:"network_bytes_out"`
NetworkPacketsIn sql.NullInt64 `json:"network_packets_in"`
NetworkPacketsOut sql.NullInt64 `json:"network_packets_out"`
NetworkConnectionsIn sql.NullInt32 `json:"network_connections_in"`
NetworkConnectionsOut sql.NullInt32 `json:"network_connections_out"`
NetworkErrorsIn sql.NullInt64 `json:"network_errors_in"`
NetworkErrorsOut sql.NullInt64 `json:"network_errors_out"`
StartTime sql.NullTime `json:"start_time"`
LastSeen sql.NullTime `json:"last_seen"`
HealthStatus sql.NullString `json:"health_status"`
HealthLastCheck sql.NullTime `json:"health_last_check"`
HealthCheckCount sql.NullInt32 `json:"health_check_count"`
HealthFailureCount sql.NullInt32 `json:"health_failure_count"`
}
func (q *Queries) ListInstanceMetrics(ctx context.Context, arg ListInstanceMetricsParams) ([]ListInstanceMetricsRow, error) {
rows, err := q.db.QueryContext(ctx, listInstanceMetrics, arg.ServiceID, arg.Timestamp)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListInstanceMetricsRow{}
for rows.Next() {
var i ListInstanceMetricsRow
if err := rows.Scan(
&i.InstanceID,
&i.NodeID,
&i.Status,
&i.Cpu,
&i.Memory,
&i.NetworkBytesIn,
&i.NetworkBytesOut,
&i.NetworkPacketsIn,
&i.NetworkPacketsOut,
&i.NetworkConnectionsIn,
&i.NetworkConnectionsOut,
&i.NetworkErrorsIn,
&i.NetworkErrorsOut,
&i.StartTime,
&i.LastSeen,
&i.HealthStatus,
&i.HealthLastCheck,
&i.HealthCheckCount,
&i.HealthFailureCount,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listNodeMetrics = `-- name: ListNodeMetrics :many
SELECT node_id, timestamp, cpu_usage, cpu_cores, load_avg_1, load_avg_5, load_avg_15,
memory_total, memory_used, memory_available, memory_usage_percent,
storage_total, storage_used, storage_available, storage_usage_percent,
network_bytes_in, network_bytes_out, network_packets_in, network_packets_out,
network_connections_in, network_connections_out, network_errors_in, network_errors_out,
coalesce(extract(epoch from uptime), 0)::bigint AS uptime_seconds,
processes, os, kernel, architecture
FROM node_metrics
WHERE node_id = $1 AND timestamp BETWEEN $2 AND $3
ORDER BY timestamp ASC
`
type ListNodeMetricsParams struct {
NodeID string `json:"node_id"`
Timestamp time.Time `json:"timestamp"`
Timestamp_2 time.Time `json:"timestamp_2"`
}
type ListNodeMetricsRow struct {
NodeID string `json:"node_id"`
Timestamp time.Time `json:"timestamp"`
CpuUsage sql.NullString `json:"cpu_usage"`
CpuCores sql.NullString `json:"cpu_cores"`
LoadAvg1 sql.NullString `json:"load_avg_1"`
LoadAvg5 sql.NullString `json:"load_avg_5"`
LoadAvg15 sql.NullString `json:"load_avg_15"`
MemoryTotal sql.NullInt64 `json:"memory_total"`
MemoryUsed sql.NullInt64 `json:"memory_used"`
MemoryAvailable sql.NullInt64 `json:"memory_available"`
MemoryUsagePercent sql.NullString `json:"memory_usage_percent"`
StorageTotal sql.NullInt64 `json:"storage_total"`
StorageUsed sql.NullInt64 `json:"storage_used"`
StorageAvailable sql.NullInt64 `json:"storage_available"`
StorageUsagePercent sql.NullString `json:"storage_usage_percent"`
NetworkBytesIn sql.NullInt64 `json:"network_bytes_in"`
NetworkBytesOut sql.NullInt64 `json:"network_bytes_out"`
NetworkPacketsIn sql.NullInt64 `json:"network_packets_in"`
NetworkPacketsOut sql.NullInt64 `json:"network_packets_out"`
NetworkConnectionsIn sql.NullInt32 `json:"network_connections_in"`
NetworkConnectionsOut sql.NullInt32 `json:"network_connections_out"`
NetworkErrorsIn sql.NullInt64 `json:"network_errors_in"`
NetworkErrorsOut sql.NullInt64 `json:"network_errors_out"`
UptimeSeconds int64 `json:"uptime_seconds"`
Processes sql.NullInt32 `json:"processes"`
Os sql.NullString `json:"os"`
Kernel sql.NullString `json:"kernel"`
Architecture sql.NullString `json:"architecture"`
}
func (q *Queries) ListNodeMetrics(ctx context.Context, arg ListNodeMetricsParams) ([]ListNodeMetricsRow, error) {
rows, err := q.db.QueryContext(ctx, listNodeMetrics, arg.NodeID, arg.Timestamp, arg.Timestamp_2)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListNodeMetricsRow{}
for rows.Next() {
var i ListNodeMetricsRow
if err := rows.Scan(
&i.NodeID,
&i.Timestamp,
&i.CpuUsage,
&i.CpuCores,
&i.LoadAvg1,
&i.LoadAvg5,
&i.LoadAvg15,
&i.MemoryTotal,
&i.MemoryUsed,
&i.MemoryAvailable,
&i.MemoryUsagePercent,
&i.StorageTotal,
&i.StorageUsed,
&i.StorageAvailable,
&i.StorageUsagePercent,
&i.NetworkBytesIn,
&i.NetworkBytesOut,
&i.NetworkPacketsIn,
&i.NetworkPacketsOut,
&i.NetworkConnectionsIn,
&i.NetworkConnectionsOut,
&i.NetworkErrorsIn,
&i.NetworkErrorsOut,
&i.UptimeSeconds,
&i.Processes,
&i.Os,
&i.Kernel,
&i.Architecture,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listServiceMetrics = `-- name: ListServiceMetrics :many
SELECT service_id, service_name, project_id, timestamp,
requests_total, requests_success, requests_errors, requests_avg_latency,
requests_p95_latency, requests_p99_latency, requests_throughput,
errors_total, errors_rate, performance_response_time, performance_throughput,
performance_concurrency, performance_saturation, performance_utilization,
resource_cpu_usage, resource_memory_usage, resource_storage_usage,
resource_network_usage, resource_score
FROM service_metrics
WHERE service_id = $1 AND timestamp BETWEEN $2 AND $3
ORDER BY timestamp ASC
`
type ListServiceMetricsParams struct {
ServiceID string `json:"service_id"`
Timestamp time.Time `json:"timestamp"`
Timestamp_2 time.Time `json:"timestamp_2"`
}
type ListServiceMetricsRow struct {
ServiceID string `json:"service_id"`
ServiceName string `json:"service_name"`
ProjectID string `json:"project_id"`
Timestamp time.Time `json:"timestamp"`
RequestsTotal sql.NullInt64 `json:"requests_total"`
RequestsSuccess sql.NullInt64 `json:"requests_success"`
RequestsErrors sql.NullInt64 `json:"requests_errors"`
RequestsAvgLatency sql.NullString `json:"requests_avg_latency"`
RequestsP95Latency sql.NullString `json:"requests_p95_latency"`
RequestsP99Latency sql.NullString `json:"requests_p99_latency"`
RequestsThroughput sql.NullString `json:"requests_throughput"`
ErrorsTotal sql.NullInt64 `json:"errors_total"`
ErrorsRate sql.NullString `json:"errors_rate"`
PerformanceResponseTime sql.NullString `json:"performance_response_time"`
PerformanceThroughput sql.NullString `json:"performance_throughput"`
PerformanceConcurrency sql.NullInt64 `json:"performance_concurrency"`
PerformanceSaturation sql.NullString `json:"performance_saturation"`
PerformanceUtilization sql.NullString `json:"performance_utilization"`
ResourceCpuUsage sql.NullString `json:"resource_cpu_usage"`
ResourceMemoryUsage sql.NullInt64 `json:"resource_memory_usage"`
ResourceStorageUsage sql.NullInt64 `json:"resource_storage_usage"`
ResourceNetworkUsage sql.NullInt64 `json:"resource_network_usage"`
ResourceScore sql.NullString `json:"resource_score"`
}
func (q *Queries) ListServiceMetrics(ctx context.Context, arg ListServiceMetricsParams) ([]ListServiceMetricsRow, error) {
rows, err := q.db.QueryContext(ctx, listServiceMetrics, arg.ServiceID, arg.Timestamp, arg.Timestamp_2)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListServiceMetricsRow{}
for rows.Next() {
var i ListServiceMetricsRow
if err := rows.Scan(
&i.ServiceID,
&i.ServiceName,
&i.ProjectID,
&i.Timestamp,
&i.RequestsTotal,
&i.RequestsSuccess,
&i.RequestsErrors,
&i.RequestsAvgLatency,
&i.RequestsP95Latency,
&i.RequestsP99Latency,
&i.RequestsThroughput,
&i.ErrorsTotal,
&i.ErrorsRate,
&i.PerformanceResponseTime,
&i.PerformanceThroughput,
&i.PerformanceConcurrency,
&i.PerformanceSaturation,
&i.PerformanceUtilization,
&i.ResourceCpuUsage,
&i.ResourceMemoryUsage,
&i.ResourceStorageUsage,
&i.ResourceNetworkUsage,
&i.ResourceScore,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const upsertInstanceMetrics = `-- name: UpsertInstanceMetrics :exec
INSERT INTO instance_metrics (
service_id, timestamp, instance_id, node_id, status, cpu, memory,
network_bytes_in, network_bytes_out, network_packets_in, network_packets_out,
network_connections_in, network_connections_out, network_errors_in, network_errors_out,
start_time, last_seen, health_status, health_last_check, health_check_count, health_failure_count
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15,
$16, $17, $18, $19, $20, $21
)
ON CONFLICT (service_id, timestamp, instance_id) DO UPDATE SET
node_id = EXCLUDED.node_id,
status = EXCLUDED.status,
cpu = EXCLUDED.cpu,
memory = EXCLUDED.memory,
network_bytes_in = EXCLUDED.network_bytes_in,
network_bytes_out = EXCLUDED.network_bytes_out,
network_packets_in = EXCLUDED.network_packets_in,
network_packets_out = EXCLUDED.network_packets_out,
network_connections_in = EXCLUDED.network_connections_in,
network_connections_out = EXCLUDED.network_connections_out,
network_errors_in = EXCLUDED.network_errors_in,
network_errors_out = EXCLUDED.network_errors_out,
start_time = EXCLUDED.start_time,
last_seen = EXCLUDED.last_seen,
health_status = EXCLUDED.health_status,
health_last_check = EXCLUDED.health_last_check,
health_check_count = EXCLUDED.health_check_count,
health_failure_count = EXCLUDED.health_failure_count
`
type UpsertInstanceMetricsParams struct {
ServiceID string `json:"service_id"`
Timestamp time.Time `json:"timestamp"`
InstanceID string `json:"instance_id"`
NodeID sql.NullString `json:"node_id"`
Status sql.NullString `json:"status"`
Cpu sql.NullString `json:"cpu"`
Memory sql.NullInt64 `json:"memory"`
NetworkBytesIn sql.NullInt64 `json:"network_bytes_in"`
NetworkBytesOut sql.NullInt64 `json:"network_bytes_out"`
NetworkPacketsIn sql.NullInt64 `json:"network_packets_in"`
NetworkPacketsOut sql.NullInt64 `json:"network_packets_out"`
NetworkConnectionsIn sql.NullInt32 `json:"network_connections_in"`
NetworkConnectionsOut sql.NullInt32 `json:"network_connections_out"`
NetworkErrorsIn sql.NullInt64 `json:"network_errors_in"`
NetworkErrorsOut sql.NullInt64 `json:"network_errors_out"`
StartTime sql.NullTime `json:"start_time"`
LastSeen sql.NullTime `json:"last_seen"`
HealthStatus sql.NullString `json:"health_status"`
HealthLastCheck sql.NullTime `json:"health_last_check"`
HealthCheckCount sql.NullInt32 `json:"health_check_count"`
HealthFailureCount sql.NullInt32 `json:"health_failure_count"`
}
func (q *Queries) UpsertInstanceMetrics(ctx context.Context, arg UpsertInstanceMetricsParams) error {
_, err := q.db.ExecContext(ctx, upsertInstanceMetrics,
arg.ServiceID,
arg.Timestamp,
arg.InstanceID,
arg.NodeID,
arg.Status,
arg.Cpu,
arg.Memory,
arg.NetworkBytesIn,
arg.NetworkBytesOut,
arg.NetworkPacketsIn,
arg.NetworkPacketsOut,
arg.NetworkConnectionsIn,
arg.NetworkConnectionsOut,
arg.NetworkErrorsIn,
arg.NetworkErrorsOut,
arg.StartTime,
arg.LastSeen,
arg.HealthStatus,
arg.HealthLastCheck,
arg.HealthCheckCount,
arg.HealthFailureCount,
)
return err
}
const upsertNodeMetrics = `-- name: UpsertNodeMetrics :exec
INSERT INTO node_metrics (
node_id, timestamp, cpu_usage, cpu_cores, load_avg_1, load_avg_5, load_avg_15,
memory_total, memory_used, memory_available, memory_usage_percent,
storage_total, storage_used, storage_available, storage_usage_percent,
network_bytes_in, network_bytes_out, network_packets_in, network_packets_out,
network_connections_in, network_connections_out, network_errors_in, network_errors_out,
uptime, processes, os, kernel, architecture
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15,
$16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28
)
ON CONFLICT (node_id, timestamp) DO UPDATE SET
cpu_usage = EXCLUDED.cpu_usage,
cpu_cores = EXCLUDED.cpu_cores,
load_avg_1 = EXCLUDED.load_avg_1,
load_avg_5 = EXCLUDED.load_avg_5,
load_avg_15 = EXCLUDED.load_avg_15,
memory_total = EXCLUDED.memory_total,
memory_used = EXCLUDED.memory_used,
memory_available = EXCLUDED.memory_available,
memory_usage_percent = EXCLUDED.memory_usage_percent,
storage_total = EXCLUDED.storage_total,
storage_used = EXCLUDED.storage_used,
storage_available = EXCLUDED.storage_available,
storage_usage_percent = EXCLUDED.storage_usage_percent,
network_bytes_in = EXCLUDED.network_bytes_in,
network_bytes_out = EXCLUDED.network_bytes_out,
network_packets_in = EXCLUDED.network_packets_in,
network_packets_out = EXCLUDED.network_packets_out,
network_connections_in = EXCLUDED.network_connections_in,
network_connections_out = EXCLUDED.network_connections_out,
network_errors_in = EXCLUDED.network_errors_in,
network_errors_out = EXCLUDED.network_errors_out,
uptime = EXCLUDED.uptime,
processes = EXCLUDED.processes,
os = EXCLUDED.os,
kernel = EXCLUDED.kernel,
architecture = EXCLUDED.architecture
`
type UpsertNodeMetricsParams struct {
NodeID string `json:"node_id"`
Timestamp time.Time `json:"timestamp"`
CpuUsage sql.NullString `json:"cpu_usage"`
CpuCores sql.NullString `json:"cpu_cores"`
LoadAvg1 sql.NullString `json:"load_avg_1"`
LoadAvg5 sql.NullString `json:"load_avg_5"`
LoadAvg15 sql.NullString `json:"load_avg_15"`
MemoryTotal sql.NullInt64 `json:"memory_total"`
MemoryUsed sql.NullInt64 `json:"memory_used"`
MemoryAvailable sql.NullInt64 `json:"memory_available"`
MemoryUsagePercent sql.NullString `json:"memory_usage_percent"`
StorageTotal sql.NullInt64 `json:"storage_total"`
StorageUsed sql.NullInt64 `json:"storage_used"`
StorageAvailable sql.NullInt64 `json:"storage_available"`
StorageUsagePercent sql.NullString `json:"storage_usage_percent"`
NetworkBytesIn sql.NullInt64 `json:"network_bytes_in"`
NetworkBytesOut sql.NullInt64 `json:"network_bytes_out"`
NetworkPacketsIn sql.NullInt64 `json:"network_packets_in"`
NetworkPacketsOut sql.NullInt64 `json:"network_packets_out"`
NetworkConnectionsIn sql.NullInt32 `json:"network_connections_in"`
NetworkConnectionsOut sql.NullInt32 `json:"network_connections_out"`
NetworkErrorsIn sql.NullInt64 `json:"network_errors_in"`
NetworkErrorsOut sql.NullInt64 `json:"network_errors_out"`
Uptime sql.NullInt64 `json:"uptime"`
Processes sql.NullInt32 `json:"processes"`
Os sql.NullString `json:"os"`
Kernel sql.NullString `json:"kernel"`
Architecture sql.NullString `json:"architecture"`
}
func (q *Queries) UpsertNodeMetrics(ctx context.Context, arg UpsertNodeMetricsParams) error {
_, err := q.db.ExecContext(ctx, upsertNodeMetrics,
arg.NodeID,
arg.Timestamp,
arg.CpuUsage,
arg.CpuCores,
arg.LoadAvg1,
arg.LoadAvg5,
arg.LoadAvg15,
arg.MemoryTotal,
arg.MemoryUsed,
arg.MemoryAvailable,
arg.MemoryUsagePercent,
arg.StorageTotal,
arg.StorageUsed,
arg.StorageAvailable,
arg.StorageUsagePercent,
arg.NetworkBytesIn,
arg.NetworkBytesOut,
arg.NetworkPacketsIn,
arg.NetworkPacketsOut,
arg.NetworkConnectionsIn,
arg.NetworkConnectionsOut,
arg.NetworkErrorsIn,
arg.NetworkErrorsOut,
arg.Uptime,
arg.Processes,
arg.Os,
arg.Kernel,
arg.Architecture,
)
return err
}
const upsertServiceMetrics = `-- name: UpsertServiceMetrics :exec
INSERT INTO service_metrics (
service_id, service_name, project_id, timestamp,
requests_total, requests_success, requests_errors, requests_avg_latency,
requests_p95_latency, requests_p99_latency, requests_throughput,
errors_total, errors_rate, performance_response_time, performance_throughput,
performance_concurrency, performance_saturation, performance_utilization,
resource_cpu_usage, resource_memory_usage, resource_storage_usage,
resource_network_usage, resource_score
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15,
$16, $17, $18, $19, $20, $21, $22, $23
)
ON CONFLICT (service_id, timestamp) DO UPDATE SET
requests_total = EXCLUDED.requests_total,
requests_success = EXCLUDED.requests_success,
requests_errors = EXCLUDED.requests_errors,
requests_avg_latency = EXCLUDED.requests_avg_latency,
requests_p95_latency = EXCLUDED.requests_p95_latency,
requests_p99_latency = EXCLUDED.requests_p99_latency,
requests_throughput = EXCLUDED.requests_throughput,
errors_total = EXCLUDED.errors_total,
errors_rate = EXCLUDED.errors_rate,
performance_response_time = EXCLUDED.performance_response_time,
performance_throughput = EXCLUDED.performance_throughput,
performance_concurrency = EXCLUDED.performance_concurrency,
performance_saturation = EXCLUDED.performance_saturation,
performance_utilization = EXCLUDED.performance_utilization,
resource_cpu_usage = EXCLUDED.resource_cpu_usage,
resource_memory_usage = EXCLUDED.resource_memory_usage,
resource_storage_usage = EXCLUDED.resource_storage_usage,
resource_network_usage = EXCLUDED.resource_network_usage,
resource_score = EXCLUDED.resource_score
`
type UpsertServiceMetricsParams struct {
ServiceID string `json:"service_id"`
ServiceName string `json:"service_name"`
ProjectID string `json:"project_id"`
Timestamp time.Time `json:"timestamp"`
RequestsTotal sql.NullInt64 `json:"requests_total"`
RequestsSuccess sql.NullInt64 `json:"requests_success"`
RequestsErrors sql.NullInt64 `json:"requests_errors"`
RequestsAvgLatency sql.NullString `json:"requests_avg_latency"`
RequestsP95Latency sql.NullString `json:"requests_p95_latency"`
RequestsP99Latency sql.NullString `json:"requests_p99_latency"`
RequestsThroughput sql.NullString `json:"requests_throughput"`
ErrorsTotal sql.NullInt64 `json:"errors_total"`
ErrorsRate sql.NullString `json:"errors_rate"`
PerformanceResponseTime sql.NullString `json:"performance_response_time"`
PerformanceThroughput sql.NullString `json:"performance_throughput"`
PerformanceConcurrency sql.NullInt64 `json:"performance_concurrency"`
PerformanceSaturation sql.NullString `json:"performance_saturation"`
PerformanceUtilization sql.NullString `json:"performance_utilization"`
ResourceCpuUsage sql.NullString `json:"resource_cpu_usage"`
ResourceMemoryUsage sql.NullInt64 `json:"resource_memory_usage"`
ResourceStorageUsage sql.NullInt64 `json:"resource_storage_usage"`
ResourceNetworkUsage sql.NullInt64 `json:"resource_network_usage"`
ResourceScore sql.NullString `json:"resource_score"`
}
func (q *Queries) UpsertServiceMetrics(ctx context.Context, arg UpsertServiceMetricsParams) error {
_, err := q.db.ExecContext(ctx, upsertServiceMetrics,
arg.ServiceID,
arg.ServiceName,
arg.ProjectID,
arg.Timestamp,
arg.RequestsTotal,
arg.RequestsSuccess,
arg.RequestsErrors,
arg.RequestsAvgLatency,
arg.RequestsP95Latency,
arg.RequestsP99Latency,
arg.RequestsThroughput,
arg.ErrorsTotal,
arg.ErrorsRate,
arg.PerformanceResponseTime,
arg.PerformanceThroughput,
arg.PerformanceConcurrency,
arg.PerformanceSaturation,
arg.PerformanceUtilization,
arg.ResourceCpuUsage,
arg.ResourceMemoryUsage,
arg.ResourceStorageUsage,
arg.ResourceNetworkUsage,
arg.ResourceScore,
)
return err
}
@@ -161,6 +161,31 @@ type EnvironmentVariable struct {
UpdatedAt sql.NullTime `json:"updated_at"`
}
type InstanceMetric struct {
ServiceID string `json:"service_id"`
Timestamp time.Time `json:"timestamp"`
InstanceID string `json:"instance_id"`
NodeID sql.NullString `json:"node_id"`
Status sql.NullString `json:"status"`
Cpu sql.NullString `json:"cpu"`
Memory sql.NullInt64 `json:"memory"`
NetworkBytesIn sql.NullInt64 `json:"network_bytes_in"`
NetworkBytesOut sql.NullInt64 `json:"network_bytes_out"`
NetworkPacketsIn sql.NullInt64 `json:"network_packets_in"`
NetworkPacketsOut sql.NullInt64 `json:"network_packets_out"`
NetworkConnectionsIn sql.NullInt32 `json:"network_connections_in"`
NetworkConnectionsOut sql.NullInt32 `json:"network_connections_out"`
NetworkErrorsIn sql.NullInt64 `json:"network_errors_in"`
NetworkErrorsOut sql.NullInt64 `json:"network_errors_out"`
StartTime sql.NullTime `json:"start_time"`
LastSeen sql.NullTime `json:"last_seen"`
HealthStatus sql.NullString `json:"health_status"`
HealthLastCheck sql.NullTime `json:"health_last_check"`
HealthCheckCount sql.NullInt32 `json:"health_check_count"`
HealthFailureCount sql.NullInt32 `json:"health_failure_count"`
CreatedAt sql.NullTime `json:"created_at"`
}
type NodeAgent struct {
ID string `json:"id"`
Name string `json:"name"`
@@ -181,6 +206,38 @@ type NodeAgent struct {
DefaultDomain string `json:"default_domain"`
}
type NodeMetric struct {
NodeID string `json:"node_id"`
Timestamp time.Time `json:"timestamp"`
CpuUsage sql.NullString `json:"cpu_usage"`
CpuCores sql.NullString `json:"cpu_cores"`
LoadAvg1 sql.NullString `json:"load_avg_1"`
LoadAvg5 sql.NullString `json:"load_avg_5"`
LoadAvg15 sql.NullString `json:"load_avg_15"`
MemoryTotal sql.NullInt64 `json:"memory_total"`
MemoryUsed sql.NullInt64 `json:"memory_used"`
MemoryAvailable sql.NullInt64 `json:"memory_available"`
MemoryUsagePercent sql.NullString `json:"memory_usage_percent"`
StorageTotal sql.NullInt64 `json:"storage_total"`
StorageUsed sql.NullInt64 `json:"storage_used"`
StorageAvailable sql.NullInt64 `json:"storage_available"`
StorageUsagePercent sql.NullString `json:"storage_usage_percent"`
NetworkBytesIn sql.NullInt64 `json:"network_bytes_in"`
NetworkBytesOut sql.NullInt64 `json:"network_bytes_out"`
NetworkPacketsIn sql.NullInt64 `json:"network_packets_in"`
NetworkPacketsOut sql.NullInt64 `json:"network_packets_out"`
NetworkConnectionsIn sql.NullInt32 `json:"network_connections_in"`
NetworkConnectionsOut sql.NullInt32 `json:"network_connections_out"`
NetworkErrorsIn sql.NullInt64 `json:"network_errors_in"`
NetworkErrorsOut sql.NullInt64 `json:"network_errors_out"`
Uptime sql.NullInt64 `json:"uptime"`
Processes sql.NullInt32 `json:"processes"`
Os sql.NullString `json:"os"`
Kernel sql.NullString `json:"kernel"`
Architecture sql.NullString `json:"architecture"`
CreatedAt sql.NullTime `json:"created_at"`
}
type Notification struct {
ID uuid.UUID `json:"id"`
UserID uuid.UUID `json:"user_id"`
@@ -305,6 +362,33 @@ type ServiceDomain struct {
CreatedAt time.Time `json:"created_at"`
}
type ServiceMetric struct {
ServiceID string `json:"service_id"`
ServiceName string `json:"service_name"`
ProjectID string `json:"project_id"`
Timestamp time.Time `json:"timestamp"`
RequestsTotal sql.NullInt64 `json:"requests_total"`
RequestsSuccess sql.NullInt64 `json:"requests_success"`
RequestsErrors sql.NullInt64 `json:"requests_errors"`
RequestsAvgLatency sql.NullString `json:"requests_avg_latency"`
RequestsP95Latency sql.NullString `json:"requests_p95_latency"`
RequestsP99Latency sql.NullString `json:"requests_p99_latency"`
RequestsThroughput sql.NullString `json:"requests_throughput"`
ErrorsTotal sql.NullInt64 `json:"errors_total"`
ErrorsRate sql.NullString `json:"errors_rate"`
PerformanceResponseTime sql.NullString `json:"performance_response_time"`
PerformanceThroughput sql.NullString `json:"performance_throughput"`
PerformanceConcurrency sql.NullInt64 `json:"performance_concurrency"`
PerformanceSaturation sql.NullString `json:"performance_saturation"`
PerformanceUtilization sql.NullString `json:"performance_utilization"`
ResourceCpuUsage sql.NullString `json:"resource_cpu_usage"`
ResourceMemoryUsage sql.NullInt64 `json:"resource_memory_usage"`
ResourceStorageUsage sql.NullInt64 `json:"resource_storage_usage"`
ResourceNetworkUsage sql.NullInt64 `json:"resource_network_usage"`
ResourceScore sql.NullString `json:"resource_score"`
CreatedAt sql.NullTime `json:"created_at"`
}
type ServiceTemplate struct {
ID string `json:"id"`
Name string `json:"name"`
@@ -13,12 +13,17 @@ import (
)
type Querier interface {
// Portable bucket bucketing (no TimescaleDB): floor epoch seconds into
// bucket-sized buckets, then back to timestamptz.
AggregateNodeMetrics(ctx context.Context, arg AggregateNodeMetricsParams) ([]AggregateNodeMetricsRow, error)
ClearServiceDomainDefault(ctx context.Context, serviceID uuid.UUID) error
ClearServiceNodePins(ctx context.Context, nodeID sql.NullString) (int64, error)
CompleteCommand(ctx context.Context, arg CompleteCommandParams) (AgentCommand, error)
CountDatabaseServicesByUserAndName(ctx context.Context, arg CountDatabaseServicesByUserAndNameParams) (int64, error)
CountDatabasesUsingBackupTarget(ctx context.Context, targetID sql.NullString) (int64, error)
CountEnvironmentServices(ctx context.Context, environmentID uuid.UUID) (int64, error)
CountProjectsByUser(ctx context.Context, arg CountProjectsByUserParams) (int64, error)
CountServiceDomains(ctx context.Context, serviceID uuid.UUID) (int64, error)
CountServicesByProjectAndName(ctx context.Context, arg CountServicesByProjectAndNameParams) (int64, error)
CountUnreadNotificationsByUser(ctx context.Context, userID uuid.UUID) (int64, error)
CreateAgent(ctx context.Context, arg CreateAgentParams) (NodeAgent, error)
@@ -33,6 +38,7 @@ type Querier interface {
CreateNotification(ctx context.Context, arg CreateNotificationParams) error
CreateOutboundWebhook(ctx context.Context, arg CreateOutboundWebhookParams) error
CreateProject(ctx context.Context, arg CreateProjectParams) (Project, error)
CreateServiceDomain(ctx context.Context, arg CreateServiceDomainParams) (CreateServiceDomainRow, error)
CreateServiceFromTemplate(ctx context.Context, arg CreateServiceFromTemplateParams) error
CreateUserInvite(ctx context.Context, arg CreateUserInviteParams) (UserInvite, error)
CreateUserTemplate(ctx context.Context, arg CreateUserTemplateParams) error
@@ -49,6 +55,7 @@ type Querier interface {
DeleteProjectByID(ctx context.Context, projectID uuid.UUID) (int64, error)
DeleteProjectEnvironment(ctx context.Context, arg DeleteProjectEnvironmentParams) error
DeleteServiceContainersOnAgent(ctx context.Context, arg DeleteServiceContainersOnAgentParams) error
DeleteServiceDomain(ctx context.Context, arg DeleteServiceDomainParams) (int64, error)
DeleteUserInvite(ctx context.Context, id uuid.UUID) error
DeleteUserTemplate(ctx context.Context, arg DeleteUserTemplateParams) (int64, error)
GetActiveAgentAuthTokenByHash(ctx context.Context, tokenHash string) (AgentAuthToken, error)
@@ -72,6 +79,10 @@ type Querier interface {
GetProjectOwnerByID(ctx context.Context, projectID uuid.UUID) (uuid.UUID, error)
GetProjectOwnerID(ctx context.Context, id uuid.UUID) (uuid.UUID, error)
GetProjectRoleForUser(ctx context.Context, arg GetProjectRoleForUserParams) (string, error)
GetServiceAccess(ctx context.Context, id uuid.UUID) (GetServiceAccessRow, error)
GetServiceDomainDefault(ctx context.Context, serviceID uuid.UUID) (string, error)
GetServiceDomainFirst(ctx context.Context, serviceID uuid.UUID) (string, error)
GetServicePlacementBrief(ctx context.Context, id uuid.UUID) (GetServicePlacementBriefRow, error)
GetServiceTemplateByID(ctx context.Context, id string) (ServiceTemplate, error)
GetUserInviteByTokenHash(ctx context.Context, tokenHash string) (UserInvite, error)
GetUserTokenByHash(ctx context.Context, tokenHash string) (UserToken, error)
@@ -93,6 +104,8 @@ type Querier interface {
ListDatabaseServicesByUser(ctx context.Context, userID string) ([]DatabaseService, error)
ListDueDatabaseBackups(ctx context.Context) ([]ListDueDatabaseBackupsRow, error)
ListEnabledOutboundWebhooks(ctx context.Context) ([]OutboundWebhook, error)
ListInstanceMetrics(ctx context.Context, arg ListInstanceMetricsParams) ([]ListInstanceMetricsRow, error)
ListNodeMetrics(ctx context.Context, arg ListNodeMetricsParams) ([]ListNodeMetricsRow, error)
ListNotificationChannelsByUser(ctx context.Context, userID uuid.UUID) ([]NotificationChannel, error)
ListNotificationsByUser(ctx context.Context, arg ListNotificationsByUserParams) ([]Notification, error)
ListOutboundWebhooksByUser(ctx context.Context, userID uuid.UUID) ([]OutboundWebhook, error)
@@ -112,6 +125,8 @@ type Querier interface {
// Distinct agents holding inventory rows for a service.
ListServiceAgents(ctx context.Context, serviceID string) ([]string, error)
ListServiceContainers(ctx context.Context, serviceID string) ([]ListServiceContainersRow, error)
ListServiceDomains(ctx context.Context, serviceID uuid.UUID) ([]ServiceDomain, error)
ListServiceMetrics(ctx context.Context, arg ListServiceMetricsParams) ([]ListServiceMetricsRow, error)
ListServiceTemplatesByCategoryForUser(ctx context.Context, arg ListServiceTemplatesByCategoryForUserParams) ([]ServiceTemplate, error)
ListServiceTemplatesForUser(ctx context.Context, ownerID uuid.NullUUID) ([]ServiceTemplate, error)
ListUserInvites(ctx context.Context) ([]UserInvite, error)
@@ -129,6 +144,7 @@ type Querier interface {
RevokeAgentAuthToken(ctx context.Context, id uuid.UUID) (AgentAuthToken, error)
RevokeUserToken(ctx context.Context, arg RevokeUserTokenParams) (int64, error)
ScrubCommandPayload(ctx context.Context, arg ScrubCommandPayloadParams) error
ServiceWriteAccess(ctx context.Context, arg ServiceWriteAccessParams) (bool, error)
SetAgentDefaultDomain(ctx context.Context, arg SetAgentDefaultDomainParams) error
SetAgentSchedulable(ctx context.Context, arg SetAgentSchedulableParams) error
SetAgentTags(ctx context.Context, arg SetAgentTagsParams) error
@@ -142,7 +158,10 @@ type Querier interface {
SetDatabaseServiceStatusByID(ctx context.Context, arg SetDatabaseServiceStatusByIDParams) error
SetDatabaseServiceStatusByIDAndUser(ctx context.Context, arg SetDatabaseServiceStatusByIDAndUserParams) error
SetProjectApproved(ctx context.Context, arg SetProjectApprovedParams) (int64, error)
SetServiceDomainDefault(ctx context.Context, arg SetServiceDomainDefaultParams) (int64, error)
SetServiceLegacyDomain(ctx context.Context, arg SetServiceLegacyDomainParams) error
TouchAgentAuthToken(ctx context.Context, tokenHash string) error
TouchServiceDomainChecked(ctx context.Context, id uuid.UUID) error
TouchUserToken(ctx context.Context, id uuid.UUID) error
UpdateAgent(ctx context.Context, arg UpdateAgentParams) (NodeAgent, error)
UpdateAgentHeartbeat(ctx context.Context, arg UpdateAgentHeartbeatParams) error
@@ -164,7 +183,10 @@ type Querier interface {
UpdateUserTemplate(ctx context.Context, arg UpdateUserTemplateParams) (int64, error)
UpdateWebhookDeliveryResult(ctx context.Context, arg UpdateWebhookDeliveryResultParams) error
UpsertEnvironmentVariable(ctx context.Context, arg UpsertEnvironmentVariableParams) error
UpsertInstanceMetrics(ctx context.Context, arg UpsertInstanceMetricsParams) error
UpsertNodeMetrics(ctx context.Context, arg UpsertNodeMetricsParams) error
UpsertServiceContainer(ctx context.Context, arg UpsertServiceContainerParams) error
UpsertServiceMetrics(ctx context.Context, arg UpsertServiceMetricsParams) error
UpsertServiceTemplate(ctx context.Context, arg UpsertServiceTemplateParams) error
}