influxdb/influxql/statistics.go

124 lines
3.2 KiB
Go

package influxql
import (
"sync"
"time"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/log"
)
// Statistics is a collection of statistics about the processing of a query.
type Statistics struct {
PlanDuration time.Duration `json:"plan_duration"` // PlanDuration is the duration spent planning the query.
ExecuteDuration time.Duration `json:"execute_duration"` // ExecuteDuration is the duration spent executing the query.
StatementCount int `json:"statement_count"` // StatementCount is the number of InfluxQL statements executed
ScannedValues int `json:"scanned_values"` // ScannedValues is the number of values scanned from storage
ScannedBytes int `json:"scanned_bytes"` // ScannedBytes is the number of bytes scanned from storage
}
// Adding returns the sum of s and other.
func (s Statistics) Adding(other Statistics) Statistics {
return Statistics{
PlanDuration: s.PlanDuration + other.PlanDuration,
ExecuteDuration: s.ExecuteDuration + other.ExecuteDuration,
StatementCount: s.StatementCount + other.StatementCount,
ScannedValues: s.ScannedValues + other.ScannedValues,
ScannedBytes: s.ScannedBytes + other.ScannedBytes,
}
}
// Add adds other to s.
func (s *Statistics) Add(other Statistics) {
s.PlanDuration += other.PlanDuration
s.ExecuteDuration += other.ExecuteDuration
s.StatementCount += other.StatementCount
s.ScannedValues += other.ScannedValues
s.ScannedBytes += other.ScannedBytes
}
func (s *Statistics) LogToSpan(span opentracing.Span) {
if span == nil {
return
}
span.LogFields(
log.Float64("stats_plan_duration_seconds", s.PlanDuration.Seconds()),
log.Float64("stats_execute_duration_seconds", s.ExecuteDuration.Seconds()),
log.Int("stats_statement_count", s.StatementCount),
log.Int("stats_scanned_values", s.ScannedValues),
log.Int("stats_scanned_bytes", s.ScannedBytes),
)
}
// TotalDuration returns the sum of all durations for s.
func (s *Statistics) TotalDuration() time.Duration {
return s.PlanDuration + s.ExecuteDuration
}
type CollectorFn func() Statistics
func (fn CollectorFn) Statistics() Statistics {
return fn()
}
type MutableCollector struct {
s *Statistics
}
func NewMutableCollector(s *Statistics) *MutableCollector {
return &MutableCollector{s: s}
}
func (c *MutableCollector) Statistics() Statistics {
return *c.s
}
type ImmutableCollector struct {
s Statistics
}
func NewImmutableCollector(s Statistics) *ImmutableCollector {
return &ImmutableCollector{s: s}
}
func (c *ImmutableCollector) Statistics() Statistics {
return c.s
}
type StatisticsCollector interface {
Statistics() Statistics
}
type StatisticsGatherer struct {
mu sync.Mutex
collectors []StatisticsCollector
}
func (sg *StatisticsGatherer) Append(sc StatisticsCollector) {
sg.mu.Lock()
defer sg.mu.Unlock()
sg.collectors = append(sg.collectors, sc)
}
func (sg *StatisticsGatherer) Statistics() Statistics {
sg.mu.Lock()
defer sg.mu.Unlock()
res := Statistics{}
for i := range sg.collectors {
res = res.Adding(sg.collectors[i].Statistics())
}
return res
}
func (sg *StatisticsGatherer) Reset() {
sg.mu.Lock()
defer sg.mu.Unlock()
coll := sg.collectors
sg.collectors = sg.collectors[:0]
for i := range coll {
coll[i] = nil
}
}