github.com/yandex/pandora@v0.5.32/core/aggregator/reporter.go (about) 1 package aggregator 2 3 import ( 4 "fmt" 5 6 "github.com/yandex/pandora/core" 7 "github.com/yandex/pandora/core/coreutil" 8 "go.uber.org/atomic" 9 "go.uber.org/zap" 10 ) 11 12 type ReporterConfig struct { 13 // SampleQueueSize is number maximum number of unhandled samples. 14 // On queue overflow, samples are dropped. 15 SampleQueueSize int `config:"sample-queue-size" validate:"min=1"` 16 } 17 18 const ( 19 samplesPerSecondUpperBound = 128 * 1024 20 diskWriteLatencySecondUpperBound = 0.5 21 samplesInQueueAfterDiskWriteUpperBound = samplesPerSecondUpperBound * diskWriteLatencySecondUpperBound 22 DefaultSampleQueueSize = 2 * samplesInQueueAfterDiskWriteUpperBound 23 ) 24 25 func DefaultReporterConfig() ReporterConfig { 26 return ReporterConfig{ 27 SampleQueueSize: DefaultSampleQueueSize, 28 } 29 } 30 31 func NewReporter(conf ReporterConfig) *Reporter { 32 return &Reporter{ 33 Incomming: make(chan core.Sample, conf.SampleQueueSize), 34 } 35 } 36 37 type Reporter struct { 38 Incomming chan core.Sample 39 samplesDropped atomic.Int64 40 lastSampleDropWarn atomic.Int64 41 } 42 43 func (a *Reporter) DroppedErr() error { 44 dropped := a.samplesDropped.Load() 45 if dropped == 0 { 46 return nil 47 } 48 return &SomeSamplesDropped{dropped} 49 } 50 51 func (a *Reporter) Report(s core.Sample) { 52 select { 53 case a.Incomming <- s: 54 default: 55 a.dropSample(s) 56 } 57 } 58 59 func (a *Reporter) dropSample(s core.Sample) { 60 dropped := a.samplesDropped.Inc() 61 if dropped == 1 { 62 // AggregatorDeps may not be passed, because Run was not called. 63 zap.L().Warn("First sample is dropped. More information in Run error") 64 } 65 coreutil.ReturnSampleIfBorrowed(s) 66 } 67 68 type SomeSamplesDropped struct { 69 Dropped int64 70 } 71 72 func (err *SomeSamplesDropped) Error() string { 73 return fmt.Sprintf("%v samples were dropped", err.Dropped) 74 }