<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "simple_metrics_manager.h"
#include "simple_tick.h"

#include <vespa/log/log.h>
LOG_SETUP(".vespalib.metrics.simple_metrics_manager");

namespace vespalib {
namespace metrics {

using Guard = std::lock_guard<std::mutex>;

SimpleMetricsManager::SimpleMetricsManager(const SimpleManagerConfig &config,
                                           Tick::UP tick_supplier)
    : _currentSamples(),
      _tickSupplier(std::move(tick_supplier)),
      _startTime(_tickSupplier->first()),
      _curTime(_startTime),
      _collectCnt(0),
      _buckets(),
      _firstBucket(0),
      _maxBuckets(config.sliding_window_seconds),
      _totalsBucket(0, _startTime, _startTime),
      _thread(&SimpleMetricsManager::tickerLoop, this)
{
    if (_maxBuckets < 1) _maxBuckets = 1;
    Point empty = pointFrom(PointMap());
    assert(empty.id() == 0);
}

SimpleMetricsManager::~SimpleMetricsManager()
{
    stopThread();
}

std::shared_ptr<MetricsManager>
SimpleMetricsManager::create(const SimpleManagerConfig &config)
{
    return std::shared_ptr<MetricsManager>(
            new SimpleMetricsManager(config, std::make_unique<SimpleTick>()));
}

std::shared_ptr<MetricsManager>
SimpleMetricsManager::createForTest(const SimpleManagerConfig &config,
                                    Tick::UP tick_supplier)
{
    return std::shared_ptr<MetricsManager>(
            new SimpleMetricsManager(config, std::move(tick_supplier)));
}

Counter
SimpleMetricsManager::counter(const vespalib::string &name, const vespalib::string &)
{
    MetricId mn = MetricId::from_name(name);
    _metricTypes.check(mn.id(), name, MetricTypes::MetricType::COUNTER);
    LOG(debug, "counter with metric name %s -> %zu", name.c_str(), mn.id());
    return Counter(shared_from_this(), mn);
}

Gauge
SimpleMetricsManager::gauge(const vespalib::string &name, const vespalib::string &)
{
    MetricId mn = MetricId::from_name(name);
    _metricTypes.check(mn.id(), name, MetricTypes::MetricType::GAUGE);
    LOG(debug, "gauge with metric name %s -> %zu", name.c_str(), mn.id());
    return Gauge(shared_from_this(), mn);
}

Bucket
SimpleMetricsManager::mergeBuckets()
{
    Guard bucketsGuard(_bucketsLock);
    if (_buckets.size() > 0) {
        TimeStamp startTime = _buckets[_firstBucket].startTime;
        Bucket merger(0, startTime, startTime);
        for (size_t i = 0; i < _buckets.size(); i++) {
            size_t off = (_firstBucket + i) % _buckets.size();
            merger.merge(_buckets[off]);
        }
        merger.padMetrics(_totalsBucket);
        return merger;
    }
    // no data
    return Bucket(0, _startTime, _curTime);
}

Bucket
SimpleMetricsManager::totalsBucket()
{
    Guard bucketsGuard(_bucketsLock);
    return _totalsBucket;
}

Snapshot
SimpleMetricsManager::snapshotFrom(const Bucket &bucket)
{
    std::vector<PointSnapshot> points;

    double s = bucket.startTime.count();
    double e = bucket.endTime.count();

    size_t max_point_id = 0;
    for (const CounterAggregator& entry : bucket.counters) {
        max_point_id = std::max(max_point_id, entry.idx.second.id());
    }
    for (const GaugeAggregator& entry : bucket.gauges) {
        max_point_id = std::max(max_point_id, entry.idx.second.id());
    }
    Snapshot snap(s, e);
    {
        for (size_t point_id = 0; point_id <= max_point_id; ++point_id) {
            const PointMap &map = Point(point_id).as_map();
            PointSnapshot point;
            for (const PointMap::value_type &kv : map) {
                point.dimensions.emplace_back(kv.first.as_name(), kv.second.as_value());
            }
            snap.add(point);
        }
    }
    for (const CounterAggregator& entry : bucket.counters) {
        MetricId mn = entry.idx.first;
        size_t pi = entry.idx.second.id();
        const vespalib::string &name = mn.as_name();
        CounterSnapshot val(name, snap.points()[pi], entry);
        snap.add(val);
    }
    for (const GaugeAggregator& entry : bucket.gauges) {
        MetricId mn = entry.idx.first;
        size_t pi = entry.idx.second.id();
        const vespalib::string &name = mn.as_name();
        GaugeSnapshot val(name, snap.points()[pi], entry);
        snap.add(val);
    }
    return snap;
}

Snapshot
SimpleMetricsManager::snapshot()
{
    Bucket merged = mergeBuckets();<commit_msg>be slightly more verbose and update local variable names<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "simple_metrics_manager.h"
#include "simple_tick.h"

#include <vespa/log/log.h>
LOG_SETUP(".vespalib.metrics.simple_metrics_manager");

namespace vespalib {
namespace metrics {

using Guard = std::lock_guard<std::mutex>;

SimpleMetricsManager::SimpleMetricsManager(const SimpleManagerConfig &config,
                                           Tick::UP tick_supplier)
    : _currentSamples(),
      _tickSupplier(std::move(tick_supplier)),
      _startTime(_tickSupplier->first()),
      _curTime(_startTime),
      _collectCnt(0),
      _buckets(),
      _firstBucket(0),
      _maxBuckets(config.sliding_window_seconds),
      _totalsBucket(0, _startTime, _startTime),
      _thread(&SimpleMetricsManager::tickerLoop, this)
{
    if (_maxBuckets < 1) _maxBuckets = 1;
    Point empty = pointFrom(PointMap());
    assert(empty.id() == 0);
}

SimpleMetricsManager::~SimpleMetricsManager()
{
    stopThread();
}

std::shared_ptr<MetricsManager>
SimpleMetricsManager::create(const SimpleManagerConfig &config)
{
    return std::shared_ptr<MetricsManager>(
            new SimpleMetricsManager(config, std::make_unique<SimpleTick>()));
}

std::shared_ptr<MetricsManager>
SimpleMetricsManager::createForTest(const SimpleManagerConfig &config,
                                    Tick::UP tick_supplier)
{
    return std::shared_ptr<MetricsManager>(
            new SimpleMetricsManager(config, std::move(tick_supplier)));
}

Counter
SimpleMetricsManager::counter(const vespalib::string &name, const vespalib::string &)
{
    MetricId mi = MetricId::from_name(name);
    _metricTypes.check(mi.id(), name, MetricTypes::MetricType::COUNTER);
    LOG(debug, "counter with metric name %s -> %zu", name.c_str(), mi.id());
    return Counter(shared_from_this(), mi);
}

Gauge
SimpleMetricsManager::gauge(const vespalib::string &name, const vespalib::string &)
{
    MetricId mi = MetricId::from_name(name);
    _metricTypes.check(mi.id(), name, MetricTypes::MetricType::GAUGE);
    LOG(debug, "gauge with metric name %s -> %zu", name.c_str(), mi.id());
    return Gauge(shared_from_this(), mi);
}

Bucket
SimpleMetricsManager::mergeBuckets()
{
    Guard bucketsGuard(_bucketsLock);
    if (_buckets.size() > 0) {
        TimeStamp startTime = _buckets[_firstBucket].startTime;
        Bucket merger(0, startTime, startTime);
        for (size_t i = 0; i < _buckets.size(); i++) {
            size_t off = (_firstBucket + i) % _buckets.size();
            merger.merge(_buckets[off]);
        }
        merger.padMetrics(_totalsBucket);
        return merger;
    }
    // no data
    return Bucket(0, _startTime, _curTime);
}

Bucket
SimpleMetricsManager::totalsBucket()
{
    Guard bucketsGuard(_bucketsLock);
    return _totalsBucket;
}

Snapshot
SimpleMetricsManager::snapshotFrom(const Bucket &bucket)
{
    std::vector<PointSnapshot> points;

    double s = bucket.startTime.count();
    double e = bucket.endTime.count();

    size_t max_point_id = 0;
    for (const CounterAggregator& entry : bucket.counters) {
        Point p = entry.idx.second;
        max_point_id = std::max(max_point_id, p.id());
    }
    for (const GaugeAggregator& entry : bucket.gauges) {
        Point p = entry.idx.second;
        max_point_id = std::max(max_point_id, p.id());
    }
    Snapshot snap(s, e);
    {
        for (size_t point_id = 0; point_id <= max_point_id; ++point_id) {
            const PointMap &map = Point(point_id).as_map();
            PointSnapshot point;
            for (const PointMap::value_type &kv : map) {
                point.dimensions.emplace_back(kv.first.as_name(), kv.second.as_value());
            }
            snap.add(point);
        }
    }
    for (const CounterAggregator& entry : bucket.counters) {
        MetricId mi = entry.idx.first;
        Point p = entry.idx.second;
        size_t pi = p.id();
        const vespalib::string &name = mi.as_name();
        CounterSnapshot val(name, snap.points()[pi], entry);
        snap.add(val);
    }
    for (const GaugeAggregator& entry : bucket.gauges) {
        MetricId mi = entry.idx.first;
        Point p = entry.idx.second;
        size_t pi = p.id();
        const vespalib::string &name = mi.as_name();
        GaugeSnapshot val(name, snap.points()[pi], entry);
        snap.add(val);
    }
    return snap;
}

Snapshot
SimpleMetricsManager::snapshot()
{
    Bucket merged = mergeBuckets();
{'fraction_non_alphanumeric': 0.1285952248750694, 'fraction_numerical': 0.003997779011660188, 'mean_word_length': 3.3152850982271205, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1794127', 'n_tokens_mistral': 2906, 'n_tokens_neox': 2804, 'n_words': 571}