Add JSON publisher

pull/493/head
Michael 5 years ago
parent a2187cadb4
commit 6f23cbe176
No known key found for this signature in database
GPG Key ID: 2D51757B47E2434C

@ -1,5 +1,6 @@
#include <util/metrics_publishers.hpp>
#include <fstream>
#include <iostream>
namespace llarp
@ -48,6 +49,7 @@ namespace llarp
stream << value;
}
}
void
formatValue(std::ostream &stream, const Record &record,
double elapsedTime, Publication::Type publicationType,
@ -156,33 +158,165 @@ namespace llarp
stream << " ]\n";
}
void
formatValue(nlohmann::json &result, const Record &record,
double elapsedTime, Publication::Type publicationType)
{
switch(publicationType)
{
case Publication::Type::Unspecified:
{
assert(false && "Invalid publication type");
}
break;
case Publication::Type::Total:
{
result["total"] = record.total();
}
break;
case Publication::Type::Count:
{
result["count"] = record.count();
}
break;
case Publication::Type::Min:
{
result["min"] = record.min();
}
break;
case Publication::Type::Max:
{
result["max"] = record.max();
}
break;
case Publication::Type::Avg:
{
result["avg"] = record.total() / record.count();
}
break;
case Publication::Type::Rate:
{
result["rate"] = record.total() / elapsedTime;
}
break;
case Publication::Type::RateCount:
{
result["rateCount"] = record.count() / elapsedTime;
}
break;
}
}
nlohmann::json
recordToJson(const Record &record, double elapsedTime)
{
nlohmann::json result;
result["id"] = record.id().toString();
auto publicationType = record.id().description()->type();
if(publicationType != Publication::Type::Unspecified)
{
result["publicationType"] = Publication::repr(publicationType);
formatValue(result, record, elapsedTime, publicationType);
}
else
{
result["count"] = record.count();
result["total"] = record.total();
if(Record::DEFAULT_MIN != record.min())
{
result["min"] = record.min();
}
if(Record::DEFAULT_MAX == record.max())
{
result["max"] = record.max();
}
}
return result;
}
} // namespace
void
StreamPublisher::publish(const Sample &values)
{
if(values.recordCount() > 0)
if(values.recordCount() == 0)
{
// nothing to publish
return;
}
m_stream << values.sampleTime() << " " << values.recordCount()
<< " Records\n";
auto gIt = values.begin();
auto prev = values.begin();
for(; gIt != values.end(); ++gIt)
{
m_stream << values.sampleTime() << " " << values.recordCount()
<< " Records\n";
const double elapsedTime = absl::ToDoubleSeconds(gIt->samplePeriod());
auto gIt = values.begin();
auto prev = values.begin();
for(; gIt != values.end(); ++gIt)
if(gIt == prev || gIt->samplePeriod() != prev->samplePeriod())
{
const double elapsedTime = absl::ToDoubleSeconds(gIt->samplePeriod());
m_stream << "\tElapsed Time: " << elapsedTime << "s\n";
}
if(gIt == prev || gIt->samplePeriod() != prev->samplePeriod())
{
m_stream << "\tElapsed Time: " << elapsedTime << "s\n";
}
for(const auto &record : *gIt)
{
publishRecord(m_stream, record, elapsedTime);
}
prev = gIt;
}
}
for(const auto &record : *gIt)
{
publishRecord(m_stream, record, elapsedTime);
}
prev = gIt;
void
JsonPublisher::publish(const Sample &values)
{
if(values.recordCount() == 0)
{
// nothing to publish
return;
}
nlohmann::json result;
result["sampleTime"] = absl::UnparseFlag(values.sampleTime());
result["recordCount"] = values.recordCount();
auto gIt = values.begin();
auto prev = values.begin();
for(; gIt != values.end(); ++gIt)
{
const double elapsedTime = absl::ToDoubleSeconds(gIt->samplePeriod());
if(gIt == prev || gIt->samplePeriod() != prev->samplePeriod())
{
result["elapsedTime"] = elapsedTime;
}
for(const auto &record : *gIt)
{
result["record"].emplace_back(recordToJson(record, elapsedTime));
}
prev = gIt;
}
m_publish(result);
}
void
JsonPublisher::directoryPublisher(const nlohmann::json &result,
fs::path path)
{
std::ofstream fstream(path.string(), std::ios_base::app);
if(!fstream)
{
std::cerr << "Skipping metrics publish, " << path << " is not a file\n";
abort();
}
fstream << std::setw(0) << result << '\n';
fstream.close();
}
} // namespace metrics
} // namespace llarp

@ -3,7 +3,10 @@
#include <util/metrics_core.hpp>
#include <util/fs.hpp>
#include <iosfwd>
#include <nlohmann/json.hpp>
namespace llarp
{
@ -25,6 +28,30 @@ namespace llarp
void
publish(const Sample& values) override;
};
class JsonPublisher final : public Publisher
{
public:
using PublishFunction = std::function< void(const nlohmann::json&) >;
private:
PublishFunction m_publish;
public:
JsonPublisher(const PublishFunction& publish) : m_publish(publish)
{
}
~JsonPublisher()
{
}
void
publish(const Sample& values) override;
static void
directoryPublisher(const nlohmann::json& result, fs::path path);
};
} // namespace metrics
} // namespace llarp

@ -123,6 +123,13 @@ namespace llarp
return stream;
}
std::string
Description::toString() const
{
util::Lock l(&m_mutex);
return m_category->name() + std::string(".") + m_name;
}
std::ostream &
Description::print(std::ostream &stream) const
{

@ -248,6 +248,9 @@ namespace llarp
return m_format;
}
std::string
toString() const;
std::ostream &
print(std::ostream &stream) const;
};
@ -317,6 +320,20 @@ namespace llarp
return m_description->name();
}
std::string
toString() const
{
if(m_description)
{
return m_description->toString();
;
}
else
{
return "INVALID_METRIC";
}
}
std::ostream &
print(std::ostream &stream, int, int) const
{

Loading…
Cancel
Save