github.com/Jeffail/benthos/v3@v3.65.0/lib/processor/sample.go (about) 1 package processor 2 3 import ( 4 "math/rand" 5 "sync" 6 "time" 7 8 "github.com/Jeffail/benthos/v3/internal/docs" 9 "github.com/Jeffail/benthos/v3/lib/log" 10 "github.com/Jeffail/benthos/v3/lib/metrics" 11 "github.com/Jeffail/benthos/v3/lib/response" 12 "github.com/Jeffail/benthos/v3/lib/types" 13 ) 14 15 //------------------------------------------------------------------------------ 16 17 func init() { 18 Constructors[TypeSample] = TypeSpec{ 19 constructor: NewSample, 20 Status: docs.StatusDeprecated, 21 Footnotes: ` 22 ## Alternatives 23 24 All functionality of this processor has been superseded by the 25 [bloblang](/docs/components/processors/bloblang) processor.`, 26 FieldSpecs: docs.FieldSpecs{ 27 docs.FieldCommon("retain", "The percentage of messages to keep."), 28 docs.FieldCommon("seed", "A seed for pseudo-random sampling."), 29 }, 30 } 31 } 32 33 //------------------------------------------------------------------------------ 34 35 // SampleConfig contains configuration fields for the Sample processor. 36 type SampleConfig struct { 37 Retain float64 `json:"retain" yaml:"retain"` 38 RandomSeed int64 `json:"seed" yaml:"seed"` 39 } 40 41 // NewSampleConfig returns a SampleConfig with default values. 42 func NewSampleConfig() SampleConfig { 43 return SampleConfig{ 44 Retain: 10.0, // 10% 45 RandomSeed: 0, 46 } 47 } 48 49 //------------------------------------------------------------------------------ 50 51 // Sample is a processor that drops messages based on a random sample. 52 type Sample struct { 53 conf Config 54 log log.Modular 55 stats metrics.Type 56 57 retain float64 58 gen *rand.Rand 59 mut sync.Mutex 60 61 mCount metrics.StatCounter 62 mDropped metrics.StatCounter 63 mSent metrics.StatCounter 64 mBatchSent metrics.StatCounter 65 } 66 67 // NewSample returns a Sample processor. 68 func NewSample( 69 conf Config, mgr types.Manager, log log.Modular, stats metrics.Type, 70 ) (Type, error) { 71 gen := rand.New(rand.NewSource(conf.Sample.RandomSeed)) 72 return &Sample{ 73 conf: conf, 74 log: log, 75 stats: stats, 76 retain: conf.Sample.Retain / 100.0, 77 gen: gen, 78 79 mCount: stats.GetCounter("count"), 80 mDropped: stats.GetCounter("dropped"), 81 mSent: stats.GetCounter("sent"), 82 mBatchSent: stats.GetCounter("batch.sent"), 83 }, nil 84 } 85 86 //------------------------------------------------------------------------------ 87 88 // ProcessMessage applies the processor to a message, either creating >0 89 // resulting messages or a response to be sent back to the message source. 90 func (s *Sample) ProcessMessage(msg types.Message) ([]types.Message, types.Response) { 91 s.mCount.Incr(1) 92 s.mut.Lock() 93 defer s.mut.Unlock() 94 if s.gen.Float64() > s.retain { 95 s.mDropped.Incr(1) 96 return nil, response.NewAck() 97 } 98 s.mBatchSent.Incr(1) 99 s.mSent.Incr(int64(msg.Len())) 100 msgs := [1]types.Message{msg} 101 return msgs[:], nil 102 } 103 104 // CloseAsync shuts down the processor and stops processing requests. 105 func (s *Sample) CloseAsync() { 106 } 107 108 // WaitForClose blocks until the processor has closed down. 109 func (s *Sample) WaitForClose(timeout time.Duration) error { 110 return nil 111 } 112 113 //------------------------------------------------------------------------------