+double get_timestamp_for_metrics()
+{
+ return duration<double>(system_clock::now().time_since_epoch()).count();
+}
+
+string Metrics::serialize_name(const string &name, const vector<pair<string, string>> &labels)
+{
+ return "nageru_" + name + serialize_labels(labels);
+}
+
+string Metrics::serialize_labels(const vector<pair<string, string>> &labels)
+{
+ if (labels.empty()) {
+ return "";
+ }
+
+ string label_str;
+ for (const pair<string, string> &label : labels) {
+ if (!label_str.empty()) {
+ label_str += ",";
+ }
+ label_str += label.first + "=\"" + label.second + "\"";
+ }
+ return "{" + label_str + "}";
+}
+
+void Metrics::add(const string &name, const vector<pair<string, string>> &labels, atomic<int64_t> *location, Metrics::Type type)
+{
+ Metric metric;
+ metric.data_type = DATA_TYPE_INT64;
+ metric.location_int64 = location;
+
+ lock_guard<mutex> lock(mu);
+ metrics.emplace(MetricKey(name, labels), metric);
+ assert(types.count(name) == 0 || types[name] == type);
+ types[name] = type;
+}
+
+void Metrics::add(const string &name, const vector<pair<string, string>> &labels, atomic<double> *location, Metrics::Type type)
+{
+ Metric metric;
+ metric.data_type = DATA_TYPE_DOUBLE;
+ metric.location_double = location;
+
+ lock_guard<mutex> lock(mu);
+ metrics.emplace(MetricKey(name, labels), metric);
+ assert(types.count(name) == 0 || types[name] == type);
+ types[name] = type;
+}
+
+void Metrics::add(const string &name, const vector<pair<string, string>> &labels, Histogram *location, Laziness laziness)