144cf27c14880005df093f372491c593e1a9a3c58Yao Chen/*
244cf27c14880005df093f372491c593e1a9a3c58Yao Chen * Copyright (C) 2017 The Android Open Source Project
344cf27c14880005df093f372491c593e1a9a3c58Yao Chen *
444cf27c14880005df093f372491c593e1a9a3c58Yao Chen * Licensed under the Apache License, Version 2.0 (the "License");
544cf27c14880005df093f372491c593e1a9a3c58Yao Chen * you may not use this file except in compliance with the License.
644cf27c14880005df093f372491c593e1a9a3c58Yao Chen * You may obtain a copy of the License at
744cf27c14880005df093f372491c593e1a9a3c58Yao Chen *
844cf27c14880005df093f372491c593e1a9a3c58Yao Chen *      http://www.apache.org/licenses/LICENSE-2.0
944cf27c14880005df093f372491c593e1a9a3c58Yao Chen *
1044cf27c14880005df093f372491c593e1a9a3c58Yao Chen * Unless required by applicable law or agreed to in writing, software
1144cf27c14880005df093f372491c593e1a9a3c58Yao Chen * distributed under the License is distributed on an "AS IS" BASIS,
1244cf27c14880005df093f372491c593e1a9a3c58Yao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1344cf27c14880005df093f372491c593e1a9a3c58Yao Chen * See the License for the specific language governing permissions and
1444cf27c14880005df093f372491c593e1a9a3c58Yao Chen * limitations under the License.
1544cf27c14880005df093f372491c593e1a9a3c58Yao Chen */
1644cf27c14880005df093f372491c593e1a9a3c58Yao Chen
1744cf27c14880005df093f372491c593e1a9a3c58Yao Chen#ifndef COUNT_METRIC_PRODUCER_H
1844cf27c14880005df093f372491c593e1a9a3c58Yao Chen#define COUNT_METRIC_PRODUCER_H
1944cf27c14880005df093f372491c593e1a9a3c58Yao Chen
2044cf27c14880005df093f372491c593e1a9a3c58Yao Chen#include <unordered_map>
21caf339d004fad667748b68912c254df4e75cdc5aYao Chen
2224809bdb45c28244aeaa9c1795581d685780645cyro#include <android/util/ProtoOutputStream.h>
2393fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen#include <gtest/gtest_prod.h>
24e2cd6d509b17894b95d14523ae3e7c4c7a9a74e3Yangster-mac#include "../anomaly/AnomalyTracker.h"
25caf339d004fad667748b68912c254df4e75cdc5aYao Chen#include "../condition/ConditionTracker.h"
26caf339d004fad667748b68912c254df4e75cdc5aYao Chen#include "../matchers/matcher_util.h"
2744cf27c14880005df093f372491c593e1a9a3c58Yao Chen#include "MetricProducer.h"
2844cf27c14880005df093f372491c593e1a9a3c58Yao Chen#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
29729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include "stats_util.h"
3044cf27c14880005df093f372491c593e1a9a3c58Yao Chen
3144cf27c14880005df093f372491c593e1a9a3c58Yao Chennamespace android {
3244cf27c14880005df093f372491c593e1a9a3c58Yao Chennamespace os {
3344cf27c14880005df093f372491c593e1a9a3c58Yao Chennamespace statsd {
3444cf27c14880005df093f372491c593e1a9a3c58Yao Chen
3593fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chenstruct CountBucket {
3693fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen    int64_t mBucketStartNs;
3793fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen    int64_t mBucketEndNs;
3893fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen    int64_t mCount;
3993fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen};
4093fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen
4144cf27c14880005df093f372491c593e1a9a3c58Yao Chenclass CountMetricProducer : public MetricProducer {
4244cf27c14880005df093f372491c593e1a9a3c58Yao Chenpublic:
43729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    // TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics.
44b356151e63140085cb96fa16804ee18b3862a4fcYao Chen    CountMetricProducer(const ConfigKey& key, const CountMetric& countMetric,
45b356151e63140085cb96fa16804ee18b3862a4fcYao Chen                        const int conditionIndex, const sp<ConditionWizard>& wizard,
46b142cc8add29c8c97f6134d35873d23db666027cYangster-mac                        const int64_t startTimeNs);
4744cf27c14880005df093f372491c593e1a9a3c58Yao Chen
4844cf27c14880005df093f372491c593e1a9a3c58Yao Chen    virtual ~CountMetricProducer();
4944cf27c14880005df093f372491c593e1a9a3c58Yao Chen
50b704177d401de895c3b00d258885dc4243a7b3a7Yao Chenprotected:
51f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster    void onMatchedLogEventInternalLocked(
529369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac            const size_t matcherIndex, const MetricDimensionKey& eventKey,
532087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac            const ConditionKey& conditionKey, bool condition,
54a7259abde4e89fd91404b14b4845113cd313d1ecChenjie Yu            const LogEvent& event) override;
552b0f88678b2877a8e9f83cea60f097322b078367yro
5644cf27c14880005df093f372491c593e1a9a3c58Yao Chenprivate:
57e68f3a5811209eeab71976bc583c6075d9a5979aYangster-mac
58b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    void onDumpReportLocked(const int64_t dumpTimeNs,
59e68f3a5811209eeab71976bc583c6075d9a5979aYangster-mac                            const bool include_current_partial_bucket,
609def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                            std::set<string> *str_set,
61288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen                            android::util::ProtoOutputStream* protoOutput) override;
62f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster
63a802d73da625ac72f6a0211aab017f365139112dYangster-mac    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
64a802d73da625ac72f6a0211aab017f365139112dYangster-mac
65f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster    // Internal interface to handle condition change.
66b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
67f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster
68f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster    // Internal interface to handle sliced condition change.
69b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
70f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster
71f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster    // Internal function to calculate the current used bytes.
72f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster    size_t byteSizeLocked() const override;
73f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster
74a78d00874d4e274937734a1b73aef4b6389eb3cdYangster-mac    void dumpStatesLocked(FILE* out, bool verbose) const override;
75884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen
76b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    void dropDataLocked(const int64_t dropTimeNs) override;
7706dba5d79c096b02d3ba6fb73e64451ff12e388dYao Chen
78f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster    // Util function to flush the old packet.
79b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    void flushIfNeededLocked(const int64_t& newEventTime) override;
8027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
81b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
82f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster
832b0f88678b2877a8e9f83cea60f097322b078367yro    // TODO: Add a lock to mPastBuckets.
849369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac    std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;
8524809bdb45c28244aeaa9c1795581d685780645cyro
8627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // The current bucket (may be a partial bucket).
873eba62186592382ed3d97cecca0c547487e4b2e4Yang Lu    std::shared_ptr<DimToValMap> mCurrentSlicedCounter = std::make_shared<DimToValMap>();
88caf339d004fad667748b68912c254df4e75cdc5aYao Chen
8927785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // The sum of previous partial buckets in the current full bucket (excluding the current
9027785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    // partial bucket). This is only updated while flushing the current bucket.
9127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    std::shared_ptr<DimToValMap> mCurrentFullCounters = std::make_shared<DimToValMap>();
9227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
93e2cd6d509b17894b95d14523ae3e7c4c7a9a74e3Yangster-mac    static const size_t kBucketSize = sizeof(CountBucket{});
9424809bdb45c28244aeaa9c1795581d685780645cyro
959369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac    bool hitGuardRailLocked(const MetricDimensionKey& newKey);
96b356151e63140085cb96fa16804ee18b3862a4fcYao Chen
9793fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen    FRIEND_TEST(CountMetricProducerTest, TestNonDimensionalEvents);
9893fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen    FRIEND_TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition);
9993fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen    FRIEND_TEST(CountMetricProducerTest, TestEventsWithSlicedCondition);
1001bf94382d036fa8d61258205c5f4e18cd53cb61dBookatz    FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
10127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    FRIEND_TEST(CountMetricProducerTest, TestEventWithAppUpgrade);
10227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    FRIEND_TEST(CountMetricProducerTest, TestEventWithAppUpgradeInNextBucket);
10344cf27c14880005df093f372491c593e1a9a3c58Yao Chen};
10444cf27c14880005df093f372491c593e1a9a3c58Yao Chen
10544cf27c14880005df093f372491c593e1a9a3c58Yao Chen}  // namespace statsd
10644cf27c14880005df093f372491c593e1a9a3c58Yao Chen}  // namespace os
10744cf27c14880005df093f372491c593e1a9a3c58Yao Chen}  // namespace android
10844cf27c14880005df093f372491c593e1a9a3c58Yao Chen#endif  // COUNT_METRIC_PRODUCER_H
109