Skip to content

Commit 765e2cb

Browse files
committed
Define observability interface between core SDK and the wrapper
1 parent 46cc8dd commit 765e2cb

18 files changed

+2891
-0
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ set(couchbase_cxx_client_FILES
393393
core/scan_result.cxx
394394
core/search_query_options.cxx
395395
core/seed_config.cxx
396+
core/signal_bridge.cxx
397+
core/signal_data.cxx
398+
core/metric_measurement.cxx
399+
core/chrono_utils.cxx
396400
core/topology/capabilities.cxx
397401
core/topology/configuration.cxx
398402
core/tracing/threshold_logging_tracer.cxx

core/chrono_utils.cxx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2025-Current 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+
#include "chrono_utils.hxx"
19+
20+
#include <array>
21+
#include <chrono>
22+
#include <stdexcept>
23+
24+
namespace couchbase::core
25+
{
26+
auto
27+
to_iso8601_utc(std::time_t time_in_seconds, std::int64_t microseconds) -> std::string
28+
{
29+
std::tm tm{};
30+
#if defined(_MSC_VER)
31+
gmtime_s(&tm, &time_in_seconds);
32+
#else
33+
gmtime_r(&time_in_seconds, &tm);
34+
#endif
35+
36+
std::array<char, 100> buffer{};
37+
auto rc = std::snprintf(buffer.data(),
38+
buffer.size(),
39+
"%04d-%02d-%02dT%02d:%02d:%02d.%06lldZ",
40+
tm.tm_year + 1900,
41+
tm.tm_mon + 1,
42+
tm.tm_mday,
43+
tm.tm_hour,
44+
tm.tm_min,
45+
tm.tm_sec,
46+
static_cast<long long>(microseconds));
47+
auto bytes_written = static_cast<std::size_t>(rc);
48+
if (rc < 0 || bytes_written >= buffer.size()) {
49+
throw std::range_error("unable to format date: not enough memory in the buffer");
50+
}
51+
return { buffer.data(), bytes_written };
52+
}
53+
54+
auto
55+
to_iso8601_utc(const std::chrono::system_clock::time_point& time_point) -> std::string
56+
{
57+
const auto duration{ time_point.time_since_epoch() };
58+
const auto seconds{ std::chrono::duration_cast<std::chrono::seconds>(duration) };
59+
const auto micros{ std::chrono::duration_cast<std::chrono::microseconds>(duration - seconds) };
60+
61+
return to_iso8601_utc(std::chrono::system_clock::to_time_t(time_point), micros.count());
62+
}
63+
} // namespace couchbase::core

core/chrono_utils.hxx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2025-Current 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 <chrono>
21+
#include <string>
22+
23+
namespace couchbase::core
24+
{
25+
auto
26+
to_iso8601_utc(std::time_t time_in_seconds, std::int64_t microseconds = 0) -> std::string;
27+
28+
auto
29+
to_iso8601_utc(const std::chrono::system_clock::time_point& time_point) -> std::string;
30+
} // namespace couchbase::core

core/log_entry.hxx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2025-Current 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 "signal_attribute.hxx"
21+
22+
#include <string>
23+
#include <vector>
24+
25+
namespace couchbase::core
26+
{
27+
struct log_entry {
28+
std::string timestamp;
29+
std::string severity;
30+
std::string message;
31+
32+
struct {
33+
std::string trace_id{};
34+
std::string span_id{};
35+
} context{};
36+
37+
std::vector<signal_attribute> attributes{};
38+
};
39+
40+
inline auto
41+
operator==(const log_entry& lhs, const log_entry& rhs) -> bool
42+
{
43+
return lhs.timestamp == rhs.timestamp && //
44+
lhs.severity == rhs.severity && //
45+
lhs.message == rhs.message && //
46+
lhs.context.trace_id == rhs.context.trace_id && //
47+
lhs.context.span_id == rhs.context.span_id && //
48+
lhs.attributes == rhs.attributes;
49+
}
50+
51+
inline auto
52+
operator!=(const log_entry& lhs, const log_entry& rhs) -> bool
53+
{
54+
return !(lhs == rhs);
55+
}
56+
} // namespace couchbase::core

core/metric_measurement.cxx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2025-Current 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+
#include "metric_measurement.hxx"
19+
20+
namespace couchbase::core
21+
{
22+
23+
[[nodiscard]] auto
24+
metric_measurement::is_double() const noexcept -> bool
25+
{
26+
return std::holds_alternative<double>(value_);
27+
}
28+
29+
[[nodiscard]] auto
30+
metric_measurement::as_double() const -> double
31+
{
32+
return std::get<double>(value_);
33+
}
34+
35+
[[nodiscard]] auto
36+
metric_measurement::try_as_double() && -> std::optional<double>
37+
{
38+
if (auto* ptr = std::get_if<double>(&value_)) {
39+
return *ptr;
40+
}
41+
return std::nullopt;
42+
}
43+
44+
[[nodiscard]] auto
45+
metric_measurement::is_int64() const noexcept -> bool
46+
{
47+
return std::holds_alternative<std::int64_t>(value_);
48+
}
49+
50+
[[nodiscard]] auto
51+
metric_measurement::as_int64() const -> std::int64_t
52+
{
53+
return std::get<std::int64_t>(value_);
54+
}
55+
56+
[[nodiscard]] auto
57+
metric_measurement::try_as_int64() && -> std::optional<std::int64_t>
58+
{
59+
if (auto* ptr = std::get_if<std::int64_t>(&value_)) {
60+
return *ptr;
61+
}
62+
return std::nullopt;
63+
}
64+
65+
} // namespace couchbase::core

core/metric_measurement.hxx

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2025-Current 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 <cstdint>
21+
#include <optional>
22+
#include <string>
23+
#include <utility>
24+
#include <variant>
25+
26+
namespace couchbase::core
27+
{
28+
class metric_measurement
29+
{
30+
public:
31+
template<typename Float, std::enable_if_t<std::is_floating_point_v<Float>, int> = 0>
32+
metric_measurement(std::string name, Float value)
33+
: name_{ std::move(name) }
34+
, value_{ value }
35+
{
36+
}
37+
38+
template<
39+
typename Integer,
40+
std::enable_if_t<std::is_integral_v<Integer> && std::is_signed_v<Integer> &&
41+
!std::is_same_v<Integer, bool> && sizeof(Integer) <= sizeof(std::int64_t),
42+
int> = 0>
43+
metric_measurement(std::string name, Integer value)
44+
: name_{ std::move(name) }
45+
, value_{ value }
46+
{
47+
}
48+
49+
metric_measurement(const metric_measurement&) = default;
50+
metric_measurement(metric_measurement&&) = default;
51+
~metric_measurement() = default;
52+
auto operator=(const metric_measurement&) -> metric_measurement& = default;
53+
auto operator=(metric_measurement&&) -> metric_measurement& = default;
54+
55+
[[nodiscard]] auto is_double() const noexcept -> bool;
56+
[[nodiscard]] auto as_double() const -> double;
57+
[[nodiscard]] auto try_as_double() && -> std::optional<double>;
58+
explicit operator double() const
59+
{
60+
return as_double();
61+
}
62+
63+
[[nodiscard]] auto is_int64() const noexcept -> bool;
64+
[[nodiscard]] auto as_int64() const -> std::int64_t;
65+
[[nodiscard]] auto try_as_int64() && -> std::optional<std::int64_t>;
66+
explicit operator std::int64_t() const
67+
{
68+
return as_int64();
69+
}
70+
71+
friend auto operator==(const metric_measurement& lhs, const metric_measurement& rhs) -> bool;
72+
73+
private:
74+
std::string name_;
75+
std::variant<double, std::int64_t> value_;
76+
};
77+
78+
inline auto
79+
operator==(const metric_measurement& lhs, const metric_measurement& rhs) -> bool
80+
{
81+
return lhs.name_ == rhs.name_ && //
82+
lhs.value_ == rhs.value_;
83+
}
84+
85+
inline auto
86+
operator!=(const metric_measurement& lhs, const metric_measurement& rhs) -> bool
87+
{
88+
return !(lhs == rhs);
89+
}
90+
} // namespace couchbase::core

core/signal_attribute.hxx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2025-Current 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 <string>
21+
22+
namespace couchbase::core
23+
{
24+
struct signal_attribute {
25+
std::string name;
26+
std::string value;
27+
};
28+
29+
inline auto
30+
operator==(const signal_attribute& lhs, const signal_attribute& rhs) -> bool
31+
{
32+
return lhs.name == rhs.name && //
33+
lhs.value == rhs.value;
34+
}
35+
36+
inline auto
37+
operator!=(const signal_attribute& lhs, const signal_attribute& rhs) -> bool
38+
{
39+
return !(lhs == rhs);
40+
}
41+
42+
} // namespace couchbase::core

0 commit comments

Comments
 (0)