analytics

package
v0.0.0-...-b47dbfd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: OSL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package analytics provides the scheduled collector for savings time-series data.

Index

Constants

View Source
const (
	// HoursPerYear is the approximate number of hours in a year (365 days).
	HoursPerYear = 365 * 24

	// MonthsPerYear amortizes an upfront commitment cost into a monthly run-rate
	// over the commitment term (term is expressed in years).
	MonthsPerYear = 12
)

Constants for time calculations.

Variables

This section is empty.

Functions

This section is empty.

Types

type AnalyticsStore

type AnalyticsStore interface {
	// SaveSnapshot stores a single savings snapshot.
	SaveSnapshot(ctx context.Context, snapshot *SavingsSnapshot) error

	// BulkInsertSnapshots inserts multiple snapshots efficiently.
	BulkInsertSnapshots(ctx context.Context, snapshots []SavingsSnapshot) error

	// QuerySavings retrieves savings snapshots based on query parameters.
	QuerySavings(ctx context.Context, req QueryRequest) ([]SavingsSnapshot, error)

	// Aggregated queries (using materialized views for performance). Scoping is
	// the dual-column model; pass empty filters only after enforcing scope.
	QueryMonthlyTotals(ctx context.Context, accountUUIDs []string, accountExternalIDsByProvider map[string][]string, months int) ([]MonthlySummary, error)
	QueryByProvider(ctx context.Context, accountUUIDs []string, accountExternalIDsByProvider map[string][]string, startDate, endDate time.Time) ([]ProviderBreakdown, error)
	QueryByService(ctx context.Context, accountUUIDs []string, accountExternalIDsByProvider map[string][]string, provider string, startDate, endDate time.Time) ([]ServiceBreakdown, error)

	// Partition management.
	CreatePartition(ctx context.Context, forMonth time.Time) error
	CreateFuturePartitions(ctx context.Context, monthsAhead int) error
	DropOldPartitions(ctx context.Context, retentionMonths int) error
	CreatePartitionsForRange(ctx context.Context, startDate, endDate time.Time) error

	// Materialized view management.
	RefreshMaterializedViews(ctx context.Context) error

	// Close cleans up resources.
	Close() error
}

AnalyticsStore defines the interface for analytics storage.

type Collector

type Collector struct {
	// contains filtered or unexported fields
}

Collector aggregates savings data and writes point-in-time snapshots to PostgreSQL for the historical-savings analytics time-series. It runs on a schedule (see server.handleCollectAnalytics) across all tenants.

func NewCollector

func NewCollector(cfg CollectorConfig, configStore config.StoreInterface) (*Collector, error)

NewCollector creates a new savings collector.

func (*Collector) Collect

func (c *Collector) Collect(ctx context.Context) error

Collect aggregates current savings data across all tenants and writes a snapshot row per bucket. Intended to be called on a schedule.

type CollectorConfig

type CollectorConfig struct {
	AnalyticsStore AnalyticsStore
}

CollectorConfig holds configuration for the collector.

type MonthlySummary

type MonthlySummary struct {
	Month          time.Time `json:"month"`
	CloudAccountID *string   `json:"cloud_account_id,omitempty"`
	// AvgCoverage is the average reservation coverage for the month.
	// A nil value means coverage data is absent for this period and must
	// not be treated as zero coverage by consumers.
	AvgCoverage   *float64 `json:"avg_coverage,omitempty"`
	AccountID     string   `json:"account_id"`
	Provider      string   `json:"provider"`
	Service       string   `json:"service"`
	TotalSavings  float64  `json:"total_savings"`
	SnapshotCount int      `json:"snapshot_count"`
}

MonthlySummary represents aggregated monthly savings.

type PostgresAnalyticsStore

type PostgresAnalyticsStore struct {
	// contains filtered or unexported fields
}

PostgresAnalyticsStore implements AnalyticsStore using PostgreSQL.

func NewPostgresAnalyticsStore

func NewPostgresAnalyticsStore(db *database.Connection) *PostgresAnalyticsStore

NewPostgresAnalyticsStore creates a new PostgreSQL analytics store.

func (*PostgresAnalyticsStore) BulkInsertSnapshots

func (s *PostgresAnalyticsStore) BulkInsertSnapshots(ctx context.Context, snapshots []SavingsSnapshot) error

BulkInsertSnapshots inserts multiple snapshots efficiently via COPY.

func (*PostgresAnalyticsStore) Close

func (s *PostgresAnalyticsStore) Close() error

Close cleans up resources (no-op for PostgreSQL store).

func (*PostgresAnalyticsStore) CreateFuturePartitions

func (s *PostgresAnalyticsStore) CreateFuturePartitions(ctx context.Context, monthsAhead int) error

CreateFuturePartitions ensures partitions exist for the current month plus monthsAhead months ahead via the create_future_savings_partitions SQL helper.

func (*PostgresAnalyticsStore) CreatePartition

func (s *PostgresAnalyticsStore) CreatePartition(ctx context.Context, forMonth time.Time) error

CreatePartition creates a partition for a specific month.

func (*PostgresAnalyticsStore) CreatePartitionsForRange

func (s *PostgresAnalyticsStore) CreatePartitionsForRange(ctx context.Context, startDate, endDate time.Time) error

CreatePartitionsForRange creates partitions for each month in a date range (used during backfill / migration).

func (*PostgresAnalyticsStore) DropOldPartitions

func (s *PostgresAnalyticsStore) DropOldPartitions(ctx context.Context, retentionMonths int) error

DropOldPartitions removes partitions older than the retention period.

func (*PostgresAnalyticsStore) QueryByProvider

func (s *PostgresAnalyticsStore) QueryByProvider(ctx context.Context, accountUUIDs []string, accountExternalIDsByProvider map[string][]string, startDate, endDate time.Time) ([]ProviderBreakdown, error)

QueryByProvider retrieves savings breakdown by provider/service.

func (*PostgresAnalyticsStore) QueryByService

func (s *PostgresAnalyticsStore) QueryByService(ctx context.Context, accountUUIDs []string, accountExternalIDsByProvider map[string][]string, provider string, startDate, endDate time.Time) ([]ServiceBreakdown, error)

QueryByService retrieves savings breakdown by service/region, optionally filtered to a single provider. An empty provider returns all providers' services.

func (*PostgresAnalyticsStore) QueryMonthlyTotals

func (s *PostgresAnalyticsStore) QueryMonthlyTotals(ctx context.Context, accountUUIDs []string, accountExternalIDsByProvider map[string][]string, months int) ([]MonthlySummary, error)

QueryMonthlyTotals retrieves monthly aggregated totals for the last N months (inclusive of the current month). months <= 0 returns no rows.

func (*PostgresAnalyticsStore) QuerySavings

QuerySavings retrieves savings snapshots based on query parameters.

func (*PostgresAnalyticsStore) RefreshMaterializedViews

func (s *PostgresAnalyticsStore) RefreshMaterializedViews(ctx context.Context) error

RefreshMaterializedViews refreshes all analytics materialized views.

func (*PostgresAnalyticsStore) SaveSnapshot

func (s *PostgresAnalyticsStore) SaveSnapshot(ctx context.Context, snapshot *SavingsSnapshot) error

SaveSnapshot stores a single savings snapshot.

type ProviderBreakdown

type ProviderBreakdown struct {
	AvgCoverage  *float64 `json:"avg_coverage,omitempty"`
	Provider     string   `json:"provider"`
	Service      string   `json:"service"`
	TotalSavings float64  `json:"total_savings"`
}

ProviderBreakdown represents savings breakdown by provider.

type QueryRequest

type QueryRequest struct {
	StartDate                    time.Time
	EndDate                      time.Time
	AccountExternalIDsByProvider map[string][]string
	Provider                     string
	Service                      string
	AccountUUIDs                 []string
	Limit                        int
}

QueryRequest defines parameters for querying savings data.

Scoping uses the same dual-column model as the live purchase_history path: rows match when cloud_account_id = ANY(AccountUUIDs) OR (provider = p AND account_id = ANY(AccountExternalIDsByProvider[p])). Both nil/empty means "all accounts accessible to the caller" — the caller MUST enforce scoping upstream before passing empty filters.

type SavingsSnapshot

type SavingsSnapshot struct {
	Timestamp          time.Time      `json:"timestamp"`
	TotalUsage         *float64       `json:"total_usage,omitempty"`
	CloudAccountID     *string        `json:"cloud_account_id,omitempty"`
	CoveragePercentage *float64       `json:"coverage_percentage,omitempty"`
	Metadata           map[string]any `json:"metadata,omitempty"`
	AccountID          string         `json:"account_id"`
	Provider           string         `json:"provider"`
	Service            string         `json:"service"`
	Region             string         `json:"region"`
	CommitmentType     string         `json:"commitment_type"`
	ID                 string         `json:"id"`
	TotalCommitment    *float64       `json:"total_commitment"`
	TotalSavings       float64        `json:"total_savings"`
}

SavingsSnapshot represents a single savings data point.

Tenant key: CloudAccountID (the cloud_accounts UUID FK) is the multi-tenant scoping key, mirroring purchase_history / purchase_executions. AccountID is the cloud-provider external account string (AWS account number, Azure subscription id, GCP project id), kept as a descriptive attribute. A row may carry only one of them populated (CloudAccountID is NULL on the AWS ambient- credentials path and on legacy rows), so both are written when available.

type ServiceBreakdown

type ServiceBreakdown struct {
	AvgCoverage  *float64 `json:"avg_coverage,omitempty"`
	Service      string   `json:"service"`
	Region       string   `json:"region"`
	TotalSavings float64  `json:"total_savings"`
}

ServiceBreakdown represents savings breakdown by service.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL