querytee

package
v3.7.1 Latest Latest
Warning

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

Go to latest
Published: Mar 26, 2026 License: AGPL-3.0 Imports: 41 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewSplittingHandler

func NewSplittingHandler(cfg SplittingHandlerConfig, logger log.Logger) (http.Handler, error)

Types

type BackendResponse

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

type ComparisonSummary

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

type FanOutHandler

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

FanOutHandler implements queryrangebase.Handler and fans out requests to multiple backends. It returns the preferred backend's response as soon as ready, while capturing remaining responses for goldfish comparison in the background.

func NewFanOutHandler

func NewFanOutHandler(cfg FanOutHandlerConfig) *FanOutHandler

NewFanOutHandler creates a new FanOutHandler.

func (*FanOutHandler) Do

Do implements queryrangebase.Handler. It fans out the request to all backends, returns the preferred backend's response, and captures remaining responses for goldfish comparison in the background.

func (*FanOutHandler) WithComparator

func (h *FanOutHandler) WithComparator(comparator comparator.ResponsesComparator) *FanOutHandler

WithComparator sets the response comparator.

func (*FanOutHandler) WithMetrics

func (h *FanOutHandler) WithMetrics(metrics *ProxyMetrics) *FanOutHandler

WithMetrics sets metrics for the handler.

type FanOutHandlerConfig

type FanOutHandlerConfig struct {
	Backends                      []*ProxyBackend
	Codec                         queryrangebase.Codec
	GoldfishManager               goldfish.Manager
	Logger                        log.Logger
	Metrics                       *ProxyMetrics
	RouteName                     string
	Comparator                    comparator.ResponsesComparator
	InstrumentCompares            bool
	RoutingMode                   RoutingMode
	RaceTolerance                 time.Duration
	AddRoutingDecisionsToWarnings bool
}

FanOutHandlerConfig holds configuration for creating a FanOutHandler.

type HandlerFactory

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

HandlerFactory creates the appropriate handler based on configuration.

func NewHandlerFactory

func NewHandlerFactory(cfg HandlerFactoryConfig) *HandlerFactory

NewHandlerFactory creates a new HandlerFactory.

func (*HandlerFactory) CreateHandler

func (f *HandlerFactory) CreateHandler(routeName string, comp comparator.ResponsesComparator) (http.Handler, error)

type HandlerFactoryConfig

type HandlerFactoryConfig struct {
	Backends                      []*ProxyBackend
	Codec                         queryrangebase.Codec
	GoldfishManager               goldfish.Manager
	InstrumentCompares            bool
	RoutingMode                   RoutingMode
	Logger                        log.Logger
	Metrics                       *ProxyMetrics
	RaceTolerance                 time.Duration
	SkipFanOutWhenNotSampling     bool
	SplitStart                    flagext.Time
	SplitLag                      time.Duration
	SplitRetentionDays            int64
	AddRoutingDecisionsToWarnings bool
}

HandlerFactoryConfig holds configuration for creating a HandlerFactory.

type InstrumentationServer

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

func NewInstrumentationServer

func NewInstrumentationServer(port int, registry *prometheus.Registry, logger log.Logger) *InstrumentationServer

NewInstrumentationServer returns a server exposing Prometheus metrics.

func (*InstrumentationServer) Start

func (s *InstrumentationServer) Start() error

Start the instrumentation server.

func (*InstrumentationServer) Stop

func (s *InstrumentationServer) Stop()

Stop closes the instrumentation server.

type NonDecodableResponse

type NonDecodableResponse struct {
	StatusCode int
	Body       []byte
}

NonDecodableResponse is a minimal response type used when returning errors. It satisfies the queryrangebase.Response interface, and allows the querytee to capture responses that would otherwise be lost.

func (*NonDecodableResponse) GetHeaders

GetHeaders implements queryrangebase.Response

func (*NonDecodableResponse) ProtoMessage

func (e *NonDecodableResponse) ProtoMessage()

ProtoMessage implements proto.Message

func (*NonDecodableResponse) Reset

func (e *NonDecodableResponse) Reset()

Reset implements proto.Message

func (*NonDecodableResponse) SetHeader

func (e *NonDecodableResponse) SetHeader(_, _ string)

SetHeader implements queryrangebase.Response

func (*NonDecodableResponse) String

func (e *NonDecodableResponse) String() string

String implements proto.Message

func (*NonDecodableResponse) WithHeaders

WithHeaders implements queryrangebase.Response

type Proxy

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

func NewProxy

func NewProxy(
	cfg ProxyConfig,
	logger log.Logger,
	readRoutes, writeRoutes []Route,
	registerer prometheus.Registerer,
) (*Proxy, error)

func (*Proxy) Await

func (p *Proxy) Await()

func (*Proxy) Endpoint

func (p *Proxy) Endpoint() string

func (*Proxy) Start

func (p *Proxy) Start() error

func (*Proxy) Stop

func (p *Proxy) Stop() error

type ProxyBackend

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

ProxyBackend holds the information of a single backend.

func NewProxyBackend

func NewProxyBackend(name string, endpoint *url.URL, timeout time.Duration, preferred ...bool) (*ProxyBackend, error)

NewProxyBackend makes a new ProxyBackend It accepts preferred booleans in the following order [v1, v2]. A backend can be v1Preferred, v2Preferred, or neither, but not both.

func (*ProxyBackend) Alias

func (b *ProxyBackend) Alias() string

Alias returns the backend alias label value for metrics. Returns "v1" for v1-preferred backends, "v2" for v2-preferred backends, or "other" for non-preferred backends.

func (*ProxyBackend) ForwardRequest

func (b *ProxyBackend) ForwardRequest(orig *http.Request, body io.ReadCloser) *BackendResponse

func (*ProxyBackend) WithFilter

func (b *ProxyBackend) WithFilter(f *regexp.Regexp) *ProxyBackend

type ProxyConfig

type ProxyConfig struct {
	ServerServicePort              int
	BackendEndpoints               string
	BackendReadTimeout             time.Duration
	CompareResponses               bool
	DisableBackendReadProxy        string
	ValueComparisonTolerance       float64
	UseRelativeError               bool
	PassThroughNonRegisteredRoutes bool
	SkipRecentSamples              time.Duration
	SkipSamplesBefore              flagext.Time
	RequestURLFilter               *regexp.Regexp
	InstrumentCompares             bool
	SkipFanOutWhenNotSampling      bool
	Goldfish                       goldfish.Config

	Routing RoutingConfig
}

func (*ProxyConfig) RegisterFlags

func (cfg *ProxyConfig) RegisterFlags(f *flag.FlagSet)

type ProxyEndpoint

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

func NewProxyEndpoint

func NewProxyEndpoint(
	backends []*ProxyBackend,
	routeName string,
	metrics *ProxyMetrics,
	logger log.Logger,
	comparator comparator.ResponsesComparator,
	instrumentCompares bool,
) *ProxyEndpoint

func (*ProxyEndpoint) ServeHTTP

func (p *ProxyEndpoint) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*ProxyEndpoint) WithGoldfish

func (p *ProxyEndpoint) WithGoldfish(manager goldfish.Manager) *ProxyEndpoint

WithGoldfish adds Goldfish manager to the endpoint.

func (*ProxyEndpoint) WithQueryHandler

func (p *ProxyEndpoint) WithQueryHandler(handler http.Handler) *ProxyEndpoint

WithQueryHandler sets the middleware-based query handlers (logs and metrics) for the endpoint. When set, ServeHTTP uses this handler instead of the legacy executeBackendRequests.

type ProxyMetrics

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

func NewProxyMetrics

func NewProxyMetrics(registerer prometheus.Registerer) *ProxyMetrics

type ResponsesComparator

type ResponsesComparator interface {
	Compare(expected, actual []byte, queryEvaluationTime time.Time) (*ComparisonSummary, error)
}

type Route

type Route struct {
	Path               string
	RouteName          string
	Methods            []string
	ResponseComparator comparator.ResponsesComparator
}

type RoutingConfig

type RoutingConfig struct {
	Mode          RoutingMode
	V1Preferred   string
	V2Preferred   string
	RaceTolerance time.Duration

	// SplitStart is the start date of data available in v2 (dataobjs) storage.
	// Queries for data before this date will only go to the v1 backend.
	// If not set, assume v2 data is always available.
	//
	// When splitting queries will be split into up to three parts:
	// 1. Data before SplitStart -> split goes to the v1 backend only
	// 2. Data between SplitStart and (now - SplitLag) -> split goes to both v1 and v2 backends
	// 3. Data after (now - SplitLag) -> split goes to the v1 backend only
	SplitStart flagext.Time

	// SplitLag is the minimum age of data to route to v2.
	// Data newer than (now - SplitLag) will only go to the v1 backend.
	// When set to 0, query splitting is disabled.
	SplitLag time.Duration

	// SplitRetentionDays is the lifecycle of data objects in days.
	// If set, data in v2 storage is considered available only for retention days.
	// Queries for data before the retention period will go to the v1 backend.
	// When both SplitStart and SplitRetentionDays are set, the more restrictive of the two will
	// determine v2 data availability.
	SplitRetentionDays int64

	// AddRoutingDecisionsToWarnings controls whether routing decisions are added
	// as warnings to query responses. When enabled, responses will include
	// warnings indicating which backend handled the query and how it was routed.
	AddRoutingDecisionsToWarnings bool
}

func (*RoutingConfig) RegisterFlags

func (cfg *RoutingConfig) RegisterFlags(f *flag.FlagSet)

func (*RoutingConfig) Validate

func (cfg *RoutingConfig) Validate() error

type RoutingMode

type RoutingMode string
const (
	RoutingModeRace        RoutingMode = "race"
	RoutingModeV1Preferred RoutingMode = "v1-preferred"
	RoutingModeV2Preferred RoutingMode = "v2-preferred"
)

type SplittingHandler

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

func (*SplittingHandler) ServeHTTP

func (f *SplittingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler interface to serve queries that can be split.

Routing behavior depends on the routing mode:

  • v2-preferred/race: Always split when splitLag > 0 (sampling only affects goldfish comparison).
  • v1-preferred: Skip fanout when not sampling, only split for goldfish comparison.

type SplittingHandlerConfig

type SplittingHandlerConfig struct {
	Codec                         queryrangebase.Codec
	FanOutHandler                 queryrangebase.Handler
	GoldfishManager               goldfish.Manager
	V1Backend                     *ProxyBackend
	SkipFanoutWhenNotSampling     bool
	RoutingMode                   RoutingMode
	SplitStart                    time.Time
	SplitLag                      time.Duration
	SplitRetentionDays            int64
	AddRoutingDecisionsToWarnings bool
}

SplittingHandlerConfig holds configuration for creating a SplittingHandler.

Directories

Path Synopsis
Package goldfish provides query sampling and comparison functionality for the querytee tool.
Package goldfish provides query sampling and comparison functionality for the querytee tool.

Jump to

Keyboard shortcuts

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