diff options
author | Alexander Smirnov <alex@ydb.tech> | 2025-03-04 16:15:41 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2025-03-04 16:15:41 +0000 |
commit | b21a377d1f5b24149cf65fd1f8feb44411ae38f9 (patch) | |
tree | 0459a651275d60cf60489d8142f20a8bd5e6a199 /library | |
parent | 827cd39b843ead1adfaa20f8a55e2e17da62a4eb (diff) | |
parent | 00325857a11f51ad6b43a4d35f57e85e06866ab6 (diff) | |
download | ydb-b21a377d1f5b24149cf65fd1f8feb44411ae38f9.tar.gz |
Merge pull request #15307 from ydb-platform/merge-libs-250304-1328
Diffstat (limited to 'library')
21 files changed, 603 insertions, 67 deletions
diff --git a/library/cpp/http/simple/http_client.cpp b/library/cpp/http/simple/http_client.cpp index 2be5a14582..6fb0475539 100644 --- a/library/cpp/http/simple/http_client.cpp +++ b/library/cpp/http/simple/http_client.cpp @@ -195,28 +195,28 @@ void TSimpleHttpClient::EnableVerificationForHttps() { HttpsVerification = true; } -void TSimpleHttpClient::DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers, NThreading::TCancellationToken cancellation) const { +void TSimpleHttpClient::DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers, THttpHeaders* outHeaders, NThreading::TCancellationToken cancellation) const { TKeepAliveHttpClient cl = CreateClient(); - TKeepAliveHttpClient::THttpCode code = cl.DoGet(relativeUrl, output, headers, nullptr, std::move(cancellation)); + TKeepAliveHttpClient::THttpCode code = cl.DoGet(relativeUrl, output, headers, outHeaders, std::move(cancellation)); Y_ENSURE(cl.GetHttpInput()); ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code); } -void TSimpleHttpClient::DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THashMap<TString, TString>& headers, NThreading::TCancellationToken cancellation) const { +void TSimpleHttpClient::DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THashMap<TString, TString>& headers, THttpHeaders* outHeaders, NThreading::TCancellationToken cancellation) const { TKeepAliveHttpClient cl = CreateClient(); - TKeepAliveHttpClient::THttpCode code = cl.DoPost(relativeUrl, body, output, headers, nullptr, std::move(cancellation)); + TKeepAliveHttpClient::THttpCode code = cl.DoPost(relativeUrl, body, output, headers, outHeaders, std::move(cancellation)); Y_ENSURE(cl.GetHttpInput()); ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code); } -void TSimpleHttpClient::DoPostRaw(const TStringBuf relativeUrl, const TStringBuf rawRequest, IOutputStream* output, NThreading::TCancellationToken cancellation) const { +void TSimpleHttpClient::DoPostRaw(const TStringBuf relativeUrl, const TStringBuf rawRequest, IOutputStream* output, THttpHeaders* outHeaders, NThreading::TCancellationToken cancellation) const { TKeepAliveHttpClient cl = CreateClient(); - TKeepAliveHttpClient::THttpCode code = cl.DoRequestRaw(rawRequest, output, nullptr, std::move(cancellation)); + TKeepAliveHttpClient::THttpCode code = cl.DoRequestRaw(rawRequest, output, outHeaders, std::move(cancellation)); Y_ENSURE(cl.GetHttpInput()); ProcessResponse(relativeUrl, *cl.GetHttpInput(), output, code); diff --git a/library/cpp/http/simple/http_client.h b/library/cpp/http/simple/http_client.h index 86a8cb4e99..3860862698 100644 --- a/library/cpp/http/simple/http_client.h +++ b/library/cpp/http/simple/http_client.h @@ -172,13 +172,13 @@ public: void EnableVerificationForHttps(); - void DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers = THeaders(), NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const; + void DoGet(const TStringBuf relativeUrl, IOutputStream* output, const THeaders& headers = THeaders(), THttpHeaders* outHeaders = nullptr, NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const; // builds post request from headers and body - void DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THeaders& headers = THeaders(), NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const; + void DoPost(const TStringBuf relativeUrl, TStringBuf body, IOutputStream* output, const THeaders& headers = THeaders(), THttpHeaders* outHeaders = nullptr, NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const; // requires already well-formed post request - void DoPostRaw(const TStringBuf relativeUrl, TStringBuf rawRequest, IOutputStream* output, NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const; + void DoPostRaw(const TStringBuf relativeUrl, TStringBuf rawRequest, IOutputStream* output, THttpHeaders* outHeaders = nullptr, NThreading::TCancellationToken cancellation = NThreading::TCancellationToken::Default()) const; virtual ~TSimpleHttpClient(); diff --git a/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp b/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp index 87c832d642..c0449a10ff 100644 --- a/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp +++ b/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp @@ -144,6 +144,12 @@ void TBufferedEncoderBase::OnLogHistogram(TInstant time, TLogHistogramSnapshotPt metric.TimeSeries.Add(time, s.Get()); } +void TBufferedEncoderBase::OnMemOnly(bool isMemOnly) { + State_.Expect(TEncoderState::EState::METRIC); + TMetric& metric = Metrics_.back(); + metric.IsMemOnly = isMemOnly; +} + TString TBufferedEncoderBase::FormatLabels(const TPooledLabels& labels) const { auto formattedLabels = TVector<TString>(Reserve(labels.size() + CommonLabels_.size())); auto addLabel = [&](const TPooledLabel& l) { diff --git a/library/cpp/monlib/encode/buffered/buffered_encoder_base.h b/library/cpp/monlib/encode/buffered/buffered_encoder_base.h index fe3714e58f..dab5671ad4 100644 --- a/library/cpp/monlib/encode/buffered/buffered_encoder_base.h +++ b/library/cpp/monlib/encode/buffered/buffered_encoder_base.h @@ -37,6 +37,8 @@ public: void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override; void OnLogHistogram(TInstant, TLogHistogramSnapshotPtr) override; + void OnMemOnly(bool isMemOnly) override; + protected: using TPooledStr = TStringPoolBuilder::TValue; @@ -80,6 +82,7 @@ protected: EMetricType MetricType = EMetricType::UNKNOWN; TPooledLabels Labels; TMetricTimeSeries TimeSeries; + bool IsMemOnly; }; protected: diff --git a/library/cpp/monlib/encode/fake/fake.cpp b/library/cpp/monlib/encode/fake/fake.cpp index 69d691361a..e3db20cbd1 100644 --- a/library/cpp/monlib/encode/fake/fake.cpp +++ b/library/cpp/monlib/encode/fake/fake.cpp @@ -43,6 +43,9 @@ namespace NMonitoring { void Close() override { } + + void OnMemOnly(bool) override { + } }; IMetricEncoderPtr EncoderFake() { diff --git a/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp b/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp index 2d11b9d5ba..2cffda13ac 100644 --- a/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp +++ b/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp @@ -227,6 +227,11 @@ namespace NMonitoring { FillLogHistogram(*snapshot, point->MutableLogHistogram()); } + void OnMemOnly(bool isMemOnly) override { + Y_ENSURE(Sample_, "metric not started"); + Sample_->SetIsMemOnly(isMemOnly); + } + void Close() override { } diff --git a/library/cpp/monlib/encode/protobuf/protos/samples.proto b/library/cpp/monlib/encode/protobuf/protos/samples.proto index 371f4181d2..a3ca917221 100644 --- a/library/cpp/monlib/encode/protobuf/protos/samples.proto +++ b/library/cpp/monlib/encode/protobuf/protos/samples.proto @@ -59,7 +59,7 @@ message TPoint { message TSingleSample { repeated TLabel Labels = 1; EMetricType MetricType = 2; - + bool IsMemOnly = 10; // inlined TPoint uint64 Time = 3; oneof Value { @@ -76,6 +76,7 @@ message TMultiSample { repeated TLabel Labels = 1; EMetricType MetricType = 2; repeated TPoint Points = 3; + bool IsMemOnly = 4; } message TSingleSamplesList { diff --git a/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp b/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp index 384ef456dd..a236bb9a50 100644 --- a/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp +++ b/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp @@ -107,15 +107,15 @@ namespace NMonitoring { c->OnMetricBegin(metricType); - // TODO: use it - ReadFixed<ui8>(); // skip flags byte + // (5.2) flags byte + c->OnMemOnly(ReadFixed<ui8>() & 0x01); auto metricNameValueIndex = std::numeric_limits<ui32>::max(); if (Header_.Version >= SV1_02) { metricNameValueIndex = ReadVarint(); } - // (5.2) labels + // (5.3) labels ui32 labelsCount = ReadVarint(); DECODE_ENSURE(Header_.Version >= SV1_02 || labelsCount > 0, "metric #" << i << " has no labels"); c->OnLabelsBegin(); @@ -125,7 +125,7 @@ namespace NMonitoring { ReadLabels(labelNames, labelValues, labelsCount, c); c->OnLabelsEnd(); - // (5.3) values + // (5.4) values switch (valueType) { case EValueType::NONE: break; diff --git a/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp b/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp index 7e13c3292b..70c5bba551 100644 --- a/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp +++ b/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp @@ -68,6 +68,10 @@ namespace NMonitoring { TBufferedEncoderBase::OnLogHistogram(time, snapshot); } + void OnMemOnly(bool isMemOnly) override { + TBufferedEncoderBase::OnMemOnly(isMemOnly); + } + void Close() override { if (Closed_) { return; @@ -128,8 +132,8 @@ namespace NMonitoring { ui8 typesByte = PackTypes(metric); Out_->Write(&typesByte, sizeof(typesByte)); - // TODO: implement - ui8 flagsByte = 0x00; + // (5.2) flags byte + ui8 flagsByte = metric.IsMemOnly & 0x01; Out_->Write(&flagsByte, sizeof(flagsByte)); // v1.2 format addition — metric name @@ -143,10 +147,10 @@ namespace NMonitoring { WriteVarUInt32(Out_, it->Value->Index); } - // (5.2) labels + // (5.3) labels WriteLabels(metric.Labels, MetricName_); - // (5.3) values + // (5.4) values switch (metric.TimeSeries.Size()) { case 0: break; diff --git a/library/cpp/monlib/encode/spack/spack_v1_ut.cpp b/library/cpp/monlib/encode/spack/spack_v1_ut.cpp index fe778eb7e0..bbc3b8712b 100644 --- a/library/cpp/monlib/encode/spack/spack_v1_ut.cpp +++ b/library/cpp/monlib/encode/spack/spack_v1_ut.cpp @@ -104,7 +104,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { ui8 expectedMetric1[] = { 0x0C, // types (RATE | NONE) (fixed ui8) - 0x00, // flags (fixed ui8) + 0x01, // flags (fixed ui8) 0x01, // metric labels count (varint) 0x00, // label name index (varint) 0x01, // label value index (varint) @@ -282,6 +282,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { e->OnLabelsBegin(); e->OnLabel("name", "q1"); e->OnLabelsEnd(); + e->OnMemOnly(true); } e->OnMetricEnd(); } @@ -513,12 +514,14 @@ Y_UNIT_TEST_SUITE(TSpackTest) { { const NProto::TMultiSample& s = samples.GetSamples(0); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), true); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "name", "q1"); } { const NProto::TMultiSample& s = samples.GetSamples(1); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); + UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "name", "q2"); @@ -528,6 +531,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { { const NProto::TMultiSample& s = samples.GetSamples(2); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); + UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "name", "q3"); @@ -537,6 +541,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { { const NProto::TMultiSample& s = samples.GetSamples(3); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "name", "answer"); @@ -547,6 +552,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { { const NProto::TMultiSample& s = samples.GetSamples(4); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HISTOGRAM); + UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "name", "responseTimeMillis"); @@ -570,6 +576,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { { const NProto::TMultiSample& s = samples.GetSamples(5); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::IGAUGE); + UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "name", "bytes"); @@ -579,6 +586,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { { const NProto::TMultiSample& s = samples.GetSamples(6); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); + UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "name", "temperature"); @@ -601,6 +609,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { { const NProto::TMultiSample& s = samples.GetSamples(7); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::LOGHISTOGRAM); + UNIT_ASSERT_EQUAL(s.GetIsMemOnly(), false); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); AssertLabelEqual(s.GetLabels(0), "name", "ms"); diff --git a/library/cpp/monlib/metrics/metric_consumer.h b/library/cpp/monlib/metrics/metric_consumer.h index f7a727585a..1152b51c4a 100644 --- a/library/cpp/monlib/metrics/metric_consumer.h +++ b/library/cpp/monlib/metrics/metric_consumer.h @@ -33,6 +33,10 @@ namespace NMonitoring { virtual void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) = 0; virtual void OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr snapshot) = 0; virtual void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) = 0; + + virtual void OnMemOnly(bool isMemOnly) { + Y_UNUSED(isMemOnly); + } }; using IMetricConsumerPtr = THolder<IMetricConsumer>; diff --git a/library/cpp/monlib/metrics/metric_registry.cpp b/library/cpp/monlib/metrics/metric_registry.cpp index c747ae2b74..245f65702d 100644 --- a/library/cpp/monlib/metrics/metric_registry.cpp +++ b/library/cpp/monlib/metrics/metric_registry.cpp @@ -11,16 +11,17 @@ namespace NMonitoring { } template <typename TLabelsConsumer> - void ConsumeMetric(TInstant time, IMetricConsumer* consumer, IMetric* metric, TLabelsConsumer&& labelsConsumer) { + void ConsumeMetric(TInstant time, IMetricConsumer* consumer, IMetric* metric, TLabelsConsumer&& labelsConsumer, TMetricOpts opts = {}) { consumer->OnMetricBegin(metric->Type()); // (1) add labels consumer->OnLabelsBegin(); labelsConsumer(); consumer->OnLabelsEnd(); - // (2) add time and value metric->Accept(time, consumer); + // (3) add flag + consumer->OnMemOnly(opts.MemOnly); consumer->OnMetricEnd(); } } @@ -55,104 +56,177 @@ namespace NMonitoring { } TGauge* TMetricRegistry::Gauge(TLabels labels) { - return Metric<TGauge, EMetricType::GAUGE>(std::move(labels)); + return GaugeWithOpts(std::move(labels)); + } + TGauge* TMetricRegistry::GaugeWithOpts(TLabels labels, TMetricOpts opts) { + return Metric<TGauge, EMetricType::GAUGE>(std::move(labels), std::move(opts)); } TGauge* TMetricRegistry::Gauge(ILabelsPtr labels) { - return Metric<TGauge, EMetricType::GAUGE>(std::move(labels)); + return GaugeWithOpts(std::move(labels)); + } + TGauge* TMetricRegistry::GaugeWithOpts(ILabelsPtr labels, TMetricOpts opts) { + return Metric<TGauge, EMetricType::GAUGE>(std::move(labels), std::move(opts)); } TLazyGauge* TMetricRegistry::LazyGauge(TLabels labels, std::function<double()> supplier) { - return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier)); + return LazyGaugeWithOpts(std::move(labels), std::move(supplier)); + } + TLazyGauge* TMetricRegistry::LazyGaugeWithOpts(TLabels labels, std::function<double()> supplier, TMetricOpts opts) { + return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels),std::move(opts), std::move(supplier)); } TLazyGauge* TMetricRegistry::LazyGauge(ILabelsPtr labels, std::function<double()> supplier) { - return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier)); + return LazyGaugeWithOpts(std::move(labels), std::move(supplier)); + } + TLazyGauge* TMetricRegistry::LazyGaugeWithOpts(ILabelsPtr labels, std::function<double()> supplier, TMetricOpts opts) { + return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(opts), std::move(supplier)); } TIntGauge* TMetricRegistry::IntGauge(TLabels labels) { - return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels)); + return IntGaugeWithOpts(std::move(labels)); + } + TIntGauge* TMetricRegistry::IntGaugeWithOpts(TLabels labels, TMetricOpts opts) { + return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(opts)); } TIntGauge* TMetricRegistry::IntGauge(ILabelsPtr labels) { - return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels)); + return IntGaugeWithOpts(std::move(labels)); + } + TIntGauge* TMetricRegistry::IntGaugeWithOpts(ILabelsPtr labels, TMetricOpts opts) { + return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(opts)); } TLazyIntGauge* TMetricRegistry::LazyIntGauge(TLabels labels, std::function<i64()> supplier) { - return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(supplier)); + return LazyIntGaugeWithOpts(std::move(labels), std::move(supplier)); + } + TLazyIntGauge* TMetricRegistry::LazyIntGaugeWithOpts(TLabels labels, std::function<i64()> supplier, TMetricOpts opts) { + return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(opts), std::move(supplier)); } TLazyIntGauge* TMetricRegistry::LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) { - return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(supplier)); + return LazyIntGaugeWithOpts(std::move(labels), std::move(supplier)); + } + TLazyIntGauge* TMetricRegistry::LazyIntGaugeWithOpts(ILabelsPtr labels, std::function<i64()> supplier, TMetricOpts opts) { + return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(opts), std::move(supplier)); } TCounter* TMetricRegistry::Counter(TLabels labels) { - return Metric<TCounter, EMetricType::COUNTER>(std::move(labels)); + return CounterWithOpts(std::move(labels)); + } + TCounter* TMetricRegistry::CounterWithOpts(TLabels labels, TMetricOpts opts) { + return Metric<TCounter, EMetricType::COUNTER>(std::move(labels), std::move(opts)); } TCounter* TMetricRegistry::Counter(ILabelsPtr labels) { - return Metric<TCounter, EMetricType::COUNTER>(std::move(labels)); + return CounterWithOpts(std::move(labels)); + } + TCounter* TMetricRegistry::CounterWithOpts(ILabelsPtr labels, TMetricOpts opts) { + return Metric<TCounter, EMetricType::COUNTER>(std::move(labels), std::move(opts)); } TLazyCounter* TMetricRegistry::LazyCounter(TLabels labels, std::function<ui64()> supplier) { - return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier)); + return LazyCounterWithOpts(std::move(labels), std::move(supplier)); + } + TLazyCounter* TMetricRegistry::LazyCounterWithOpts(TLabels labels, std::function<ui64()> supplier, TMetricOpts opts) { + return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(opts), std::move(supplier)); } TLazyCounter* TMetricRegistry::LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) { - return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier)); + return LazyCounterWithOpts(std::move(labels), std::move(supplier)); + } + TLazyCounter* TMetricRegistry::LazyCounterWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts) { + return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(opts), std::move(supplier)); } TRate* TMetricRegistry::Rate(TLabels labels) { - return Metric<TRate, EMetricType::RATE>(std::move(labels)); + return RateWithOpts(std::move(labels)); + } + TRate* TMetricRegistry::RateWithOpts(TLabels labels, TMetricOpts opts) { + return Metric<TRate, EMetricType::RATE>(std::move(labels), std::move(opts)); } TRate* TMetricRegistry::Rate(ILabelsPtr labels) { - return Metric<TRate, EMetricType::RATE>(std::move(labels)); + return RateWithOpts(std::move(labels)); + } + TRate* TMetricRegistry::RateWithOpts(ILabelsPtr labels, TMetricOpts opts) { + return Metric<TRate, EMetricType::RATE>(std::move(labels), std::move(opts)); } TLazyRate* TMetricRegistry::LazyRate(TLabels labels, std::function<ui64()> supplier) { - return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier)); + return LazyRateWithOpts(std::move(labels), std::move(supplier)); + } + TLazyRate* TMetricRegistry::LazyRateWithOpts(TLabels labels, std::function<ui64()> supplier, TMetricOpts opts) { + return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(opts), std::move(supplier)); } TLazyRate* TMetricRegistry::LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) { - return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier)); + return LazyRateWithOpts(std::move(labels), std::move(supplier)); + } + TLazyRate* TMetricRegistry::LazyRateWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts) { + return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(opts), std::move(supplier)); } THistogram* TMetricRegistry::HistogramCounter(TLabels labels, IHistogramCollectorPtr collector) { - return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false); + return HistogramCounterWithOpts(std::move(labels), std::move(collector)); + } + THistogram* TMetricRegistry::HistogramCounterWithOpts(TLabels labels, IHistogramCollectorPtr collector, TMetricOpts opts) { + return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(opts), std::move(collector), false); } THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) { - return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false); + return HistogramCounterWithOpts(std::move(labels), std::move(collector)); + } + THistogram* TMetricRegistry::HistogramCounterWithOpts(ILabelsPtr labels, IHistogramCollectorPtr collector, TMetricOpts opts) { + return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(opts), std::move(collector), false); } THistogram* TMetricRegistry::HistogramCounter(TLabels labels, std::function<IHistogramCollectorPtr()> supplier) { - return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(supplier), false); + return HistogramCounterWithOpts(std::move(labels), std::move(supplier)); + } + THistogram* TMetricRegistry::HistogramCounterWithOpts(TLabels labels, std::function<IHistogramCollectorPtr()> supplier, TMetricOpts opts) { + return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(opts), std::move(supplier), false); } THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier) { - return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(supplier), false); + return HistogramCounterWithOpts(std::move(labels), std::move(supplier)); + } + THistogram* TMetricRegistry::HistogramCounterWithOpts(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier, TMetricOpts opts) { + return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(opts), std::move(supplier), false); } THistogram* TMetricRegistry::HistogramRate(TLabels labels, IHistogramCollectorPtr collector) { - return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true); + return HistogramRateWithOpts(std::move(labels), std::move(collector)); + } + THistogram* TMetricRegistry::HistogramRateWithOpts(TLabels labels, IHistogramCollectorPtr collector, TMetricOpts opts) { + return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(opts), std::move(collector), true); } THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) { - return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true); + return HistogramRateWithOpts(std::move(labels), std::move(collector)); + } + THistogram* TMetricRegistry::HistogramRateWithOpts(ILabelsPtr labels, IHistogramCollectorPtr collector, TMetricOpts opts) { + return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(opts), std::move(collector), true); } THistogram* TMetricRegistry::HistogramRate(TLabels labels, std::function<IHistogramCollectorPtr()> supplier) { - return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(supplier), true); + return HistogramRateWithOpts(std::move(labels), std::move(supplier)); + } + THistogram* TMetricRegistry::HistogramRateWithOpts(TLabels labels, std::function<IHistogramCollectorPtr()> supplier, TMetricOpts opts) { + return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(opts), std::move(supplier), true); } THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier) { - return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(supplier), true); + return HistogramRateWithOpts(std::move(labels), std::move(supplier)); + } + THistogram* TMetricRegistry::HistogramRateWithOpts(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier, TMetricOpts opts) { + return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(opts), std::move(supplier), true); } void TMetricRegistry::Reset() { TWriteGuard g{*Lock_}; - for (auto& [label, metric] : Metrics_) { + for (auto& [label, metricValue] : Metrics_) { + auto metric = metricValue.Metric; switch (metric->Type()) { case EMetricType::GAUGE: static_cast<TGauge*>(metric.Get())->Set(.0); @@ -184,16 +258,19 @@ namespace NMonitoring { } template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> - TMetric* TMetricRegistry::Metric(TLabelsType&& labels, Args&&... args) { + TMetric* TMetricRegistry::Metric(TLabelsType&& labels, TMetricOpts&& opts, Args&&... args) { { TReadGuard g{*Lock_}; auto it = Metrics_.find(labels); if (it != Metrics_.end()) { - Y_ENSURE(it->second->Type() == type, "cannot create metric " << labels + Y_ENSURE(it->second.Metric->Type() == type, "cannot create metric " << labels << " with type " << MetricTypeToStr(type) - << ", because registry already has same metric with type " << MetricTypeToStr(it->second->Type())); - return static_cast<TMetric*>(it->second.Get()); + << ", because registry already has same metric with type " << MetricTypeToStr(it->second.Metric->Type())); + Y_ENSURE(it->second.Opts.MemOnly == opts.MemOnly,"cannot create metric " << labels + << " with memOnly=" << opts.MemOnly + << ", because registry already has same metric with memOnly=" << it->second.Opts.MemOnly); + return static_cast<TMetric*>(it->second.Metric.Get()); } } @@ -202,14 +279,15 @@ namespace NMonitoring { TWriteGuard g{*Lock_}; // decltype(Metrics_)::iterator breaks build on windows - THashMap<ILabelsPtr, IMetricPtr>::iterator it; + THashMap<ILabelsPtr, TMetricValue>::iterator it; + TMetricValue metricValue = {metric, opts}; if constexpr (!std::is_convertible_v<TLabelsType, ILabelsPtr>) { - it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metric)).first; + it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metricValue)).first; } else { - it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metric)).first; + it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metricValue)).first; } - return static_cast<TMetric*>(it->second.Get()); + return static_cast<TMetric*>(it->second.Metric.Get()); } } @@ -227,7 +305,7 @@ namespace NMonitoring { consumer->OnLabelsEnd(); } - TVector<std::pair<ILabelsPtr, IMetricPtr>> tmpMetrics; + TVector<std::pair<ILabelsPtr, TMetricValue>> tmpMetrics; { TReadGuard g{*Lock_}; @@ -239,10 +317,17 @@ namespace NMonitoring { for (const auto& it: tmpMetrics) { ILabels* labels = it.first.Get(); - IMetric* metric = it.second.Get(); - ConsumeMetric(time, consumer, metric, [&]() { - ConsumeLabels(consumer, *labels); - }); + IMetric* metric = it.second.Metric.Get(); + TMetricOpts opts = it.second.Opts; + ConsumeMetric( + time, + consumer, + metric, + [&]() { + ConsumeLabels(consumer, *labels); + }, + opts + ); } consumer->OnStreamEnd(); @@ -253,11 +338,18 @@ namespace NMonitoring { for (const auto& it: Metrics_) { ILabels* labels = it.first.Get(); - IMetric* metric = it.second.Get(); - ConsumeMetric(time, consumer, metric, [&]() { - ConsumeLabels(consumer, CommonLabels_); - ConsumeLabels(consumer, *labels); - }); + IMetric* metric = it.second.Metric.Get(); + TMetricOpts opts = it.second.Opts; + ConsumeMetric( + time, + consumer, + metric, + [&]() { + ConsumeLabels(consumer, CommonLabels_); + ConsumeLabels(consumer, *labels); + }, + opts + ); } } } diff --git a/library/cpp/monlib/metrics/metric_registry.h b/library/cpp/monlib/metrics/metric_registry.h index 7b3a7aab70..f60467cf91 100644 --- a/library/cpp/monlib/metrics/metric_registry.h +++ b/library/cpp/monlib/metrics/metric_registry.h @@ -9,35 +9,109 @@ namespace NMonitoring { + + struct TMetricOpts { + bool MemOnly = false; + }; + class IMetricFactory { public: virtual ~IMetricFactory() = default; virtual IGauge* Gauge(ILabelsPtr labels) = 0; + virtual IGauge* GaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) { + Y_UNUSED(opts); + return Gauge(std::move(labels)); + } + virtual ILazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) = 0; + virtual ILazyGauge* LazyGaugeWithOpts(ILabelsPtr labels, std::function<double()> supplier, TMetricOpts opts = {}) { + Y_UNUSED(opts); + return LazyGauge(std::move(labels), std::move(supplier)); + } + virtual IIntGauge* IntGauge(ILabelsPtr labels) = 0; + virtual IIntGauge* IntGaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) { + Y_UNUSED(opts); + return IntGauge(std::move(labels)); + } virtual ILazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) = 0; + virtual ILazyIntGauge* LazyIntGaugeWithOpts(ILabelsPtr labels, std::function<i64()> supplier, TMetricOpts opts = {}) { + Y_UNUSED(opts); + return LazyIntGauge(std::move(labels), std::move(supplier)); + } + virtual ICounter* Counter(ILabelsPtr labels) = 0; + virtual ICounter* CounterWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) { + Y_UNUSED(opts); + return Counter(std::move(labels)); + } + virtual ILazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) = 0; + virtual ILazyCounter* LazyCounterWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) { + Y_UNUSED(opts); + return LazyCounter(std::move(labels), std::move(supplier)); + } virtual IRate* Rate(ILabelsPtr labels) = 0; + virtual IRate* RateWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) { + Y_UNUSED(opts); + return Rate(std::move(labels)); + } + virtual ILazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) = 0; + virtual ILazyRate* LazyRateWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) { + Y_UNUSED(opts); + return LazyRate(std::move(labels), std::move(supplier)); + } virtual IHistogram* HistogramCounter( ILabelsPtr labels, IHistogramCollectorPtr collector) = 0; + virtual IHistogram* HistogramCounterWithOpts( + ILabelsPtr labels, + IHistogramCollectorPtr collector, + TMetricOpts opts = {}) + { + Y_UNUSED(opts); + return HistogramCounter(std::move(labels), std::move(collector)); + } virtual IHistogram* HistogramRate( ILabelsPtr labels, IHistogramCollectorPtr collector) = 0; + virtual IHistogram* HistogramRateWithOpts( + ILabelsPtr labels, + IHistogramCollectorPtr collector, + TMetricOpts opts = {}) + { + Y_UNUSED(opts); + return HistogramRate(std::move(labels), std::move(collector)); + } virtual IHistogram* HistogramCounter( ILabelsPtr labels, std::function<IHistogramCollectorPtr()> makeHistogramCollector) = 0; + virtual IHistogram* HistogramCounterWithOpts( + ILabelsPtr labels, + std::function<IHistogramCollectorPtr()> makeHistogramCollector, + TMetricOpts opts = {}) + { + Y_UNUSED(opts); + return HistogramCounter(std::move(labels), std::move(makeHistogramCollector)); + } virtual IHistogram* HistogramRate( ILabelsPtr labels, std::function<IHistogramCollectorPtr()> makeHistogramCollector) = 0; + virtual IHistogram* HistogramRateWithOpts( + ILabelsPtr labels, + std::function<IHistogramCollectorPtr()> makeHistogramCollector, + TMetricOpts opts = {}) + { + Y_UNUSED(opts); + return HistogramRate(std::move(labels), std::move(makeHistogramCollector)); + } }; class IMetricSupplier { @@ -79,29 +153,53 @@ namespace NMonitoring { static std::shared_ptr<TMetricRegistry> SharedInstance(); TGauge* Gauge(TLabels labels); + TGauge* GaugeWithOpts(TLabels labels, TMetricOpts opts = {}); TLazyGauge* LazyGauge(TLabels labels, std::function<double()> supplier); + TLazyGauge* LazyGaugeWithOpts(TLabels labels, std::function<double()> supplier, TMetricOpts opts = {}); TIntGauge* IntGauge(TLabels labels); + TIntGauge* IntGaugeWithOpts(TLabels labels, TMetricOpts opts = {}); TLazyIntGauge* LazyIntGauge(TLabels labels, std::function<i64()> supplier); + TLazyIntGauge* LazyIntGaugeWithOpts(TLabels labels, std::function<i64()> supplier, TMetricOpts opts = {}); TCounter* Counter(TLabels labels); + TCounter* CounterWithOpts(TLabels labels, TMetricOpts opts = {}); TLazyCounter* LazyCounter(TLabels labels, std::function<ui64()> supplier); + TLazyCounter* LazyCounterWithOpts(TLabels labels, std::function<ui64()> supplier, TMetricOpts opts = {}); TRate* Rate(TLabels labels); + TRate* RateWithOpts(TLabels labels, TMetricOpts opts = {}); TLazyRate* LazyRate(TLabels labels, std::function<ui64()> supplier); + TLazyRate* LazyRateWithOpts(TLabels labels, std::function<ui64()> supplier, TMetricOpts opts = {}); THistogram* HistogramCounter( TLabels labels, IHistogramCollectorPtr collector); + THistogram* HistogramCounterWithOpts( + TLabels labels, + IHistogramCollectorPtr collector, + TMetricOpts opts = {}); THistogram* HistogramRate( TLabels labels, IHistogramCollectorPtr collector); + THistogram* HistogramRateWithOpts( + TLabels labels, + IHistogramCollectorPtr collector, + TMetricOpts opts = {}); THistogram* HistogramCounter( TLabels labels, std::function<IHistogramCollectorPtr()> makeHistogramCollector); + THistogram* HistogramCounterWithOpts( + TLabels labels, + std::function<IHistogramCollectorPtr()> makeHistogramCollector, + TMetricOpts opts = {}); THistogram* HistogramRate( TLabels labels, std::function<IHistogramCollectorPtr()> makeHistogramCollector); + THistogram* HistogramRateWithOpts( + TLabels labels, + std::function<IHistogramCollectorPtr()> makeHistogramCollector, + TMetricOpts opts = {}); /** * Set all registered metrics to zero @@ -123,36 +221,65 @@ namespace NMonitoring { private: TGauge* Gauge(ILabelsPtr labels) override; + TGauge* GaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override; TLazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) override; + TLazyGauge* LazyGaugeWithOpts(ILabelsPtr labels, std::function<double()> supplier, TMetricOpts opts = {}) override; TIntGauge* IntGauge(ILabelsPtr labels) override; + TIntGauge* IntGaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override; TLazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) override; + TLazyIntGauge* LazyIntGaugeWithOpts(ILabelsPtr labels, std::function<i64()> supplier, TMetricOpts opts = {}) override; TCounter* Counter(ILabelsPtr labels) override; + TCounter* CounterWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override; TLazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) override; + TLazyCounter* LazyCounterWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) override; TRate* Rate(ILabelsPtr labels) override; + TRate* RateWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override; TLazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) override; + TLazyRate* LazyRateWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) override; THistogram* HistogramCounter( ILabelsPtr labels, IHistogramCollectorPtr collector) override; + THistogram* HistogramCounterWithOpts( + ILabelsPtr labels, + IHistogramCollectorPtr collector, + TMetricOpts opts = {}) override; THistogram* HistogramRate( ILabelsPtr labels, IHistogramCollectorPtr collector) override; + THistogram* HistogramRateWithOpts( + ILabelsPtr labels, + IHistogramCollectorPtr collector, + TMetricOpts opts = {}) override; THistogram* HistogramCounter( ILabelsPtr labels, std::function<IHistogramCollectorPtr()> makeHistogramCollector) override; + THistogram* HistogramCounterWithOpts( + ILabelsPtr labels, + std::function<IHistogramCollectorPtr()> makeHistogramCollector, + TMetricOpts opts = {}) override; THistogram* HistogramRate( ILabelsPtr labels, std::function<IHistogramCollectorPtr()> makeHistogramCollector) override; + THistogram* HistogramRateWithOpts( + ILabelsPtr labels, + std::function<IHistogramCollectorPtr()> makeHistogramCollector, + TMetricOpts opts = {}) override; + + struct TMetricValue { + IMetricPtr Metric; + TMetricOpts Opts; + }; private: THolder<TRWMutex> Lock_ = MakeHolder<TRWMutex>(); - THashMap<ILabelsPtr, IMetricPtr> Metrics_; + THashMap<ILabelsPtr, TMetricValue> Metrics_; template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> - TMetric* Metric(TLabelsType&& labels, Args&&... args); + TMetric* Metric(TLabelsType&& labels, TMetricOpts&& opts, Args&&... args); TLabels CommonLabels_; }; diff --git a/library/cpp/monlib/metrics/metric_registry_ut.cpp b/library/cpp/monlib/metrics/metric_registry_ut.cpp index 802c423264..89e6d56146 100644 --- a/library/cpp/monlib/metrics/metric_registry_ut.cpp +++ b/library/cpp/monlib/metrics/metric_registry_ut.cpp @@ -396,4 +396,76 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { UNIT_ASSERT(commonLabels[0].GetName() == "common"); UNIT_ASSERT(commonLabels[0].GetValue() == "label"); } + + Y_UNIT_TEST(MemOnlyMetric) { + TMetricRegistry registry; + i64 int_val = 0; + double double_val = 0; + + registry.GaugeWithOpts({{"some", "gauge"}}, {true}); + UNIT_ASSERT_EXCEPTION(registry.Gauge({{"some", "gauge"}}), yexception); + + registry.LazyGaugeWithOpts( + {{"some", "lazy_gauge"}}, + [&double_val](){return double_val;}, + {true}); + UNIT_ASSERT_EXCEPTION( + registry.LazyGauge( + {{"some", "lazy_gauge"}}, + [&double_val](){return double_val;}), + yexception); + + registry.IntGaugeWithOpts({{"some", "int_gauge"}}, {true}); + UNIT_ASSERT_EXCEPTION(registry.IntGauge({{"some", "int_gauge"}}), yexception); + + registry.LazyIntGaugeWithOpts( + {{"some", "lazy_int_gauge"}}, + [&int_val](){return int_val;}, + {true}); + UNIT_ASSERT_EXCEPTION( + registry.LazyIntGauge( + {{"some", "lazy_int_gauge"}}, + [&int_val](){return int_val;}), + yexception); + + registry.CounterWithOpts({{"some", "counter"}}, {true}); + UNIT_ASSERT_EXCEPTION(registry.Counter({{"some", "counter"}}), yexception); + + registry.LazyCounterWithOpts({{"some", "lazy_counter"}}, [&int_val](){return int_val;}, {true}); + UNIT_ASSERT_EXCEPTION( + registry.LazyCounter( + {{"some", "lazy_counter"}}, + [&int_val](){return int_val;}), + yexception); + + registry.RateWithOpts({{"some", "rate"}}, {true}); + UNIT_ASSERT_EXCEPTION(registry.Rate({{"some", "rate"}}), yexception); + + registry.LazyRateWithOpts({{"some", "lazy_rate"}}, [&double_val](){return double_val;}, {true}); + UNIT_ASSERT_EXCEPTION( + registry.LazyRate( + {{"some", "lazy_rate"}}, + [&double_val](){return double_val;}), + yexception); + + registry.HistogramCounterWithOpts( + {{"some", "histogram_counter"}}, + ExplicitHistogram({1, 5, 15, 20, 25}), + {true}); + UNIT_ASSERT_EXCEPTION( + registry.HistogramCounter( + {{"some", "histogram_counter"}}, + ExplicitHistogram({1, 5, 15, 20, 25})), + yexception); + + registry.HistogramRateWithOpts( + {{"some", "histogram_rate"}}, + ExponentialHistogram(5, 2), + {true}); + UNIT_ASSERT_EXCEPTION( + registry.HistogramRate( + {{"some", "histogram_rate"}}, + ExponentialHistogram(5, 2)), + yexception); + } } diff --git a/library/cpp/monlib/metrics/metric_sub_registry.h b/library/cpp/monlib/metrics/metric_sub_registry.h index d1860c00a9..c3481f338f 100644 --- a/library/cpp/monlib/metrics/metric_sub_registry.h +++ b/library/cpp/monlib/metrics/metric_sub_registry.h @@ -33,61 +33,110 @@ public: AddCommonLabels(labels.Get()); return DelegatePtr_->Gauge(std::move(labels)); } + IGauge* GaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->GaugeWithOpts(std::move(labels), std::move(opts)); + } ILazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) override { AddCommonLabels(labels.Get()); return DelegatePtr_->LazyGauge(std::move(labels), std::move(supplier)); } + ILazyGauge* LazyGaugeWithOpts(ILabelsPtr labels, std::function<double()> supplier, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->LazyGaugeWithOpts(std::move(labels), std::move(supplier), std::move(opts)); + } IIntGauge* IntGauge(ILabelsPtr labels) override { AddCommonLabels(labels.Get()); return DelegatePtr_->IntGauge(std::move(labels)); } + IIntGauge* IntGaugeWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->IntGaugeWithOpts(std::move(labels), std::move(opts)); + } ILazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) override { AddCommonLabels(labels.Get()); return DelegatePtr_->LazyIntGauge(std::move(labels), std::move(supplier)); } + ILazyIntGauge* LazyIntGaugeWithOpts(ILabelsPtr labels, std::function<i64()> supplier, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->LazyIntGaugeWithOpts(std::move(labels), std::move(supplier), std::move(opts)); + } ICounter* Counter(ILabelsPtr labels) override { AddCommonLabels(labels.Get()); return DelegatePtr_->Counter(std::move(labels)); } + ICounter* CounterWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->CounterWithOpts(std::move(labels), std::move(opts)); + } ILazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) override { AddCommonLabels(labels.Get()); return DelegatePtr_->LazyCounter(std::move(labels), std::move(supplier)); } + ILazyCounter* LazyCounterWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->LazyCounterWithOpts(std::move(labels), std::move(supplier), std::move(opts)); + } IRate* Rate(ILabelsPtr labels) override { AddCommonLabels(labels.Get()); return DelegatePtr_->Rate(std::move(labels)); } + IRate* RateWithOpts(ILabelsPtr labels, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->RateWithOpts(std::move(labels), std::move(opts)); + } + ILazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) override { AddCommonLabels(labels.Get()); return DelegatePtr_->LazyRate(std::move(labels), std::move(supplier)); } + ILazyRate* LazyRateWithOpts(ILabelsPtr labels, std::function<ui64()> supplier, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->LazyRateWithOpts(std::move(labels), std::move(supplier), std::move(opts)); + } IHistogram* HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) override { AddCommonLabels(labels.Get()); return DelegatePtr_->HistogramCounter(std::move(labels), std::move(collector)); } + IHistogram* HistogramCounterWithOpts(ILabelsPtr labels, IHistogramCollectorPtr collector, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->HistogramCounterWithOpts(std::move(labels), std::move(collector), std::move(opts)); + } IHistogram* HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) override { AddCommonLabels(labels.Get()); return DelegatePtr_->HistogramRate(std::move(labels), std::move(collector)); } + IHistogram* HistogramRateWithOpts(ILabelsPtr labels, IHistogramCollectorPtr collector, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->HistogramRateWithOpts(std::move(labels), std::move(collector), std::move(opts)); + } IHistogram* HistogramCounter(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> collector) override { AddCommonLabels(labels.Get()); return DelegatePtr_->HistogramCounter(std::move(labels), std::move(collector)); } + IHistogram* HistogramCounterWithOpts(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> collector, TMetricOpts opts = {}) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->HistogramCounterWithOpts(std::move(labels), std::move(collector), std::move(opts)); + } IHistogram* HistogramRate(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> collector) override { AddCommonLabels(labels.Get()); return DelegatePtr_->HistogramRate(std::move(labels), std::move(collector)); } + IHistogram* HistogramRateWithOpts(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> collector, TMetricOpts opts) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->HistogramRateWithOpts(std::move(labels), std::move(collector), std::move(opts)); + } void Accept(TInstant time, IMetricConsumer* consumer) const override { DelegatePtr_->Accept(time, consumer); diff --git a/library/cpp/yt/memory/non_null_ptr-inl.h b/library/cpp/yt/memory/non_null_ptr-inl.h index a14b1e9302..d4d00c5549 100644 --- a/library/cpp/yt/memory/non_null_ptr-inl.h +++ b/library/cpp/yt/memory/non_null_ptr-inl.h @@ -1,6 +1,6 @@ #pragma once #ifndef NON_NULL_PTR_H_ -#error "Direct inclusion of this file is not allowed, include helpers.h" +#error "Direct inclusion of this file is not allowed, include non_null_ptr.h" // For the sake of sane code completion. #include "non_null_ptr.h" #endif diff --git a/library/cpp/yt/memory/poison-inl.h b/library/cpp/yt/memory/poison-inl.h new file mode 100644 index 0000000000..c7563565a8 --- /dev/null +++ b/library/cpp/yt/memory/poison-inl.h @@ -0,0 +1,60 @@ +#pragma once +#ifndef POISON_INL_H_ +#error "Direct inclusion of this file is not allowed, include poison.h" +// For the sake of sane code completion. +#include "poison.h" +#endif + +#include <util/system/compiler.h> + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +#if defined(_asan_enabled_) + +extern "C" { +void __asan_poison_memory_region(void const volatile *addr, size_t size); +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +} // extern "C" + +Y_FORCE_INLINE void PoisonMemory(TMutableRef ref) +{ + __asan_poison_memory_region(ref.data(), ref.size()); +} + +Y_FORCE_INLINE void UnpoisonMemory(TMutableRef ref) +{ + __asan_unpoison_memory_region(ref.data(), ref.size()); +} + +#elif defined(_msan_enabled_) + +extern "C" { +void __msan_unpoison(const volatile void* a, size_t size); +void __msan_poison(const volatile void* a, size_t size); +} // extern "C" + +Y_FORCE_INLINE void PoisonMemory(TMutableRef ref) +{ + __msan_poison(ref.data(), ref.size()); +} + +Y_FORCE_INLINE void UnpoisonMemory(TMutableRef ref) +{ + __msan_unpoison(ref.data(), ref.size()); +} + +#elif defined(NDEBUG) + +Y_FORCE_INLINE void PoisonMemory(TMutableRef /*ref*/) +{ } + +Y_FORCE_INLINE void UnpoisonMemory(TMutableRef /*ref*/) +{ } + +#endif + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/memory/poison.cpp b/library/cpp/yt/memory/poison.cpp new file mode 100644 index 0000000000..bc4bcad4e0 --- /dev/null +++ b/library/cpp/yt/memory/poison.cpp @@ -0,0 +1,64 @@ +#include "poison.h" + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +namespace { + +template <char Byte0, char Byte1, char Byte2, char Byte3, char Byte4, char Byte5, char Byte6, char Byte7> +void ClobberMemory(char* __restrict__ ptr, size_t size) +{ + while (size >= 8) { + *ptr++ = Byte0; + *ptr++ = Byte1; + *ptr++ = Byte2; + *ptr++ = Byte3; + *ptr++ = Byte4; + *ptr++ = Byte5; + *ptr++ = Byte6; + *ptr++ = Byte7; + size -= 8; + } + + switch (size) { + case 7: + *ptr++ = Byte0; + [[fallthrough]]; + case 6: + *ptr++ = Byte1; + [[fallthrough]]; + case 5: + *ptr++ = Byte2; + [[fallthrough]]; + case 4: + *ptr++ = Byte3; + [[fallthrough]]; + case 3: + *ptr++ = Byte4; + [[fallthrough]]; + case 2: + *ptr++ = Byte5; + [[fallthrough]]; + case 1: + *ptr++ = Byte6; + } +} + +} // namespace + +#if !defined(NDEBUG) && !defined(_asan_enabled_) && !defined(_msan_enabled_) +void PoisonMemory(TMutableRef ref) +{ + ClobberMemory<'d', 'e', 'a', 'd', 'b', 'e', 'e', 'f'>(ref.data(), ref.size()); +} + +void UnpoisonMemory(TMutableRef ref) +{ + ClobberMemory<'c', 'a', 'f', 'e', 'b', 'a', 'b', 'e'>(ref.data(), ref.size()); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT diff --git a/library/cpp/yt/memory/poison.h b/library/cpp/yt/memory/poison.h new file mode 100644 index 0000000000..9519f3da10 --- /dev/null +++ b/library/cpp/yt/memory/poison.h @@ -0,0 +1,25 @@ +#pragma once + +#include "ref.h" + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +//! In release builds, does nothing. +//! In checked builds, clobbers memory with garbage pattern. +//! In sanitized builds, invokes sanitizer poisoning. +void PoisonMemory(TMutableRef ref); + +//! In release builds, does nothing. +//! In checked builds, clobbers memory with (another) garbage pattern. +//! In sanitized builds, invokes sanitizer unpoisoning. +void UnpoisonMemory(TMutableRef ref); + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT + +#define POISON_INL_H_ +#include "poison-inl.h" +#undef POISON_INL_H_ diff --git a/library/cpp/yt/memory/range.h b/library/cpp/yt/memory/range.h index 420ee9b429..84ea2e7758 100644 --- a/library/cpp/yt/memory/range.h +++ b/library/cpp/yt/memory/range.h @@ -354,12 +354,23 @@ public: : TRange<T>(elements) { } + using TRange<T>::Data; using TRange<T>::Begin; using TRange<T>::End; using TRange<T>::Front; using TRange<T>::Back; using TRange<T>::operator[]; + T* Data() const + { + return const_cast<T*>(this->Data_); + } + + T* data() const + { + return Data(); + } + iterator Begin() const { return const_cast<T*>(this->Data_); diff --git a/library/cpp/yt/memory/ya.make b/library/cpp/yt/memory/ya.make index 5397dccf32..d0c377cf3d 100644 --- a/library/cpp/yt/memory/ya.make +++ b/library/cpp/yt/memory/ya.make @@ -16,6 +16,7 @@ SRCS( chunked_output_stream.cpp memory_tag.cpp new.cpp + poison.cpp ref.cpp ref_tracked.cpp safe_memory_reader.cpp |