Couchbase C++ SDK 1.0.1 (rev. 58d46d7)
Loading...
Searching...
No Matches
otel_meter.hxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright 2021 Couchbase, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
20#include "opentelemetry/sdk/metrics/meter.h"
22
23#include <iostream>
24#include <thread>
25#include <utility>
26
29
30namespace nostd = opentelemetry::nostd;
31namespace metrics_api = opentelemetry::metrics;
32namespace metrics_sdk = opentelemetry::sdk::metrics;
33
34namespace couchbase::metrics
35{
36
38{
39public:
40 otel_sync_histogram(nostd::shared_ptr<metrics_api::Histogram<long>> histogram_counter)
41 : histogram_counter_(histogram_counter)
42 {
43 }
44 void record(uint64_t value,
45 const opentelemetry::common::KeyValueIterable& tags,
46 opentelemetry::context::Context& ctx)
47 {
48 // overflow
49 if (value > LONG_MAX) {
50 value = LONG_MAX;
51 }
52 long lvalue = static_cast<long>(value);
53 histogram_counter_->Record(lvalue, tags, ctx);
54 }
55
56private:
57 nostd::shared_ptr<metrics_api::Histogram<long>> histogram_counter_;
58 std::mutex mutex_;
59};
60
62{
63public:
64 explicit otel_value_recorder(nostd::shared_ptr<metrics_api::Histogram<long>> histogram_counter,
65 const std::map<std::string, std::string>& tags)
66 : histogram_counter_(histogram_counter)
67 , tags_(tags)
68 {
69 }
70 void record_value(std::int64_t value) override
71 {
72 if (value > LONG_MAX) {
73 value = LONG_MAX;
74 }
75 long lvalue = static_cast<long>(value);
76 histogram_counter_->Record(
77 value, opentelemetry::common::KeyValueIterableView<decltype(tags_)>{ tags_ }, context_);
78 }
79
80 const std::map<std::string, std::string> tags()
81 {
82 return tags_;
83 }
84
85 nostd::shared_ptr<metrics_api::Histogram<long>> histogram_counter()
86 {
87 return histogram_counter_;
88 }
89
90private:
91 nostd::shared_ptr<metrics_api::Histogram<long>> histogram_counter_;
92 const std::map<std::string, std::string> tags_;
93 opentelemetry::context::Context context_{};
94 std::mutex mutex_;
95};
96
98{
99public:
100 explicit otel_meter(nostd::shared_ptr<metrics_api::Meter> meter)
101 : meter_(meter)
102 {
103 }
104
105 auto get_value_recorder(const std::string& name, const std::map<std::string, std::string>& tags)
106 -> std::shared_ptr<value_recorder> override
107 {
108 // first look up the histogram, in case we already have it...
109 std::scoped_lock<std::mutex> lock(mutex_);
110 auto it = recorders_.equal_range(name);
111 if (it.first == it.second) {
112 // this name isn't associated with any histogram, so make one and return it.
113 // Note we'd like to make one with more buckets than default, given the range of
114 // response times we'd like to display (queries vs kv for instance), but otel
115 // api doesn't seem to allow this.
116 return recorders_
117 .insert({ name,
118 std::make_shared<otel_value_recorder>(meter_->CreateLongHistogram(name, "", "us"),
119 tags) })
120 ->second;
121 }
122 // so it is already, lets see if we already have one with those tags, or need
123 // to make a new one (using the histogram we already have).
124 for (auto itr = it.first; itr != it.second; itr++) {
125 if (tags == itr->second->tags()) {
126 return itr->second;
127 }
128 }
129 // if you are here, we need to add one with these tags and the histogram associated with the
130 // name.
131 return recorders_
132 .insert(
133 { name,
134 std::make_shared<otel_value_recorder>(it.first->second->histogram_counter(), tags) })
135 ->second;
136 }
137
138private:
139 nostd::shared_ptr<metrics_api::Meter> meter_;
140 std::mutex mutex_;
141 std::multimap<std::string, std::shared_ptr<otel_value_recorder>> recorders_;
142};
143} // namespace couchbase::metrics
Definition meter.hxx:40
Definition otel_meter.hxx:98
auto get_value_recorder(const std::string &name, const std::map< std::string, std::string > &tags) -> std::shared_ptr< value_recorder > override
Definition otel_meter.hxx:105
otel_meter(nostd::shared_ptr< metrics_api::Meter > meter)
Definition otel_meter.hxx:100
Definition otel_meter.hxx:38
void record(uint64_t value, const opentelemetry::common::KeyValueIterable &tags, opentelemetry::context::Context &ctx)
Definition otel_meter.hxx:44
otel_sync_histogram(nostd::shared_ptr< metrics_api::Histogram< long > > histogram_counter)
Definition otel_meter.hxx:40
Definition otel_meter.hxx:62
otel_value_recorder(nostd::shared_ptr< metrics_api::Histogram< long > > histogram_counter, const std::map< std::string, std::string > &tags)
Definition otel_meter.hxx:64
void record_value(std::int64_t value) override
Definition otel_meter.hxx:70
nostd::shared_ptr< metrics_api::Histogram< long > > histogram_counter()
Definition otel_meter.hxx:85
const std::map< std::string, std::string > tags()
Definition otel_meter.hxx:80
Definition meter.hxx:27
Definition meter.hxx:25