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  //------------------------------------------------------------------------------