mirror of
https://github.com/hanzoai/traces.git
synced 2026-10-30 18:20:41 +00:00
161 lines
5.6 KiB
Go
161 lines
5.6 KiB
Go
package frontend
|
|
|
|
import (
|
|
"flag"
|
|
"time"
|
|
|
|
"github.com/go-kit/log"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
"github.com/grafana/tempo/modules/frontend/pipeline"
|
|
v1 "github.com/grafana/tempo/modules/frontend/v1"
|
|
"github.com/grafana/tempo/pkg/usagestats"
|
|
)
|
|
|
|
var statVersion = usagestats.NewString("frontend_version")
|
|
|
|
type Config struct {
|
|
Config v1.Config `yaml:",inline"`
|
|
MaxRetries int `yaml:"max_retries,omitempty"`
|
|
Search SearchConfig `yaml:"search"`
|
|
TraceByID TraceByIDConfig `yaml:"trace_by_id"`
|
|
Metrics MetricsConfig `yaml:"metrics"`
|
|
MultiTenantQueriesEnabled bool `yaml:"multi_tenant_queries_enabled"`
|
|
ResponseConsumers int `yaml:"response_consumers"`
|
|
Weights pipeline.WeightsConfig `yaml:"weights"`
|
|
MCPServer MCPServerConfig `yaml:"mcp_server"`
|
|
|
|
// the maximum time limit that tempo will work on an api request. this includes both
|
|
// grpc and http requests and applies to all "api" frontend query endpoints such as
|
|
// traceql, tag search, tag value search, trace by id and all streaming gRPC endpoints.
|
|
// 0 disables
|
|
APITimeout time.Duration `yaml:"api_timeout,omitempty"`
|
|
|
|
// A list of regexes for black listing requests, these will apply for every request regardless the endpoint
|
|
URLDenyList []string `yaml:"url_deny_list,omitempty"`
|
|
|
|
// Maximum allowed size of the raw TraceQL Query expression in bytes
|
|
MaxQueryExpressionSizeBytes int `yaml:"max_query_expression_size_bytes,omitempty"`
|
|
|
|
// A list of headers allowed through the HTTP pipeline. Everything else will be stripped.
|
|
AllowedHeaders []string `yaml:"allowed_headers,omitempty"`
|
|
|
|
// RF1After specifies the time after which RF1 logic is applied.
|
|
RF1After time.Time `yaml:"rf1_after" category:"advanced"`
|
|
|
|
// QueryEndCutoff prevents querying incomplete recent data.
|
|
QueryEndCutoff time.Duration `yaml:"query_end_cutoff,omitempty"`
|
|
}
|
|
|
|
type MCPServerConfig struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
}
|
|
|
|
type SearchConfig struct {
|
|
Timeout time.Duration `yaml:"timeout,omitempty"`
|
|
Sharder SearchSharderConfig `yaml:",inline"`
|
|
SLO SLOConfig `yaml:",inline"`
|
|
MetadataSLO SLOConfig `yaml:"metadata_slo,omitempty"`
|
|
}
|
|
|
|
type TraceByIDConfig struct {
|
|
QueryShards int `yaml:"query_shards,omitempty"`
|
|
ConcurrentShards int `yaml:"concurrent_shards,omitempty"`
|
|
SLO SLOConfig `yaml:",inline"`
|
|
ExternalEnabled bool `yaml:"external_enabled,omitempty"`
|
|
|
|
// RF1After specifies the time after which RF1 logic is applied, injected by the configuration
|
|
// or determined at runtime based on search request parameters.
|
|
RF1After time.Time `yaml:"-"`
|
|
}
|
|
|
|
type MetricsConfig struct {
|
|
Sharder QueryRangeSharderConfig `yaml:",inline"`
|
|
SLO SLOConfig `yaml:",inline"`
|
|
MaxIntervals uint64 `yaml:"max_intervals,omitempty"`
|
|
}
|
|
|
|
type SLOConfig struct {
|
|
DurationSLO time.Duration `yaml:"duration_slo,omitempty"`
|
|
ThroughputBytesSLO float64 `yaml:"throughput_bytes_slo,omitempty"`
|
|
}
|
|
|
|
func (cfg *Config) RegisterFlagsAndApplyDefaults(string, *flag.FlagSet) {
|
|
slo := SLOConfig{
|
|
DurationSLO: 0,
|
|
ThroughputBytesSLO: 0,
|
|
}
|
|
|
|
cfg.Config.MaxOutstandingPerTenant = 2000
|
|
cfg.Config.MaxBatchSize = 7
|
|
cfg.MaxRetries = 2
|
|
cfg.ResponseConsumers = 10
|
|
cfg.Search = SearchConfig{
|
|
Sharder: SearchSharderConfig{
|
|
QueryBackendAfter: 15 * time.Minute,
|
|
DefaultLimit: 20,
|
|
MaxLimit: 256 * 1024,
|
|
MaxDuration: 168 * time.Hour, // 1 week
|
|
ConcurrentRequests: defaultConcurrentRequests,
|
|
TargetBytesPerRequest: defaultTargetBytesPerRequest,
|
|
MostRecentShards: defaultMostRecentShards,
|
|
IngesterShards: 3,
|
|
DefaultSpansPerSpanSet: 3,
|
|
MaxSpansPerSpanSet: 100,
|
|
},
|
|
SLO: slo,
|
|
}
|
|
cfg.TraceByID = TraceByIDConfig{
|
|
QueryShards: 50,
|
|
SLO: slo,
|
|
}
|
|
cfg.Metrics = MetricsConfig{
|
|
Sharder: QueryRangeSharderConfig{
|
|
MaxDuration: 24 * time.Hour,
|
|
QueryBackendAfter: 30 * time.Minute,
|
|
ConcurrentRequests: defaultConcurrentRequests,
|
|
TargetBytesPerRequest: defaultTargetBytesPerRequest,
|
|
Interval: 5 * time.Minute,
|
|
MaxExemplars: 100,
|
|
MaxResponseSeries: 0,
|
|
StreamingShards: defaultStreamingShards,
|
|
},
|
|
SLO: slo,
|
|
}
|
|
cfg.Weights = pipeline.WeightsConfig{
|
|
RequestWithWeights: true,
|
|
RetryWithWeights: true,
|
|
MaxRegexConditions: 1,
|
|
MaxTraceQLConditions: 4,
|
|
}
|
|
|
|
// enabling an mcp server opens the door to send tracing data to an LLM. it should require
|
|
// explicit enabling
|
|
cfg.MCPServer = MCPServerConfig{
|
|
Enabled: false,
|
|
}
|
|
|
|
// set default max query size to 128 KiB, queries larger than this will be rejected
|
|
cfg.MaxQueryExpressionSizeBytes = 128 * 1024
|
|
// enable multi tenant queries by default
|
|
cfg.MultiTenantQueriesEnabled = true
|
|
cfg.Metrics.MaxIntervals = 10_000
|
|
}
|
|
|
|
type CortexNoQuerierLimits struct{}
|
|
|
|
// InitFrontend initializes V1 frontend
|
|
//
|
|
// Returned RoundTripper can be wrapped in more round-tripper middlewares, and then eventually registered
|
|
// into HTTP server using the Handler from this package. Returned RoundTripper is always non-nil
|
|
// (if there are no errors), and it uses the returned frontend (if any).
|
|
func InitFrontend(cfg v1.Config, log log.Logger, reg prometheus.Registerer) (pipeline.RoundTripper, *v1.Frontend, error) {
|
|
statVersion.Set("v1")
|
|
// No scheduler = use original frontend.
|
|
fr, err := v1.New(cfg, log, reg)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return fr, fr, nil
|
|
}
|