/// <summary>Create a mutable metric that estimates quantiles of a stream of values</summary> /// <param name="name">of the metric</param> /// <param name="desc">metric description</param> /// <param name="sampleName">of the metric (e.g., "Ops")</param> /// <param name="valueName">of the metric (e.g., "Time" or "Latency")</param> /// <param name="interval">rollover interval of estimator in seconds</param> /// <returns>a new quantile estimator object</returns> public virtual MutableQuantiles NewQuantiles(string name, string desc, string sampleName , string valueName, int interval) { lock (this) { CheckMetricName(name); MutableQuantiles ret = new MutableQuantiles(name, desc, sampleName, valueName, interval ); metricsMap[name] = ret; return(ret); } }
/// <summary> /// Ensure that quantile estimates from /// <see cref="MutableQuantiles"/> /// are within /// specified error bounds. /// </summary> /// <exception cref="System.Exception"/> public virtual void TestMutableQuantilesError() { MetricsRecordBuilder mb = MetricsAsserts.MockMetricsRecordBuilder(); MetricsRegistry registry = new MetricsRegistry("test"); // Use a 5s rollover period MutableQuantiles quantiles = registry.NewQuantiles("foo", "stat", "Ops", "Latency" , 5); // Push some values in and wait for it to publish long start = Runtime.NanoTime() / 1000000; for (long i = 1; i <= 1000; i++) { quantiles.Add(i); quantiles.Add(1001 - i); } long end = Runtime.NanoTime() / 1000000; Thread.Sleep(6000 - (end - start)); registry.Snapshot(mb, false); // Print out the snapshot IDictionary <Quantile, long> previousSnapshot = quantiles.previousSnapshot; foreach (KeyValuePair <Quantile, long> item in previousSnapshot) { System.Console.Out.WriteLine(string.Format("Quantile %.2f has value %d", item.Key .quantile, item.Value)); } // Verify the results are within our requirements Org.Mockito.Mockito.Verify(mb).AddGauge(Interns.Info("FooNumOps", "Number of ops for stat with 5s interval" ), (long)2000); Quantile[] quants = MutableQuantiles.quantiles; string name = "Foo%dthPercentileLatency"; string desc = "%d percentile latency with 5 second interval for stat"; foreach (Quantile q in quants) { int percentile = (int)(100 * q.quantile); int error = (int)(1000 * q.error); string n = string.Format(name, percentile); string d = string.Format(desc, percentile); long expected = (long)(q.quantile * 1000); Org.Mockito.Mockito.Verify(mb).AddGauge(Matchers.Eq(Interns.Info(n, d)), AdditionalMatchers.Leq (expected + error)); Org.Mockito.Mockito.Verify(mb).AddGauge(Matchers.Eq(Interns.Info(n, d)), AdditionalMatchers.Geq (expected - error)); } }
/// <summary> /// Test that /// <see cref="MutableQuantiles"/> /// rolls the window over at the specified /// interval. /// </summary> /// <exception cref="System.Exception"/> public virtual void TestMutableQuantilesRollover() { MetricsRecordBuilder mb = MetricsAsserts.MockMetricsRecordBuilder(); MetricsRegistry registry = new MetricsRegistry("test"); // Use a 5s rollover period MutableQuantiles quantiles = registry.NewQuantiles("foo", "stat", "Ops", "Latency" , 5); Quantile[] quants = MutableQuantiles.quantiles; string name = "Foo%dthPercentileLatency"; string desc = "%d percentile latency with 5 second interval for stat"; // Push values for three intervals long start = Runtime.NanoTime() / 1000000; for (int i = 1; i <= 3; i++) { // Insert the values for (long j = 1; j <= 1000; j++) { quantiles.Add(i); } // Sleep until 1s after the next 5s interval, to let the metrics // roll over long sleep = (start + (5000 * i) + 1000) - (Runtime.NanoTime() / 1000000); Thread.Sleep(sleep); // Verify that the window reset, check it has the values we pushed in registry.Snapshot(mb, false); foreach (Quantile q in quants) { int percentile = (int)(100 * q.quantile); string n = string.Format(name, percentile); string d = string.Format(desc, percentile); Org.Mockito.Mockito.Verify(mb).AddGauge(Interns.Info(n, d), (long)i); } } // Verify the metrics were added the right number of times Org.Mockito.Mockito.Verify(mb, Org.Mockito.Mockito.Times(3)).AddGauge(Interns.Info ("FooNumOps", "Number of ops for stat with 5s interval"), (long)1000); foreach (Quantile q_1 in quants) { int percentile = (int)(100 * q_1.quantile); string n = string.Format(name, percentile); string d = string.Format(desc, percentile); Org.Mockito.Mockito.Verify(mb, Org.Mockito.Mockito.Times(3)).AddGauge(Matchers.Eq (Interns.Info(n, d)), Matchers.AnyLong()); } }
/// <summary> /// Test that /// <see cref="MutableQuantiles"/> /// rolls over correctly even if no items /// have been added to the window /// </summary> /// <exception cref="System.Exception"/> public virtual void TestMutableQuantilesEmptyRollover() { MetricsRecordBuilder mb = MetricsAsserts.MockMetricsRecordBuilder(); MetricsRegistry registry = new MetricsRegistry("test"); // Use a 5s rollover period MutableQuantiles quantiles = registry.NewQuantiles("foo", "stat", "Ops", "Latency" , 5); // Check it initially quantiles.Snapshot(mb, true); Org.Mockito.Mockito.Verify(mb).AddGauge(Interns.Info("FooNumOps", "Number of ops for stat with 5s interval" ), (long)0); Thread.Sleep(6000); quantiles.Snapshot(mb, false); Org.Mockito.Mockito.Verify(mb, Org.Mockito.Mockito.Times(2)).AddGauge(Interns.Info ("FooNumOps", "Number of ops for stat with 5s interval"), (long)0); }
public RolloverSample(MutableQuantiles parent) { this.parent = parent; }