/** * Input data from a producer thread. * * @param x * the data to insert */ public void update(SAMPLE x) { update(x, getOrCreateLocal()); }
@Override public Result search(Query query, Execution execution) { Result r; long when = query.getStartTime() / 1000L; Hit meta = null; directory.update(when); if (useMetaHit) { if (query.properties().getBoolean(propertyName, false)) { List<QueryRatePerSecond> l = merge(directory.fetch()); Tuple2<Integer, Double> maxAndMean = maxAndMean(l); meta = new QpsHit(maxAndMean.first, maxAndMean.second); } } r = execution.search(query); if (meta != null) { r.hits().add(meta); } return r; }
/** * Update a metric. This API is not intended for clients for the * simplemetrics API, declare a Counter or a Gauge using * {@link #declareCounter(String)}, {@link #declareCounter(String, Point)}, * {@link #declareGauge(String)}, or {@link #declareGauge(String, Point)} * instead. * * @param s * a single simple containing all meta data necessary to update a * metric */ public void update(Sample s) { // pass around the receiver instead of histogram settings to avoid reading any volatile if unnecessary s.setReceiver(this); metricsCollection.update(s); }
private Bucket updateBuffer() { List<Bucket> buckets = metricsCollection.fetch(); final long toMillis = System.currentTimeMillis(); final int bucketIndex = generation++ % buffer.length; Bucket bucketToDelete = buffer[bucketIndex]; Bucket latest = new Bucket(fromMillis, toMillis); for (Bucket b : buckets) { latest.merge(b, true); } buffer[bucketIndex] = latest; this.fromMillis = toMillis; return bucketToDelete; }
static ThreadLocalDirectory<Deque<QueryRatePerSecond>, Long> createDirectory() { return new ThreadLocalDirectory<>(new QueryRate()); }
/** * Expose the thread local for the running thread, for use in conjunction * with update(SAMPLE, LocalInstance<AGGREGATOR, SAMPLE>). * * @return the current thread's local instance */ public LocalInstance<AGGREGATOR, SAMPLE> getLocalInstance() { return getOrCreateLocal(); }
/** * Update a value with a given thread local instance. * * <p> * If a producer thread is to insert a series of data, it is desirable to * limit the number of memory transactions to the theoretical minimum. Since * reading a thread local is the memory equivalence of reading a volatile, * it is then useful to avoid re-reading the running threads' input * instance. For this scenario, fetch the running thread's instance with * getLocalInstance(), and then insert the produced data with the multiple * calls necessary to update(SAMPLE, LocalInstance<AGGREGATOR, SAMPLE>). * </p> * * @param x * the data to insert * @param localInstance * the local data insertion instance */ public void update(SAMPLE x, LocalInstance<AGGREGATOR, SAMPLE> localInstance) { boolean isRegistered; isRegistered = localInstance.update(x, updater); if (!isRegistered) { put(localInstance); } }
/** gathers all data since last snapshot */ public Bucket getSnapshot() { final Bucket merged = new Bucket(); for (Bucket b : collection.fetch()) { merged.merge(b, true); } return merged; } /** utility method for testing */
public MockReceiver() { this(new ThreadLocalDirectory<>(new MetricUpdater())); } /** gathers all data since last snapshot */
@Override public void run(Handle h, boolean firstRun) { List<Deque<QueryRatePerSecond>> data = directory.fetch(); List<QueryRatePerSecond> chewed = merge(data); for (QueryRatePerSecond qps : chewed) { qpsStatistics.put((double) qps.howMany); } } }
private MetricManager(ManagerConfig settings, Updater<Bucket, Sample> updater) { log.log(LogLevel.CONFIG, "setting up simple metrics gathering." + " reportPeriodSeconds=" + settings.reportPeriodSeconds() + ", pointsToKeepPerMetric=" + settings.pointsToKeepPerMetric()); metricsCollection = new ThreadLocalDirectory<>(updater); final AtomicReference<Bucket> currentSnapshot = new AtomicReference<>(null); executor = new ScheduledThreadPoolExecutor(1); // Fixed rate, not fixed delay, is it is not too important that each // bucket has data for exactly one second, but one should strive for // this.buffer to contain data for as close a period to the report // interval as possible executor.scheduleAtFixedRate(new MetricAggregator(metricsCollection, currentSnapshot, settings), 1, 1, TimeUnit.SECONDS); receiver = new MetricReceiver(metricsCollection, currentSnapshot); }