MediaWiki  master
SamplingStatsdClient.php
Go to the documentation of this file.
1 <?php
26 
32 class SamplingStatsdClient extends StatsdClient {
33  protected $samplingRates = [];
34 
42  public function setSamplingRates( array $samplingRates ) {
43  $this->samplingRates = $samplingRates;
44  }
45 
52  public function appendSampleRate( $data, $sampleRate = 1 ) {
54  if ( !$samplingRates && $sampleRate !== 1 ) {
55  $samplingRates = [ '*' => $sampleRate ];
56  }
57  if ( $samplingRates ) {
58  array_walk( $data, function ( $item ) use ( $samplingRates ) {
60  foreach ( $samplingRates as $pattern => $rate ) {
61  if ( fnmatch( $pattern, $item->getKey(), FNM_NOESCAPE ) ) {
62  $item->setSampleRate( $item->getSampleRate() * $rate );
63  break;
64  }
65  }
66  } );
67  }
68 
69  return $data;
70  }
71 
82  public function send( $data, $sampleRate = 1 ) {
83  if ( !is_array( $data ) ) {
84  $data = [ $data ];
85  }
86  if ( !$data ) {
87  return 0;
88  }
89  foreach ( $data as $item ) {
90  if ( !( $item instanceof StatsdDataInterface ) ) {
91  throw new InvalidArgumentException(
92  'SamplingStatsdClient does not accept stringified messages' );
93  }
94  }
95 
96  // add sampling
97  $data = $this->appendSampleRate( $data, $sampleRate );
98  $data = $this->sampleData( $data );
99 
100  $data = array_map( 'strval', $data );
101 
102  // reduce number of packets
103  if ( $this->getReducePacket() ) {
104  $data = $this->reduceCount( $data );
105  }
106 
107  // failures in any of this should be silently ignored if ..
108  $written = 0;
109  try {
110  $fp = $this->getSender()->open();
111  if ( !$fp ) {
112  return 0;
113  }
114  foreach ( $data as $message ) {
115  $written += $this->getSender()->write( $fp, $message );
116  }
117  $this->getSender()->close( $fp );
118  } catch ( Exception $e ) {
119  $this->throwException( $e );
120  }
121 
122  return $written;
123  }
124 
131  protected function sampleData( $data ) {
132  $newData = [];
133  $mt_rand_max = mt_getrandmax();
134  foreach ( $data as $item ) {
135  $samplingRate = $item->getSampleRate();
136  if ( $samplingRate <= 0.0 || $samplingRate > 1.0 ) {
137  throw new LogicException( 'Sampling rate shall be within ]0, 1]' );
138  }
139  if (
140  $samplingRate === 1 ||
141  ( mt_rand() / $mt_rand_max <= $samplingRate )
142  ) {
143  $newData[] = $item;
144  }
145  }
146  return $newData;
147  }
148 
152  protected function throwException( Exception $exception ) {
153  if ( !$this->getFailSilently() ) {
154  throw $exception;
155  }
156  }
157 }
setSamplingRates(array $samplingRates)
Sampling rates as an associative array of patterns and rates.
sampleData( $data)
Throw away some of the data according to the sample rate.
send( $data, $sampleRate=1)
Send the metrics over UDP Sample the metrics according to their sample rate and send the remaining on...
A statsd client that applies the sampling rate to the data items before sending them.
appendSampleRate( $data, $sampleRate=1)
Sets sampling rate for all items in $data.
throwException(Exception $exception)