aboutsummaryrefslogblamecommitdiffstats
path: root/library/cpp/monlib/encode/prometheus/prometheus_encoder_ut.cpp
blob: fd9debb060efd081814701cea15af26ed859600d (plain) (tree)
1
2
3
4
5
6
7




                                                          
                                                  













                                                           


                                                                                   






















































































                                                                                            
             
                                                        





                                                                          
                                 
             













                                                                                     



                                                  






























































































































































































































                                                                                                 










































                                                                                          
 
#include "prometheus.h"

#include <library/cpp/monlib/encode/protobuf/protobuf.h>
#include <library/cpp/monlib/metrics/metric_value.h>
#include <library/cpp/monlib/metrics/histogram_snapshot.h>

#include <library/cpp/testing/unittest/registar.h>

#include <util/stream/str.h>

using namespace NMonitoring;

Y_UNIT_TEST_SUITE(TPrometheusEncoderTest) {

    template <typename TFunc>
    TString EncodeToString(TFunc fn) {
        TStringStream ss;
        IMetricEncoderPtr encoder = EncoderPrometheus(&ss);
        fn(encoder.Get());
        return ss.Str();
    }

    ISummaryDoubleSnapshotPtr TestSummaryDouble() {
        return MakeIntrusive<TSummaryDoubleSnapshot>(10.1, -0.45, 0.478, 0.3, 30u);
    }

    Y_UNIT_TEST(Empty) {
        auto result = EncodeToString([](IMetricEncoder* e) {
            e->OnStreamBegin();
            e->OnStreamEnd();
        });
        UNIT_ASSERT_STRINGS_EQUAL(result, "\n");
    }

    Y_UNIT_TEST(DoubleGauge) {
        auto result = EncodeToString([](IMetricEncoder* e) {
            e->OnStreamBegin();
            { // no values
                e->OnMetricBegin(EMetricType::GAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "cpuUsage");
                    e->OnLabelsEnd();
                }
                e->OnMetricEnd();
            }
            { // one value no ts
                e->OnMetricBegin(EMetricType::GAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "diskUsage");
                    e->OnLabel("disk", "sda1");
                    e->OnLabelsEnd();
                }
                e->OnDouble(TInstant::Zero(), 1000);
                e->OnMetricEnd();
            }
            { // one value with ts
                e->OnMetricBegin(EMetricType::GAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "memoryUsage");
                    e->OnLabel("host", "solomon-man-00");
                    e->OnLabel("dc", "man");
                    e->OnLabelsEnd();
                }
                e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000);
                e->OnMetricEnd();
            }
            { // many values
                e->OnMetricBegin(EMetricType::GAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "bytesRx");
                    e->OnLabel("host", "solomon-sas-01");
                    e->OnLabel("dc", "sas");
                    e->OnLabelsEnd();
                }
                e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2);
                e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4);
                e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8);
                e->OnMetricEnd();
            }
            { // already seen metric name
                e->OnMetricBegin(EMetricType::GAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "diskUsage");
                    e->OnLabel("disk", "sdb1");
                    e->OnLabelsEnd();
                }
                e->OnDouble(TInstant::Zero(), 1001);
                e->OnMetricEnd();
            }
            { // NaN
                e->OnMetricBegin(EMetricType::GAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "nanValue");
                    e->OnLabelsEnd();
                }
                e->OnDouble(TInstant::Zero(), NAN);
                e->OnMetricEnd();
            }
            { // Inf
                e->OnMetricBegin(EMetricType::GAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "infValue");
                    e->OnLabelsEnd();
                }
                e->OnDouble(TInstant::Zero(), INFINITY);
                e->OnMetricEnd();
            }
            {
                e->OnMetricBegin(EMetricType::DSUMMARY);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "seconds");
                    e->OnLabel("disk", "sdb1");
                    e->OnLabelsEnd();
                }
                e->OnSummaryDouble(TInstant::Zero(), TestSummaryDouble());
                e->OnMetricEnd();
            }
            e->OnStreamEnd();
        });

        UNIT_ASSERT_STRINGS_EQUAL(result,
            "# TYPE diskUsage gauge\n"
            "diskUsage{disk=\"sda1\", } 1000\n"
            "# TYPE memoryUsage gauge\n"
            "memoryUsage{host=\"solomon-man-00\", dc=\"man\", } 1000 1512216000000\n"
            "# TYPE bytesRx gauge\n"
            "bytesRx{host=\"solomon-sas-01\", dc=\"sas\", } 8 1512216010000\n"
            "diskUsage{disk=\"sdb1\", } 1001\n"
            "# TYPE nanValue gauge\n"
            "nanValue nan\n"
            "# TYPE infValue gauge\n"
            "infValue inf\n"
            "seconds_sum{disk=\"sdb1\", } 10.1\n"
            "seconds_min{disk=\"sdb1\", } -0.45\n"
            "seconds_max{disk=\"sdb1\", } 0.478\n"
            "seconds_last{disk=\"sdb1\", } 0.3\n"
            "seconds_count{disk=\"sdb1\", } 30\n"
            "\n");
    }

    Y_UNIT_TEST(IntGauges) {
        auto result = EncodeToString([](IMetricEncoder* e) {
            e->OnStreamBegin();
            { // no values
                e->OnMetricBegin(EMetricType::IGAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "cpuUsage");
                    e->OnLabelsEnd();
                }
                e->OnMetricEnd();
            }
            { // one value no ts
                e->OnMetricBegin(EMetricType::IGAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "diskUsage");
                    e->OnLabel("disk", "sda1");
                    e->OnLabelsEnd();
                }
                e->OnInt64(TInstant::Zero(), 1000);
                e->OnMetricEnd();
            }
            { // one value with ts
                e->OnMetricBegin(EMetricType::IGAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "memoryUsage");
                    e->OnLabel("dc", "man");
                    e->OnLabel("host", "solomon-man-00");
                    e->OnLabelsEnd();
                }
                e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000);
                e->OnMetricEnd();
            }
            { // many values
                e->OnMetricBegin(EMetricType::IGAUGE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "bytesRx");
                    e->OnLabel("dc", "sas");
                    e->OnLabel("host", "solomon-sas-01");
                    e->OnLabelsEnd();
                }
                e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2);
                e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4);
                e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8);
                e->OnMetricEnd();
            }
            e->OnStreamEnd();
        });

        UNIT_ASSERT_STRINGS_EQUAL(result,
            "# TYPE diskUsage gauge\n"
            "diskUsage{disk=\"sda1\", } 1000\n"
            "# TYPE memoryUsage gauge\n"
            "memoryUsage{dc=\"man\", host=\"solomon-man-00\", } 1000 1512216000000\n"
            "# TYPE bytesRx gauge\n"
            "bytesRx{dc=\"sas\", host=\"solomon-sas-01\", } 8 1512216010000\n"
            "\n");
    }

    Y_UNIT_TEST(Counters) {
        auto result = EncodeToString([](IMetricEncoder* e) {
            e->OnStreamBegin();
            { // no values
                e->OnMetricBegin(EMetricType::COUNTER);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "cpuUsage");
                    e->OnLabelsEnd();
                }
                e->OnMetricEnd();
            }
            { // one value no ts
                e->OnMetricBegin(EMetricType::COUNTER);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "diskUsage");
                    e->OnLabel("disk", "sda1");
                    e->OnLabelsEnd();
                }
                e->OnInt64(TInstant::Zero(), 1000);
                e->OnMetricEnd();
            }
            { // one value with ts
                e->OnMetricBegin(EMetricType::COUNTER);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "memoryUsage");
                    e->OnLabel("host", "solomon-man-00");
                    e->OnLabel("dc", "man");
                    e->OnLabelsEnd();
                }
                e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000);
                e->OnMetricEnd();
            }
            { // many values
                e->OnMetricBegin(EMetricType::COUNTER);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "bytesRx");
                    e->OnLabel("host", "solomon-sas-01");
                    e->OnLabel("dc", "sas");
                    e->OnLabelsEnd();
                }
                e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2);
                e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4);
                e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8);
                e->OnMetricEnd();
            }
            e->OnStreamEnd();
        });

        UNIT_ASSERT_STRINGS_EQUAL(result,
            "# TYPE diskUsage counter\n"
            "diskUsage{disk=\"sda1\", } 1000\n"
            "# TYPE memoryUsage counter\n"
            "memoryUsage{host=\"solomon-man-00\", dc=\"man\", } 1000 1512216000000\n"
            "# TYPE bytesRx counter\n"
            "bytesRx{host=\"solomon-sas-01\", dc=\"sas\", } 8 1512216010000\n"
            "\n");
    }

    Y_UNIT_TEST(Histograms) {
        auto result = EncodeToString([](IMetricEncoder* e) {
            e->OnStreamBegin();
            { // no values histogram
                e->OnMetricBegin(EMetricType::HIST);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "cpuUsage");
                    e->OnLabelsEnd();
                }
                e->OnMetricEnd();
            }
            { // one value no ts
                e->OnMetricBegin(EMetricType::HIST);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "inboundBytesPerSec");
                    e->OnLabel("client", "mbus");
                    e->OnLabelsEnd();
                }
                e->OnHistogram(
                    TInstant::Zero(),
                    ExplicitHistogramSnapshot({10, 20, HISTOGRAM_INF_BOUND}, {1, 4, 0}));
                e->OnMetricEnd();
            }
            { // one value no ts no +inf bucket
                e->OnMetricBegin(EMetricType::HIST);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "inboundBytesPerSec");
                    e->OnLabel("client", "grpc");
                    e->OnLabelsEnd();
                }
                e->OnHistogram(
                    TInstant::Zero(),
                    ExplicitHistogramSnapshot({10, 20, 30}, {1, 4, 0}));
                e->OnMetricEnd();
            }
            { // one value with ts
                e->OnMetricBegin(EMetricType::HIST_RATE);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "outboundBytesPerSec");
                    e->OnLabel("client", "grps");
                    e->OnLabelsEnd();
                }
                e->OnHistogram(
                    TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"),
                    ExplicitHistogramSnapshot({100, 200, HISTOGRAM_INF_BOUND}, {1, 0, 0}));
                e->OnMetricEnd();
            }
            { // many values
                e->OnMetricBegin(EMetricType::HIST);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "bytesRx");
                    e->OnLabel("host", "solomon-sas-01");
                    e->OnLabel("dc", "sas");
                    e->OnLabelsEnd();
                }
                TBucketBounds bounds = {100, 200, HISTOGRAM_INF_BOUND};
                e->OnHistogram(
                    TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"),
                    ExplicitHistogramSnapshot(bounds, {10, 0, 0}));
                e->OnHistogram(
                    TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"),
                    ExplicitHistogramSnapshot(bounds, {10, 2, 0}));
                e->OnHistogram(
                    TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"),
                    ExplicitHistogramSnapshot(bounds, {10, 2, 5}));
                e->OnMetricEnd();
            }
            e->OnStreamEnd();
        });

        UNIT_ASSERT_STRINGS_EQUAL(result,
            "# TYPE inboundBytesPerSec histogram\n"
            "inboundBytesPerSec_bucket{client=\"mbus\", le=\"10\"} 1\n"
            "inboundBytesPerSec_bucket{client=\"mbus\", le=\"20\"} 5\n"
            "inboundBytesPerSec_bucket{client=\"mbus\", le=\"+Inf\"} 5\n"
            "inboundBytesPerSec_count{client=\"mbus\", } 5\n"
            "inboundBytesPerSec_bucket{client=\"grpc\", le=\"10\"} 1\n"
            "inboundBytesPerSec_bucket{client=\"grpc\", le=\"20\"} 5\n"
            "inboundBytesPerSec_bucket{client=\"grpc\", le=\"30\"} 5\n"
            "inboundBytesPerSec_count{client=\"grpc\", } 5\n"
            "# TYPE outboundBytesPerSec histogram\n"
            "outboundBytesPerSec_bucket{client=\"grps\", le=\"100\"} 1 1512216000000\n"
            "outboundBytesPerSec_bucket{client=\"grps\", le=\"200\"} 1 1512216000000\n"
            "outboundBytesPerSec_bucket{client=\"grps\", le=\"+Inf\"} 1 1512216000000\n"
            "outboundBytesPerSec_count{client=\"grps\", } 1 1512216000000\n"
            "# TYPE bytesRx histogram\n"
            "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"100\"} 10 1512216010000\n"
            "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"200\"} 12 1512216010000\n"
            "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"+Inf\"} 17 1512216010000\n"
            "bytesRx_count{host=\"solomon-sas-01\", dc=\"sas\", } 17 1512216010000\n"
            "\n");
    }

    Y_UNIT_TEST(CommonLables) {
        auto result = EncodeToString([](IMetricEncoder* e) {
            e->OnStreamBegin();
            { // common time
                e->OnCommonTime(TInstant::Seconds(1500000000));
            }
            { // common labels
                e->OnLabelsBegin();
                e->OnLabel("project", "solomon");
                e->OnLabelsEnd();
            }
            { // metric #1
                e->OnMetricBegin(EMetricType::COUNTER);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "single");
                    e->OnLabel("labels", "l1");
                    e->OnLabelsEnd();
                }
                e->OnUint64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 17);
                e->OnMetricEnd();
            }
            { // metric #2
                e->OnMetricBegin(EMetricType::COUNTER);
                {
                    e->OnLabelsBegin();
                    e->OnLabel("sensor", "two");
                    e->OnLabel("labels", "l2");
                    e->OnLabelsEnd();
                }
                e->OnUint64(TInstant::Zero(), 42);
                e->OnMetricEnd();
            }
            e->OnStreamEnd();
        });
    UNIT_ASSERT_STRINGS_EQUAL(result,
R"(# TYPE single counter
single{labels="l1", project="solomon", } 17 1512216010000
# TYPE two counter
two{labels="l2", project="solomon", } 42 1500000000000

)");
    }
}