123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- #include "text.h"
- #include <library/cpp/monlib/encode/encoder_state.h>
- #include <library/cpp/monlib/metrics/labels.h>
- #include <library/cpp/monlib/metrics/metric_value.h>
- #include <util/datetime/base.h>
- #include <util/stream/format.h>
- namespace NMonitoring {
- namespace {
- class TEncoderText final: public IMetricEncoder {
- public:
- TEncoderText(IOutputStream* out, bool humanReadableTs)
- : Out_(out)
- , HumanReadableTs_(humanReadableTs)
- {
- }
- private:
- void OnStreamBegin() override {
- State_.Expect(TEncoderState::EState::ROOT);
- }
- void OnStreamEnd() override {
- State_.Expect(TEncoderState::EState::ROOT);
- }
- void OnCommonTime(TInstant time) override {
- State_.Expect(TEncoderState::EState::ROOT);
- CommonTime_ = time;
- if (time != TInstant::Zero()) {
- Out_->Write(TStringBuf("common time: "));
- WriteTime(time);
- Out_->Write('\n');
- }
- }
- void OnMetricBegin(EMetricType type) override {
- State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC);
- ClearLastMetricState();
- MetricType_ = type;
- }
- void OnMetricEnd() override {
- State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT);
- WriteMetric();
- }
- void OnLabelsBegin() override {
- if (State_ == TEncoderState::EState::METRIC) {
- State_ = TEncoderState::EState::METRIC_LABELS;
- } else if (State_ == TEncoderState::EState::ROOT) {
- State_ = TEncoderState::EState::COMMON_LABELS;
- } else {
- State_.ThrowInvalid("expected METRIC or ROOT");
- }
- }
- void OnLabelsEnd() override {
- if (State_ == TEncoderState::EState::METRIC_LABELS) {
- State_ = TEncoderState::EState::METRIC;
- } else if (State_ == TEncoderState::EState::COMMON_LABELS) {
- State_ = TEncoderState::EState::ROOT;
- Out_->Write(TStringBuf("common labels: "));
- WriteLabels();
- Out_->Write('\n');
- } else {
- State_.ThrowInvalid("expected LABELS or COMMON_LABELS");
- }
- }
- void OnLabel(TStringBuf name, TStringBuf value) override {
- Labels_.Add(name, value);
- }
- void OnDouble(TInstant time, double value) override {
- State_.Expect(TEncoderState::EState::METRIC);
- TimeSeries_.Add(time, value);
- }
- void OnInt64(TInstant time, i64 value) override {
- State_.Expect(TEncoderState::EState::METRIC);
- TimeSeries_.Add(time, value);
- }
- void OnUint64(TInstant time, ui64 value) override {
- State_.Expect(TEncoderState::EState::METRIC);
- TimeSeries_.Add(time, value);
- }
- void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override {
- State_.Expect(TEncoderState::EState::METRIC);
- TimeSeries_.Add(time, snapshot.Get());
- }
- void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override {
- State_.Expect(TEncoderState::EState::METRIC);
- TimeSeries_.Add(time, snapshot.Get());
- }
- void OnLogHistogram(TInstant ts, TLogHistogramSnapshotPtr snapshot) override {
- State_.Expect(TEncoderState::EState::METRIC);
- TimeSeries_.Add(ts, snapshot.Get());
- }
- void Close() override {
- }
- void WriteTime(TInstant time) {
- if (HumanReadableTs_) {
- char buf[64];
- auto len = FormatDate8601(buf, sizeof(buf), time.TimeT());
- Out_->Write(buf, len);
- } else {
- (*Out_) << time.Seconds();
- }
- }
- void WriteValue(EMetricValueType type, TMetricValue value) {
- switch (type) {
- case EMetricValueType::DOUBLE:
- (*Out_) << value.AsDouble();
- break;
- case EMetricValueType::INT64:
- (*Out_) << value.AsInt64();
- break;
- case EMetricValueType::UINT64:
- (*Out_) << value.AsUint64();
- break;
- case EMetricValueType::HISTOGRAM:
- (*Out_) << *value.AsHistogram();
- break;
- case EMetricValueType::SUMMARY:
- (*Out_) << *value.AsSummaryDouble();
- break;
- case EMetricValueType::LOGHISTOGRAM:
- (*Out_) << *value.AsLogHistogram();
- break;
- case EMetricValueType::UNKNOWN:
- ythrow yexception() << "unknown metric value type";
- }
- }
- void WriteLabels() {
- auto& out = *Out_;
- const auto size = Labels_.Size();
- size_t i = 0;
- out << '{';
- for (auto&& l : Labels_) {
- out << l.Name() << TStringBuf("='") << l.Value() << '\'';
- ++i;
- if (i < size) {
- out << TStringBuf(", ");
- }
- };
- out << '}';
- }
- void WriteMetric() {
- // (1) type
- TStringBuf typeStr = MetricTypeToStr(MetricType_);
- (*Out_) << LeftPad(typeStr, MaxMetricTypeNameLength) << ' ';
- // (2) name and labels
- auto name = Labels_.Extract(TStringBuf("sensor"));
- if (name) {
- if (name->Value().find(' ') != TString::npos) {
- (*Out_) << '"' << name->Value() << '"';
- } else {
- (*Out_) << name->Value();
- }
- }
- WriteLabels();
- // (3) values
- if (!TimeSeries_.Empty()) {
- TimeSeries_.SortByTs();
- Out_->Write(TStringBuf(" ["));
- for (size_t i = 0; i < TimeSeries_.Size(); i++) {
- if (i > 0) {
- Out_->Write(TStringBuf(", "));
- }
- const auto& point = TimeSeries_[i];
- if (point.GetTime() == CommonTime_ || point.GetTime() == TInstant::Zero()) {
- WriteValue(TimeSeries_.GetValueType(), point.GetValue());
- } else {
- Out_->Write('(');
- WriteTime(point.GetTime());
- Out_->Write(TStringBuf(", "));
- WriteValue(TimeSeries_.GetValueType(), point.GetValue());
- Out_->Write(')');
- }
- }
- Out_->Write(']');
- }
- Out_->Write('\n');
- }
- void ClearLastMetricState() {
- MetricType_ = EMetricType::UNKNOWN;
- Labels_.Clear();
- TimeSeries_.Clear();
- }
- private:
- TEncoderState State_;
- IOutputStream* Out_;
- bool HumanReadableTs_;
- TInstant CommonTime_ = TInstant::Zero();
- EMetricType MetricType_ = EMetricType::UNKNOWN;
- TLabels Labels_;
- TMetricTimeSeries TimeSeries_;
- };
- }
- IMetricEncoderPtr EncoderText(IOutputStream* out, bool humanReadableTs) {
- return MakeHolder<TEncoderText>(out, humanReadableTs);
- }
- }
|