Skip to content

Commit 4065db2

Browse files
committed
metrics WIP
1 parent f452d7d commit 4065db2

File tree

4 files changed

+183
-139
lines changed

4 files changed

+183
-139
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ set(couchbase_cxx_client_FILES
249249
core/meta/version.cxx
250250
core/metrics/logging_meter.cxx
251251
core/metrics/meter_wrapper.cxx
252+
core/metrics/otel_meter.cxx
252253
core/n1ql_query_options.cxx
253254
core/operations/document_analytics.cxx
254255
core/operations/document_append.cxx

core/metrics/otel_meter.cxx

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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 "otel_meter.hxx"
21+
22+
#include <couchbase/metrics/meter.hxx>
23+
24+
#include <opentelemetry/metrics/meter_provider.h>
25+
#include <opentelemetry/metrics/provider.h>
26+
27+
#include <algorithm>
28+
#include <iostream>
29+
#include <thread>
30+
#include <utility>
31+
32+
namespace couchbase::core::metrics
33+
{
34+
namespace
35+
{
36+
class otel_sync_histogram
37+
{
38+
public:
39+
otel_sync_histogram(
40+
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Histogram<std::uint64_t>>
41+
histogram_counter)
42+
: histogram_counter_(histogram_counter)
43+
{
44+
}
45+
46+
void record(std::uint64_t value,
47+
const opentelemetry::common::KeyValueIterable& tags,
48+
opentelemetry::context::Context& ctx)
49+
{
50+
histogram_counter_->Record(value, tags, ctx);
51+
}
52+
53+
private:
54+
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Histogram<std::uint64_t>>
55+
histogram_counter_;
56+
std::mutex mutex_;
57+
};
58+
59+
class otel_value_recorder : public couchbase::metrics::value_recorder
60+
{
61+
public:
62+
explicit otel_value_recorder(
63+
nostd::shared_ptr<metrics_api::Histogram<std::uint64_t>> histogram_counter,
64+
const std::map<std::string, std::string>& tags)
65+
: histogram_counter_(histogram_counter)
66+
, tags_(tags)
67+
{
68+
}
69+
void record_value(std::int64_t value) override
70+
{
71+
value = std::max<int64_t>(value, 0);
72+
auto uvalue = static_cast<std::uint64_t>(value);
73+
histogram_counter_->Record(
74+
uvalue, opentelemetry::common::KeyValueIterableView<decltype(tags_)>{ tags_ }, context_);
75+
}
76+
77+
auto tags() -> const std::map<std::string, std::string>
78+
{
79+
return tags_;
80+
}
81+
82+
auto histogram_counter()
83+
-> opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Histogram<std::uint64_t>>
84+
{
85+
return histogram_counter_;
86+
}
87+
88+
private:
89+
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Histogram<std::uint64_t>>
90+
histogram_counter_;
91+
const std::map<std::string, std::string> tags_;
92+
opentelemetry::context::Context context_{};
93+
std::mutex mutex_;
94+
};
95+
} // namespace
96+
97+
class otel_meter_impl
98+
{
99+
friend otel_meter;
100+
101+
public:
102+
explicit otel_meter_impl(opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Meter> meter)
103+
: meter_(meter)
104+
{
105+
}
106+
107+
private:
108+
opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Meter> meter_;
109+
std::mutex mutex_;
110+
std::multimap<std::string, std::shared_ptr<otel_value_recorder>> recorders_;
111+
};
112+
113+
auto
114+
otel_meter::get_value_recorder(const std::string& name,
115+
const std::map<std::string, std::string>& tags)
116+
-> std::shared_ptr<couchbase::metrics::value_recorder>
117+
{
118+
// first look up the histogram, in case we already have it...
119+
std::scoped_lock<std::mutex> lock(mutex_);
120+
auto it = recorders_.equal_range(name);
121+
if (it.first == it.second) {
122+
// this name isn't associated with any histogram, so make one and return it.
123+
// Note we'd like to make one with more buckets than default, given the range of
124+
// response times we'd like to display (queries vs kv for instance), but otel
125+
// api doesn't seem to allow this.
126+
return recorders_
127+
.insert({ name,
128+
std::make_shared<otel_value_recorder>(meter_->CreateUInt64Histogram(name, "", "us"),
129+
tags) })
130+
->second;
131+
}
132+
// so it is already, lets see if we already have one with those tags, or need
133+
// to make a new one (using the histogram we already have).
134+
for (auto itr = it.first; itr != it.second; itr++) {
135+
if (tags == itr->second->tags()) {
136+
return itr->second;
137+
}
138+
}
139+
// if you are here, we need to add one with these tags and the histogram associated with the
140+
// name.
141+
return recorders_
142+
.insert(
143+
{ name, std::make_shared<otel_value_recorder>(it.first->second->histogram_counter(), tags) })
144+
->second;
145+
}
146+
} // namespace couchbase::core::metrics

core/metrics/otel_meter.hxx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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 <couchbase/metrics/meter.hxx>
21+
22+
namespace couchbase::core::metrics
23+
{
24+
25+
class otel_meter_impl;
26+
27+
class otel_meter : public couchbase::metrics::meter
28+
{
29+
public:
30+
auto get_value_recorder(const std::string& name, const std::map<std::string, std::string>& tags)
31+
-> std::shared_ptr<couchbase::metrics::value_recorder> override;
32+
33+
private:
34+
std::unique_ptr<otel_meter_impl> impl_;
35+
};
36+
} // namespace couchbase::core::metrics

couchbase/metrics/otel_meter.hxx

Lines changed: 0 additions & 139 deletions
This file was deleted.

0 commit comments

Comments
 (0)