Skip to content

Commit 342de5e

Browse files
ashish-250gjasny
authored andcommitted
fix(core): Locale-independent floating-point serialization
Fixes: #509
1 parent 95ea1a3 commit 342de5e

File tree

1 file changed

+9
-32
lines changed

1 file changed

+9
-32
lines changed

core/src/text_serializer.cc

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
11
#include "prometheus/text_serializer.h"
22

3-
#include <array>
43
#include <cmath>
4+
#include <limits>
55
#include <locale>
66
#include <ostream>
7-
#include <stdexcept>
87
#include <string>
98

10-
#if __cpp_lib_to_chars >= 201611L
11-
#include <charconv>
12-
#include <stdexcept>
13-
#include <system_error>
14-
#else
15-
#include <cstdio>
16-
#include <limits>
17-
#endif
18-
199
#include "prometheus/client_metric.h"
2010
#include "prometheus/metric_family.h"
2111
#include "prometheus/metric_type.h"
@@ -31,26 +21,7 @@ void WriteValue(std::ostream& out, double value) {
3121
} else if (std::isinf(value)) {
3222
out << (value < 0 ? "-Inf" : "+Inf");
3323
} else {
34-
std::array<char, 128> buffer;
35-
36-
#if __cpp_lib_to_chars >= 201611L
37-
auto [ptr, ec] =
38-
std::to_chars(buffer.data(), buffer.data() + buffer.size(), value);
39-
if (ec != std::errc()) {
40-
throw std::runtime_error("Could not convert double to string: " +
41-
std::make_error_code(ec).message());
42-
}
43-
out.write(buffer.data(), ptr - buffer.data());
44-
#else
45-
auto wouldHaveWritten =
46-
std::snprintf(buffer.data(), buffer.size(), "%.*g",
47-
std::numeric_limits<double>::max_digits10 - 1, value);
48-
if (wouldHaveWritten <= 0 ||
49-
static_cast<std::size_t>(wouldHaveWritten) >= buffer.size()) {
50-
throw std::runtime_error("Could not convert double to string");
51-
}
52-
out.write(buffer.data(), wouldHaveWritten);
53-
#endif
24+
out << value;
5425
}
5526
}
5627

@@ -217,11 +188,17 @@ void SerializeFamily(std::ostream& out, const MetricFamily& family) {
217188

218189
void TextSerializer::Serialize(std::ostream& out,
219190
const std::vector<MetricFamily>& metrics) const {
220-
std::locale saved_locale = out.getloc();
191+
auto saved_locale = out.getloc();
192+
auto saved_precision = out.precision();
193+
221194
out.imbue(std::locale::classic());
195+
out.precision(std::numeric_limits<double>::max_digits10 - 1);
196+
222197
for (auto& family : metrics) {
223198
SerializeFamily(out, family);
224199
}
200+
225201
out.imbue(saved_locale);
202+
out.precision(saved_precision);
226203
}
227204
} // namespace prometheus

0 commit comments

Comments
 (0)