0847e60d2a
CobraConnection: sets a counter as a field for each event published.
168 lines
6.6 KiB
C++
168 lines
6.6 KiB
C++
/*
|
|
* IXCobraMetricsPublisher.h
|
|
* Author: Benjamin Sergeant
|
|
* Copyright (c) 2017 Machine Zone. All rights reserved.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "IXCobraMetricsThreadedPublisher.h"
|
|
#include <atomic>
|
|
#include <chrono>
|
|
#include <jsoncpp/json/json.h>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
namespace ix
|
|
{
|
|
class CobraMetricsPublisher
|
|
{
|
|
public:
|
|
CobraMetricsPublisher();
|
|
~CobraMetricsPublisher();
|
|
|
|
/// Thread safety notes:
|
|
///
|
|
/// 1. _enabled, _blacklist and _rate_control read/writes are not protected by a mutex
|
|
/// to make shouldPush as fast as possible. _enabled default to false.
|
|
///
|
|
/// The code that set those is ran only once at init, and
|
|
/// the last value to be set is _enabled, which is also the first value checked in
|
|
/// shouldPush, so there shouldn't be any race condition.
|
|
///
|
|
/// 2. The queue of messages is thread safe, so multiple metrics can be safely pushed on
|
|
/// multiple threads
|
|
///
|
|
/// 3. Access to _last_update is protected as it needs to be read/write.
|
|
///
|
|
|
|
/// Configuration / set keys, etc...
|
|
/// All input data but the channel name is encrypted with rc4
|
|
void configure(const std::string& appkey,
|
|
const std::string& endpoint,
|
|
const std::string& channel,
|
|
const std::string& rolename,
|
|
const std::string& rolesecret,
|
|
bool enablePerMessageDeflate);
|
|
|
|
/// Setter for the list of blacklisted metrics ids.
|
|
/// That list is sorted internally for fast lookups
|
|
void setBlacklist(const std::vector<std::string>& blacklist);
|
|
|
|
/// Set the maximum rate at which a metrics can be sent. Unit is seconds
|
|
/// if rate_control = { 'foo_id': 60 },
|
|
/// the foo_id metric cannot be pushed more than once every 60 seconds
|
|
void setRateControl(const std::unordered_map<std::string, int>& rate_control);
|
|
|
|
/// Configuration / enable/disable
|
|
void enable(bool enabled);
|
|
|
|
/// Simple interface, list of key value pairs where typeof(key) == typeof(value) == string
|
|
typedef std::unordered_map<std::string, std::string> Message;
|
|
void push(const std::string& id,
|
|
const CobraMetricsPublisher::Message& data = CobraMetricsPublisher::Message());
|
|
|
|
/// Richer interface using json, which supports types (bool, int, float) and hierarchies of
|
|
/// elements
|
|
///
|
|
/// The shouldPushTest argument should be set to false, and used in combination with the
|
|
/// shouldPush method for places where we want to be as lightweight as possible when
|
|
/// collecting metrics. When set to false, it is used so that we don't do double work when
|
|
/// computing whether a metrics should be sent or not.
|
|
void push(const std::string& id, const Json::Value& data, bool shouldPushTest = true);
|
|
|
|
/// Interface used by lua. msg is a json encoded string.
|
|
void push(const std::string& id, const std::string& data, bool shouldPushTest = true);
|
|
|
|
/// Tells whether a metric can be pushed.
|
|
/// A metric can be pushed if it satisfies those conditions:
|
|
///
|
|
/// 1. the metrics system should be enabled
|
|
/// 2. the metrics shouldn't be black-listed
|
|
/// 3. the metrics shouldn't have reached its rate control limit at this
|
|
/// "sampling"/"calling" time
|
|
bool shouldPush(const std::string& id) const;
|
|
|
|
/// Get generic information json object
|
|
Json::Value& getGenericAttributes();
|
|
|
|
/// Set generic information values
|
|
void setGenericAttributes(const std::string& attrName, const Json::Value& value);
|
|
|
|
/// Set a unique id for the session. A uuid can be used.
|
|
void setSession(const std::string& session) { _session = session; }
|
|
|
|
/// Get the unique id used to identify the current session
|
|
const std::string& getSession() const { return _session; }
|
|
|
|
/// Return the number of milliseconds since the epoch (~1970)
|
|
uint64_t getMillisecondsSinceEpoch() const;
|
|
|
|
/// Set satori connection publish mode
|
|
void setPublishMode(CobraConnectionPublishMode publishMode);
|
|
|
|
/// Flush the publish queue
|
|
bool flushQueue();
|
|
|
|
/// Lifecycle management. Free resources when backgrounding
|
|
void suspend();
|
|
void resume();
|
|
|
|
/// Tells whether the socket connection is opened
|
|
bool isConnected() const;
|
|
|
|
/// Returns true only if we're authenticated
|
|
bool isAuthenticated() const;
|
|
|
|
private:
|
|
/// Lookup an id in our metrics to see whether it is blacklisted
|
|
/// Complexity is logarithmic
|
|
bool isMetricBlacklisted(const std::string& id) const;
|
|
|
|
/// Tells whether we should drop a metrics or not as part of an enqueuing
|
|
/// because it exceed the max update rate (it is sent too often)
|
|
bool isAboveMaxUpdateRate(const std::string& id) const;
|
|
|
|
/// Record when a metric was last sent. Used for rate control
|
|
void setLastUpdate(const std::string& id);
|
|
|
|
///
|
|
/// Member variables
|
|
///
|
|
|
|
CobraMetricsThreadedPublisher _cobra_metrics_theaded_publisher;
|
|
|
|
/// A boolean to enable or disable this system
|
|
/// push becomes a no-op when _enabled is false
|
|
std::atomic<bool> _enabled;
|
|
|
|
/// A uuid used to uniquely identify a session
|
|
std::string _session;
|
|
|
|
/// The _device json blob is populated once when configuring this system
|
|
/// It record generic metadata about the client, run (version, device model, etc...)
|
|
Json::Value _device;
|
|
mutable std::mutex _device_mutex; // protect access to _device
|
|
|
|
/// Metrics control (black list + rate control)
|
|
std::vector<std::string> _blacklist;
|
|
std::unordered_map<std::string, int> _rate_control;
|
|
std::unordered_map<std::string, std::chrono::time_point<std::chrono::steady_clock>>
|
|
_last_update;
|
|
mutable std::mutex _last_update_mutex; // protect access to _last_update
|
|
|
|
/// Bump a counter for each metric type
|
|
std::unordered_map<std::string, int> _counters;
|
|
mutable std::mutex _counters_mutex; // protect access to _counters
|
|
|
|
// const strings for internal ids
|
|
static const std::string kSetRateControlId;
|
|
static const std::string kSetBlacklistId;
|
|
|
|
/// Our protocol version. Can be used by subscribers who would want to be backward
|
|
/// compatible if we change the way we arrange data
|
|
static const int kVersion;
|
|
};
|
|
|
|
} // namespace ix
|