/* * Stats.h * * This source file is part of the FoundationDB open source project * * Copyright 2013-2018 Apple Inc. and the FoundationDB project authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FLOW_STATS_H #define FLOW_STATS_H #pragma once // Yet another performance statistics interface /* struct MyCounters { CounterCollection cc; Counter foo, bar, baz; MyCounters() : foo("foo", cc), bar("bar", cc), baz("baz", cc) {} }; */ #include #include #include "flow/flow.h" #include "flow/TDMetric.actor.h" struct ICounter { // All counters have a name and value virtual std::string const& getName() const = 0; virtual int64_t getValue() const = 0; // Counters may also have rate and roughness virtual bool hasRate() const = 0; virtual double getRate() const = 0; virtual bool hasRoughness() const = 0; virtual double getRoughness() const = 0; virtual void resetInterval() = 0; virtual void remove() {} }; struct CounterCollection { CounterCollection(std::string name, std::string id = std::string()) : name(name), id(id) {} std::vector counters, counters_to_remove; ~CounterCollection() { for (auto c : counters_to_remove) c->remove(); } std::string name; std::string id; }; struct Counter : ICounter { public: typedef int64_t Value; Counter(std::string const& name, CounterCollection& collection); void operator += (Value delta); void operator ++ () { *this += 1; } void clear(); void resetInterval(); std::string const& getName() const { return name; } Value getIntervalDelta() const { return interval_delta; } Value getValue() const { return interval_start_value + interval_delta; } double getRate() const; // dValue / dt double getRoughness() const; // value deltas come in "clumps" of this many ( 1 = periodic, 2 = poisson, 10 = periodic clumps of 10 (nearly) simultaneous delta ) bool hasRate() const { return true; } bool hasRoughness() const { return true; } private: std::string name; double interval_start, last_event, interval_sq_time; Value interval_delta, interval_start_value; Int64MetricHandle metric; }; template struct SpecialCounter : ICounter, FastAllocated> { SpecialCounter(CounterCollection& collection, std::string const& name, F && f) : name(name), f(f) { collection.counters.push_back(this); collection.counters_to_remove.push_back(this); } virtual void remove() { delete this; } virtual std::string const& getName() const { return name; } virtual int64_t getValue() const { return f(); } virtual void resetInterval() {} virtual bool hasRate() const { return false; } virtual double getRate() const { throw internal_error(); } virtual bool hasRoughness() const { return false; } virtual double getRoughness() const { throw internal_error(); } std::string name; F f; }; template static void specialCounter(CounterCollection& collection, std::string const& name, F && f) { new SpecialCounter(collection, name, std::move(f)); } Future traceCounters(std::string const& traceEventName, UID const& traceEventID, double const& interval, CounterCollection* const& counters, std::string const& trackLatestName = std::string()); #endif