goldfish

package
v3.7.4 Latest Latest
Warning

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

Go to latest
Published: Jul 22, 2026 License: AGPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package goldfish provides query sampling and comparison functionality for the querytee and Goldfish UI. It enables A/B testing between two query backends (cells) by sampling queries, comparing their responses (including performance metrics and content hashes), and persisting results for analysis. This package provides the data structures and SQL queries to persist and retrieve the results of this analysis.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIResponse

type APIResponse struct {
	Queries  []QuerySample `json:"queries"`
	HasMore  bool          `json:"hasMore"`
	Page     int           `json:"page"`
	PageSize int           `json:"pageSize"`
}

APIResponse represents the paginated API response for UI

type ComparisonResult

type ComparisonResult struct {
	CorrelationID        string
	ComparisonStatus     ComparisonStatus
	MatchWithinTolerance bool
	MismatchCause        string
	DifferenceDetails    map[string]any
	PerformanceMetrics   PerformanceMetrics
	ComparedAt           time.Time
}

ComparisonResult represents the outcome of comparing two responses

type ComparisonStatus

type ComparisonStatus string

ComparisonStatus represents the outcome of a comparison

const (
	ComparisonStatusMatch                ComparisonStatus = "match"
	ComparisonStatusMismatch             ComparisonStatus = "mismatch"
	ComparisonStatusError                ComparisonStatus = "error"
	ComparisonStatusPartial              ComparisonStatus = "partial"
	ComparisonStatusMatchWithinTolerance ComparisonStatus = "match_within_tolerance"
)

func (ComparisonStatus) IsValid added in v3.7.0

func (cs ComparisonStatus) IsValid() bool

IsValid checks if the ComparisonStatus value is valid

type MySQLStorage

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

MySQLStorage provides MySQL storage implementation

func NewMySQLStorage

func NewMySQLStorage(config StorageConfig, logger log.Logger) (*MySQLStorage, error)

NewMySQLStorage creates a new MySQL storage backend

func (*MySQLStorage) Close

func (s *MySQLStorage) Close() error

Close closes the storage connection

func (*MySQLStorage) GetQueryByCorrelationID added in v3.7.0

func (s *MySQLStorage) GetQueryByCorrelationID(ctx context.Context, correlationID string) (*QuerySample, error)

GetQueryByCorrelationID retrieves a single query sample by correlation ID

func (*MySQLStorage) GetSampledQueries

func (s *MySQLStorage) GetSampledQueries(ctx context.Context, page, pageSize int, filter QueryFilter) (*APIResponse, error)

GetSampledQueries retrieves sampled queries from the database with pagination and outcome filtering

func (*MySQLStorage) GetStatistics added in v3.7.0

func (s *MySQLStorage) GetStatistics(ctx context.Context, filter StatsFilter) (*Statistics, error)

GetStatistics retrieves aggregated statistics from the database

func (*MySQLStorage) StoreComparisonResult

func (s *MySQLStorage) StoreComparisonResult(ctx context.Context, result *ComparisonResult) error

StoreComparisonResult stores the outcome of comparing two responses

func (*MySQLStorage) StoreQuerySample

func (s *MySQLStorage) StoreQuerySample(ctx context.Context, sample *QuerySample, comparison *ComparisonResult) error

StoreQuerySample stores a sampled query with performance statistics

type NoopStorage

type NoopStorage struct{}

NoopStorage is a no-op implementation of the Storage interface

func NewNoopStorage

func NewNoopStorage() *NoopStorage

NewNoopStorage creates a new no-op storage backend

func (*NoopStorage) Close

func (n *NoopStorage) Close() error

Close is a no-op

func (*NoopStorage) GetQueryByCorrelationID added in v3.7.0

func (n *NoopStorage) GetQueryByCorrelationID(_ context.Context, _ string) (*QuerySample, error)

GetQueryByCorrelationID returns an error as goldfish is disabled

func (*NoopStorage) GetSampledQueries

func (n *NoopStorage) GetSampledQueries(_ context.Context, _, _ int, _ QueryFilter) (*APIResponse, error)

GetSampledQueries returns an error as goldfish is disabled

func (*NoopStorage) GetStatistics added in v3.7.0

func (n *NoopStorage) GetStatistics(_ context.Context, _ StatsFilter) (*Statistics, error)

GetStatistics returns an error as goldfish is disabled

func (*NoopStorage) StoreComparisonResult

func (n *NoopStorage) StoreComparisonResult(_ context.Context, _ *ComparisonResult) error

StoreComparisonResult is a no-op

func (*NoopStorage) StoreQuerySample

func (n *NoopStorage) StoreQuerySample(_ context.Context, _ *QuerySample, _ *ComparisonResult) error

StoreQuerySample is a no-op

type PerformanceMetrics

type PerformanceMetrics struct {
	CellAQueryTime  time.Duration
	CellBQueryTime  time.Duration
	QueryTimeRatio  float64
	CellABytesTotal int64
	CellBBytesTotal int64
	BytesRatio      float64
}

PerformanceMetrics contains performance comparison data

type QueryFilter

type QueryFilter struct {
	Tenant           string
	User             string
	IsLogsDrilldown  *bool // pointer to handle true/false/nil states
	UsedNewEngine    *bool // pointer to handle true/false/nil states
	ComparisonStatus ComparisonStatus
	From, To         time.Time
}

QueryFilter contains filters for querying sampled queries

type QuerySample

type QuerySample struct {
	CorrelationID   string        `json:"correlationId"`
	TenantID        string        `json:"tenantId"`
	User            string        `json:"user"`
	Issuer          string        `json:"issuer"`
	IsLogsDrilldown bool          `json:"isLogsDrilldown"`
	Query           string        `json:"query"`
	QueryType       string        `json:"queryType"`
	StartTime       time.Time     `json:"startTime"`
	EndTime         time.Time     `json:"endTime"`
	Step            time.Duration `json:"step"`

	// Performance statistics instead of raw responses
	CellAStats QueryStats `json:"cellAStats"`
	CellBStats QueryStats `json:"cellBStats"`

	// Response metadata without sensitive content
	CellAResponseHash string `json:"cellAResponseHash"`
	CellBResponseHash string `json:"cellBResponseHash"`
	CellAResponseSize int64  `json:"cellAResponseSize"`
	CellBResponseSize int64  `json:"cellBResponseSize"`
	CellAStatusCode   int    `json:"cellAStatusCode"`
	CellBStatusCode   int    `json:"cellBStatusCode"`
	CellATraceID      string `json:"cellATraceID"`
	CellBTraceID      string `json:"cellBTraceID"`
	CellASpanID       string `json:"cellASpanID"`
	CellBSpanID       string `json:"cellBSpanID"`

	// Result storage metadata
	CellAResultURI         string `json:"cellAResultURI"`
	CellBResultURI         string `json:"cellBResultURI"`
	CellAResultSize        int64  `json:"cellAResultSize"`
	CellBResultSize        int64  `json:"cellBResultSize"`
	CellAResultCompression string `json:"cellAResultCompression"`
	CellBResultCompression string `json:"cellBResultCompression"`

	// Query engine version tracking
	CellAUsedNewEngine bool `json:"cellAUsedNewEngine"`
	CellBUsedNewEngine bool `json:"cellBUsedNewEngine"`

	// Comparison outcome
	ComparisonStatus     ComparisonStatus `json:"comparisonStatus"`
	MatchWithinTolerance bool             `json:"matchWithinTolerance"`
	MismatchCause        string           `json:"mismatchCause,omitempty"` // Set when ComparisonStatus is mismatch

	SampledAt time.Time `json:"sampledAt"`
}

QuerySample represents a sampled query with performance stats from both cells

type QueryStats

type QueryStats struct {
	ExecTimeMs           int64 `json:"execTimeMs"`           // Execution time in milliseconds
	QueueTimeMs          int64 `json:"queueTimeMs"`          // Queue time in milliseconds
	BytesProcessed       int64 `json:"bytesProcessed"`       // Total bytes processed
	LinesProcessed       int64 `json:"linesProcessed"`       // Total lines processed
	BytesPerSecond       int64 `json:"bytesPerSecond"`       // Bytes processed per second
	LinesPerSecond       int64 `json:"linesPerSecond"`       // Lines processed per second
	TotalEntriesReturned int64 `json:"totalEntriesReturned"` // Number of result entries
	Splits               int64 `json:"splits"`               // Number of splits
	Shards               int64 `json:"shards"`               // Number of shards
}

QueryStats contains extracted performance statistics

type Statistics added in v3.7.0

type Statistics struct {
	QueriesExecuted       int64   `json:"queriesExecuted"`       // Count of queries executed with new engine
	EngineCoverage        float64 `json:"engineCoverage"`        // Ratio of queries using new engine
	MatchingQueries       float64 `json:"matchingQueries"`       // Ratio of queries with matching responses
	PerformanceDifference float64 `json:"performanceDifference"` // Geometric mean of performance ratio
}

Statistics contains aggregated statistics across sampled queries

type StatsFilter added in v3.7.0

type StatsFilter struct {
	From           time.Time
	To             time.Time
	UsesRecentData bool // When false, exclude queries that touch data within the last 3h
}

StatsFilter contains filters for statistics queries

type Storage

type Storage interface {
	// Write operations (used by querytee)
	StoreQuerySample(ctx context.Context, sample *QuerySample, comparison *ComparisonResult) error
	StoreComparisonResult(ctx context.Context, result *ComparisonResult) error

	// Read operations (used by UI)
	GetSampledQueries(ctx context.Context, page, pageSize int, filter QueryFilter) (*APIResponse, error)
	GetQueryByCorrelationID(ctx context.Context, correlationID string) (*QuerySample, error)
	GetStatistics(ctx context.Context, filter StatsFilter) (*Statistics, error)

	// Lifecycle
	Close() error
}

Storage defines the interface for storing and retrieving query samples and comparison results

type StorageConfig

type StorageConfig struct {
	Type string `yaml:"type"` // "cloudsql", "rds", "mysql", or empty string for no storage

	// Direct MySQL connection
	MySQLHost     string `yaml:"mysql_host"`
	MySQLPort     int    `yaml:"mysql_port"`
	MySQLDatabase string `yaml:"mysql_database"`
	MySQLUser     string `yaml:"mysql_user"`

	// CloudSQL specific (via proxy)
	CloudSQLHost     string `yaml:"cloudsql_host"`
	CloudSQLPort     int    `yaml:"cloudsql_port"`
	CloudSQLDatabase string `yaml:"cloudsql_database"`
	CloudSQLUser     string `yaml:"cloudsql_user"`

	// RDS specific
	RDSEndpoint string `yaml:"rds_endpoint"` // e.g., "mydb.123456789012.us-east-1.rds.amazonaws.com:3306"
	RDSDatabase string `yaml:"rds_database"`
	RDSUser     string `yaml:"rds_user"`

	// Common settings
	MaxConnections int `yaml:"max_connections"`
	MaxIdleTime    int `yaml:"max_idle_time_seconds"`
}

StorageConfig defines storage backend configuration

Jump to

Keyboard shortcuts

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