1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <gtest/gtest_prod.h>
20 #include "config/ConfigListener.h"
21 #include "logd/LogReader.h"
22 #include "metrics/MetricsManager.h"
23 #include "packages/UidMap.h"
24 #include "external/StatsPullerManager.h"
25 
26 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
27 
28 #include <stdio.h>
29 #include <unordered_map>
30 
31 namespace android {
32 namespace os {
33 namespace statsd {
34 
35 // Keep this in sync with DumpReportReason enum in stats_log.proto
36 enum DumpReportReason {
37     DEVICE_SHUTDOWN = 1,
38     CONFIG_UPDATED = 2,
39     CONFIG_REMOVED = 3,
40     GET_DATA_CALLED = 4,
41     ADB_DUMP = 5,
42     CONFIG_RESET = 6,
43     STATSCOMPANION_DIED = 7
44 };
45 
46 class StatsLogProcessor : public ConfigListener {
47 public:
48     StatsLogProcessor(const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor,
49                       const sp<AlarmMonitor>& subscriberTriggerAlarmMonitor,
50                       const int64_t timeBaseNs,
51                       const std::function<bool(const ConfigKey&)>& sendBroadcast);
52     virtual ~StatsLogProcessor();
53 
54     void OnLogEvent(LogEvent* event, bool reconnectionStarts);
55 
56     // for testing only.
57     void OnLogEvent(LogEvent* event);
58 
59     void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
60                          const StatsdConfig& config);
61     void OnConfigRemoved(const ConfigKey& key);
62 
63     size_t GetMetricsSize(const ConfigKey& key) const;
64 
65     void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
66                       const bool include_current_partial_bucket,
67                       const DumpReportReason dumpReportReason, vector<uint8_t>* outData);
68 
69     /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
70     void onAnomalyAlarmFired(
71             const int64_t& timestampNs,
72             unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
73 
74     /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
75     void onPeriodicAlarmFired(
76             const int64_t& timestampNs,
77             unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
78 
79     /* Flushes data to disk. Data on memory will be gone after written to disk. */
80     void WriteDataToDisk(const DumpReportReason dumpReportReason);
81 
82     // Reset all configs.
83     void resetConfigs();
84 
getUidMap()85     inline sp<UidMap> getUidMap() {
86         return mUidMap;
87     }
88 
89     void dumpStates(FILE* out, bool verbose);
90 
91     void informPullAlarmFired(const int64_t timestampNs);
92 
93     int64_t getLastReportTimeNs(const ConfigKey& key);
94 
setPrintLogs(bool enabled)95     inline void setPrintLogs(bool enabled) {
96 #ifdef VERY_VERBOSE_PRINTING
97         std::lock_guard<std::mutex> lock(mMetricsMutex);
98         mPrintAllLogs = enabled;
99 #endif
100     }
101 
102     // Add a specific config key to the possible configs to dump ASAP.
103     void noteOnDiskData(const ConfigKey& key);
104 
105 private:
106     // For testing only.
getAnomalyAlarmMonitor()107     inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
108         return mAnomalyAlarmMonitor;
109     }
110 
getPeriodicAlarmMonitor()111     inline sp<AlarmMonitor> getPeriodicAlarmMonitor() const {
112         return mPeriodicAlarmMonitor;
113     }
114 
115     mutable mutex mMetricsMutex;
116 
117     std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers;
118 
119     std::unordered_map<ConfigKey, long> mLastBroadcastTimes;
120 
121     // Tracks when we last checked the bytes consumed for each config key.
122     std::unordered_map<ConfigKey, long> mLastByteSizeTimes;
123 
124     // Tracks which config keys has metric reports on disk
125     std::set<ConfigKey> mOnDiskDataConfigs;
126 
127     sp<UidMap> mUidMap;  // Reference to the UidMap to lookup app name and version for each uid.
128 
129     StatsPullerManager mStatsPullerManager;
130 
131     sp<AlarmMonitor> mAnomalyAlarmMonitor;
132 
133     sp<AlarmMonitor> mPeriodicAlarmMonitor;
134 
135     void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
136 
137     void OnConfigUpdatedLocked(
138         const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
139 
140     void WriteDataToDiskLocked(const DumpReportReason dumpReportReason);
141     void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs,
142                                const DumpReportReason dumpReportReason);
143 
144     void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs,
145                                      const bool include_current_partial_bucket,
146                                      const DumpReportReason dumpReportReason,
147                                      util::ProtoOutputStream* proto);
148 
149     /* Check if we should send a broadcast if approaching memory limits and if we're over, we
150      * actually delete the data. */
151     void flushIfNecessaryLocked(int64_t timestampNs, const ConfigKey& key,
152                                 MetricsManager& metricsManager);
153 
154     // Maps the isolated uid in the log event to host uid if the log event contains uid fields.
155     void mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const;
156 
157     // Handler over the isolated uid change event.
158     void onIsolatedUidChangedEventLocked(const LogEvent& event);
159 
160     // Reset all configs.
161     void resetConfigsLocked(const int64_t timestampNs);
162     // Reset the specified configs.
163     void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs);
164 
165     // Function used to send a broadcast so that receiver for the config key can call getData
166     // to retrieve the stored data.
167     std::function<bool(const ConfigKey& key)> mSendBroadcast;
168 
169     const int64_t mTimeBaseNs;
170 
171     // Largest timestamp of the events that we have processed.
172     int64_t mLargestTimestampSeen = 0;
173 
174     int64_t mLastTimestampSeen = 0;
175 
176     bool mInReconnection = false;
177 
178     // Processed log count
179     uint64_t mLogCount = 0;
180 
181     // Log loss detected count
182     int mLogLossCount = 0;
183 
184     long mLastPullerCacheClearTimeSec = 0;
185 
186 #ifdef VERY_VERBOSE_PRINTING
187     bool mPrintAllLogs = false;
188 #endif
189 
190     FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs);
191     FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
192     FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast);
193     FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
194     FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
195     FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
196     FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3);
197     FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1);
198     FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2);
199     FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3);
200     FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1);
201     FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2);
202     FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
203     FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
204     FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
205     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
206     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
207     FRIEND_TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents);
208     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
209     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
210 
211     FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition);
212     FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition);
213     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition);
214     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition);
215 
216     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition);
217     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition);
218     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition);
219 
220     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition);
221     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition);
222     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition);
223 
224     FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
225     FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
226     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
227     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
228     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
229 
230     FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
231     FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
232 };
233 
234 }  // namespace statsd
235 }  // namespace os
236 }  // namespace android
237