| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| #pragma once |
| |
| #include <vector> |
| #include <string> |
| #include <string_view> |
| |
| // #include "ts/ts.h" |
| // #include "ts/apidefs.h" |
| #include "tsutil/Metrics.h" |
| |
| #include "cripts/Lulu.hpp" |
| |
| namespace detail |
| { |
| |
| using MetricID = ts::Metrics::IdType; |
| |
| class BaseMetrics |
| { |
| using self_type = detail::BaseMetrics; |
| |
| public: |
| BaseMetrics() = delete; |
| BaseMetrics(const self_type &) = delete; |
| void operator=(const self_type &) = delete; |
| virtual ~BaseMetrics() = default; |
| |
| BaseMetrics(const cripts::string_view &name) : _name(name) {} |
| |
| void |
| operator=(int64_t val) |
| { |
| CAssert(_id != TS_ERROR); |
| _metric->store(val); |
| } |
| |
| operator int64_t() const |
| { |
| CAssert(_id != TS_ERROR); |
| return _metric->load(); |
| } |
| |
| [[nodiscard]] cripts::string_view |
| Name() const |
| { |
| return {_name}; |
| } |
| |
| [[nodiscard]] detail::MetricID |
| Id() const |
| { |
| return _id; |
| } |
| |
| void |
| Increment(int64_t inc) const |
| { |
| CAssert(_id != ts::Metrics::NOT_FOUND); |
| _metric->increment(inc); |
| } |
| |
| void |
| Increment() const |
| { |
| Increment(1); |
| } |
| |
| void |
| Decrement(int64_t dec) const |
| { |
| CAssert(_id != ts::Metrics::NOT_FOUND); |
| _metric->decrement(dec); |
| } |
| |
| void |
| Decrement() const |
| { |
| Decrement(1); |
| } |
| |
| protected: |
| void |
| _initialize(detail::MetricID id) |
| { |
| static auto &instance = ts::Metrics::instance(); |
| |
| _id = id; |
| _metric = instance.lookup(id); |
| } |
| |
| private: |
| ts::Metrics::AtomicType *_metric = nullptr; |
| cripts::string _name = "unknown"; |
| detail::MetricID _id = ts::Metrics::NOT_FOUND; |
| }; // class BaseMetrics |
| |
| } // namespace detail |
| |
| namespace cripts |
| { |
| |
| namespace Metrics |
| { |
| class Counter : public detail::BaseMetrics |
| { |
| using super_type = detail::BaseMetrics; |
| using self_type = Counter; |
| |
| public: |
| Counter(const cripts::string_view &name) : super_type(name) { _initialize(ts::Metrics::Counter::create(name)); } |
| |
| // Counters can only increment, so lets produce some nice compile time erorrs too |
| void Decrement(int64_t) = delete; |
| void Setter(int64_t val) = delete; |
| |
| template <typename T> |
| void |
| Decrement(T) |
| { |
| static_assert(std::is_same_v<T, int64_t>, "A Metric::Counter can only use Increment(), consider Metric::Gauge instead?"); |
| } |
| |
| template <typename T> |
| void |
| Setter(T) |
| { |
| static_assert(std::is_same_v<T, int64_t>, "A Metric::Counter can not be set to a value), consider Metric::Gauge instead?"); |
| } |
| |
| static self_type * |
| Create(const cripts::string_view &name) |
| { |
| auto *ret = new self_type(name); |
| auto id = ts::Metrics::Counter::create(name); |
| |
| ret->_initialize(id); |
| |
| return ret; |
| } |
| |
| }; // class Counter |
| |
| class Gauge : public detail::BaseMetrics |
| { |
| using super_type = detail::BaseMetrics; |
| using self_type = Gauge; |
| |
| public: |
| Gauge(const cripts::string_view &name) : super_type(name) { _initialize(ts::Metrics::Gauge::create(name)); } |
| |
| static self_type * |
| Create(const cripts::string_view &name) |
| { |
| auto *ret = new self_type(name); |
| auto id = ts::Metrics::Gauge::create(name); |
| |
| ret->_initialize(id); |
| |
| return ret; |
| } |
| |
| }; // class Counter |
| |
| } // namespace Metrics |
| |
| class MetricStorage |
| { |
| using self_type = MetricStorage; |
| |
| public: |
| MetricStorage() = delete; |
| MetricStorage(const self_type &) = delete; |
| void operator=(const self_type &) = delete; |
| |
| MetricStorage(size_t size) : _metrics(size) {} |
| |
| ~MetricStorage() |
| { |
| for (auto &metric : _metrics) { |
| delete metric; |
| } |
| } |
| |
| detail::BaseMetrics *& |
| operator[](std::size_t index) |
| { |
| if (_metrics.size() <= index) { |
| _metrics.resize(index + 8); // 8 at a time. |
| } |
| |
| return _metrics[index]; |
| } |
| |
| private: |
| std::vector<detail::BaseMetrics *> _metrics; |
| |
| }; // class MetricStorage |
| |
| } // namespace cripts |