Skip to content

Commit

Permalink
Refactor serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
jupp0r committed Oct 15, 2016
1 parent f03cbe7 commit 6f84912
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 72 deletions.
151 changes: 79 additions & 72 deletions lib/exposer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/message_differencer.h>

#include "exposer.h"

Expand All @@ -27,31 +28,53 @@ MetricsHandler::MetricsHandler(
numScrapes_(numScrapesFamily_->add({})) {}

static std::string serializeToDelimitedProtobuf(
const std::vector<std::weak_ptr<Collectable>>& collectables) {
const std::vector<io::prometheus::client::MetricFamily>& metrics) {
std::ostringstream ss;
for (auto&& wcollectable : collectables) {
auto collectable = wcollectable.lock();
if (!collectable) {
continue;
for (auto&& metric : metrics) {
{
google::protobuf::io::OstreamOutputStream rawOutput{&ss};
google::protobuf::io::CodedOutputStream output(&rawOutput);

const int size = metric.ByteSize();
output.WriteVarint32(size);
}

for (auto&& metricFamily : collectable->collect()) {
{
google::protobuf::io::OstreamOutputStream rawOutput{&ss};
google::protobuf::io::CodedOutputStream output(&rawOutput);
auto buffer = std::string{};
metric.SerializeToString(&buffer);
ss << buffer;
}
return ss.str();
}

static std::string serializeToJson(
const std::vector<io::prometheus::client::MetricFamily>& metrics) {
using google::protobuf::util::MessageDifferencer;

const int size = metricFamily.ByteSize();
output.WriteVarint32(size);
}
std::stringstream ss;
ss << "[";

auto buffer = std::string{};
metricFamily.SerializeToString(&buffer);
ss << buffer;
for (auto&& metric : metrics) {
std::string result;
google::protobuf::util::MessageToJsonString(
metric, &result, google::protobuf::util::JsonPrintOptions());
ss << result;
if (!MessageDifferencer::Equals(metric, metrics.back())) {
ss << ",";
}
}
ss << "]";
return ss.str();
}

static std::string serializeToHumanReadable(
const std::vector<io::prometheus::client::MetricFamily>& metrics) {
auto result = std::string{};
for (auto&& metric : metrics) {
result += metric.DebugString() + "\n";
}
return result;
}

static std::string getAcceptedEncoding(struct mg_connection* conn) {
auto request_info = mg_get_request_info(conn);
for (int i = 0; i < request_info->num_headers; i++) {
Expand All @@ -68,69 +91,35 @@ bool MetricsHandler::handleGet(CivetServer* server,
using namespace io::prometheus::client;

auto acceptedEncoding = getAcceptedEncoding(conn);
auto metrics = collectMetrics();

auto body = std::string{};
auto contentType = std::string{};

if (acceptedEncoding.find("application/vnd.google.protobuf") !=
std::string::npos) {
auto body = serializeToDelimitedProtobuf(collectables_);
mg_printf(conn,
"HTTP/1.1 200 OK\r\n"
"Content-Type: "
"application/vnd.google.protobuf; "
"proto=io.prometheus.client.MetricFamily; "
"encoding=delimited\r\n"
"Content-Length: ");
mg_printf(conn, "%lu\r\n\r\n", body.size());
mg_write(conn, body.data(), body.size());
bytesTransfered_->inc(body.size());
body = serializeToDelimitedProtobuf(metrics);
contentType =
"application/vnd.google.protobuf; "
"proto=io.prometheus.client.MetricFamily; "
"encoding=delimited";
} else if (acceptedEncoding.find("application/json") != std::string::npos) {
std::stringstream ss;
ss << "[";

for (auto&& wcollectable : collectables_) {
auto collectable = wcollectable.lock();
if (!collectable) {
continue;
}

for (auto&& metricFamily : collectable->collect()) {
std::string result;
google::protobuf::util::MessageToJsonString(
metricFamily, &result, google::protobuf::util::JsonPrintOptions());
ss << result;
if (collectable != collectables_.back().lock()) {
ss << ",";
}
}
}
ss << "]";
auto body = ss.str();
mg_printf(conn,
"HTTP/1.1 200 OK\r\n"
"Content-Type: application/json\r\n"
"Content-Length: ");
mg_printf(conn, "%lu\r\n\r\n", body.size());
mg_write(conn, body.data(), body.size());
bytesTransfered_->inc(body.size());
body = serializeToJson(metrics);
contentType = "application/json";
} else {
auto body = std::string{};
for (auto&& wcollectable : collectables_) {
auto collectable = wcollectable.lock();
if (!collectable) {
continue;
}

for (auto&& metricFamily : collectable->collect()) {
body += metricFamily.DebugString() + "\n";
}
mg_printf(conn,
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: ");
mg_printf(conn, "%lu\r\n\r\n", body.size());
mg_write(conn, body.data(), body.size());
bytesTransfered_->inc(body.size());
}
body = serializeToHumanReadable(metrics);
contentType = "text/plain";
}

mg_printf(conn,
"HTTP/1.1 200 OK\r\n"
"Content-Type: %s\r\n",
contentType.c_str());
mg_printf(conn, "Content-Length: %lu\r\n\r\n", body.size());
mg_write(conn, body.data(), body.size());

bytesTransfered_->inc(body.size());

numScrapes_->inc();
return true;
}
Expand All @@ -148,4 +137,22 @@ void Exposer::registerCollectable(
const std::weak_ptr<Collectable>& collectable) {
collectables_.push_back(collectable);
}

std::vector<io::prometheus::client::MetricFamily>
MetricsHandler::collectMetrics() const {
auto collectedMetrics = std::vector<io::prometheus::client::MetricFamily>{};

for (auto&& wcollectable : collectables_) {
auto collectable = wcollectable.lock();
if (!collectable) {
continue;
}

for (auto metric : collectable->collect()) {
collectedMetrics.push_back(metric);
}
}

return collectedMetrics;
}
}
3 changes: 3 additions & 0 deletions lib/exposer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class MetricsHandler : public CivetHandler {

bool handleGet(CivetServer* server, struct mg_connection* conn);

private:
std::vector<io::prometheus::client::MetricFamily> collectMetrics() const;

const std::vector<std::weak_ptr<Collectable>>& collectables_;
Family<Counter>* bytesTransferedFamily_;
Counter* bytesTransfered_;
Expand Down

0 comments on commit 6f84912

Please sign in to comment.