1 /*
2  * Copyright 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 #pragma once
17 
18 #include "config/ConfigKey.h"
19 
20 #include <gtest/gtest_prod.h>
21 #include <log/log_time.h>
22 #include <list>
23 #include <mutex>
24 #include <string>
25 #include <vector>
26 #include <unordered_map>
27 
28 namespace android {
29 namespace os {
30 namespace statsd {
31 
32 struct ConfigStats {
33     int32_t uid;
34     int64_t id;
35     int32_t creation_time_sec;
36     int32_t deletion_time_sec = 0;
37     int32_t reset_time_sec = 0;
38     int32_t metric_count;
39     int32_t condition_count;
40     int32_t matcher_count;
41     int32_t alert_count;
42     bool is_valid;
43 
44     std::list<int32_t> broadcast_sent_time_sec;
45 
46     // Times at which this config is activated.
47     std::list<int32_t> activation_time_sec;
48 
49     // Times at which this config is deactivated.
50     std::list<int32_t> deactivation_time_sec;
51 
52     std::list<int32_t> data_drop_time_sec;
53     // Number of bytes dropped at corresponding time.
54     std::list<int64_t> data_drop_bytes;
55     std::list<std::pair<int32_t, int64_t>> dump_report_stats;
56 
57     // Stores how many times a matcher have been matched. The map size is capped by kMaxConfigCount.
58     std::map<const int64_t, int> matcher_stats;
59 
60     // Stores the number of output tuple of condition trackers when it's bigger than
61     // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
62     // it means some data has been dropped. The map size is capped by kMaxConfigCount.
63     std::map<const int64_t, int> condition_stats;
64 
65     // Stores the number of output tuple of metric producers when it's bigger than
66     // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
67     // it means some data has been dropped. The map size is capped by kMaxConfigCount.
68     std::map<const int64_t, int> metric_stats;
69 
70     // Stores the max number of output tuple of dimensions in condition across dimensions in what
71     // when it's bigger than kDimensionKeySizeSoftLimit. When you see the number is
72     // kDimensionKeySizeHardLimit +1, it means some data has been dropped. The map size is capped by
73     // kMaxConfigCount.
74     std::map<const int64_t, int> metric_dimension_in_condition_stats;
75 
76     // Stores the number of times an anomaly detection alert has been declared.
77     // The map size is capped by kMaxConfigCount.
78     std::map<const int64_t, int> alert_stats;
79 
80     // Stores the config ID for each sub-config used.
81     std::list<std::pair<const int64_t, const int32_t>> annotations;
82 };
83 
84 struct UidMapStats {
85     int32_t changes;
86     int32_t bytes_used;
87     int32_t dropped_changes;
88     int32_t deleted_apps = 0;
89 };
90 
91 // Keeps track of stats of statsd.
92 // Single instance shared across the process. All public methods are thread safe.
93 class StatsdStats {
94 public:
95     static StatsdStats& getInstance();
~StatsdStats()96     ~StatsdStats(){};
97 
98     const static int kDimensionKeySizeSoftLimit = 500;
99     const static int kDimensionKeySizeHardLimit = 800;
100 
101     // Per atom dimension key size limit
102     static const std::map<int, std::pair<size_t, size_t>> kAtomDimensionKeySizeLimitMap;
103 
104     const static int kMaxConfigCountPerUid = 20;
105     const static int kMaxAlertCountPerConfig = 100;
106     const static int kMaxConditionCountPerConfig = 300;
107     const static int kMaxMetricCountPerConfig = 1000;
108     const static int kMaxMatcherCountPerConfig = 800;
109 
110     // The max number of old config stats we keep.
111     const static int kMaxIceBoxSize = 20;
112 
113     const static int kMaxLoggerErrors = 20;
114 
115     const static int kMaxSystemServerRestarts = 20;
116 
117     const static int kMaxTimestampCount = 20;
118 
119     const static int kMaxLogSourceCount = 50;
120 
121     const static int kMaxPullAtomPackages = 100;
122 
123     // Max memory allowed for storing metrics per configuration. If this limit is exceeded, statsd
124     // drops the metrics data in memory.
125     static const size_t kMaxMetricsBytesPerConfig = 2 * 1024 * 1024;
126 
127     // Soft memory limit per configuration. Once this limit is exceeded, we begin notifying the
128     // data subscriber that it's time to call getData.
129     static const size_t kBytesPerConfigTriggerGetData = 192 * 1024;
130 
131     // Cap the UID map's memory usage to this. This should be fairly high since the UID information
132     // is critical for understanding the metrics.
133     const static size_t kMaxBytesUsedUidMap = 50 * 1024;
134 
135     // The number of deleted apps that are stored in the uid map.
136     const static int kMaxDeletedAppsInUidMap = 100;
137 
138     /* Minimum period between two broadcasts in nanoseconds. */
139     static const int64_t kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
140 
141     /* Min period between two checks of byte size per config key in nanoseconds. */
142     static const int64_t kMinByteSizeCheckPeriodNs = 60 * NS_PER_SEC;
143 
144     /* Minimum period between two activation broadcasts in nanoseconds. */
145     static const int64_t kMinActivationBroadcastPeriodNs = 10 * NS_PER_SEC;
146 
147     // Maximum age (30 days) that files on disk can exist in seconds.
148     static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
149 
150     // Maximum age (2 days) that local history files on disk can exist in seconds.
151     static const int kMaxLocalHistoryAgeSecond = 60 * 60 * 24 * 2;
152 
153     // Maximum number of files (1000) that can be in stats directory on disk.
154     static const int kMaxFileNumber = 1000;
155 
156     // Maximum size of all files that can be written to stats directory on disk.
157     static const int kMaxFileSize = 50 * 1024 * 1024;
158 
159     // How long to try to clear puller cache from last time
160     static const long kPullerCacheClearIntervalSec = 1;
161 
162     // Max time to do a pull.
163     static const int64_t kPullMaxDelayNs = 30 * NS_PER_SEC;
164 
165     // Maximum number of pushed atoms statsd stats will track above kMaxPushedAtomId.
166     static const int kMaxNonPlatformPushedAtoms = 100;
167 
168     // Maximum atom id value that we consider a platform pushed atom.
169     // This should be updated once highest pushed atom id in atoms.proto approaches this value.
170     static const int kMaxPushedAtomId = 500;
171 
172     // Atom id that is the start of the pulled atoms.
173     static const int kPullAtomStartTag = 10000;
174 
175     // Atom id that is the start of vendor atoms.
176     static const int kVendorAtomStartTag = 100000;
177 
178     // Vendor pulled atom start id.
179     static const int32_t kVendorPulledAtomStartTag = 150000;
180 
181     // Beginning of range for timestamp truncation.
182     static const int32_t kTimestampTruncationStartTag = 300000;
183 
184     // End of range for timestamp truncation.
185     static const int32_t kTimestampTruncationEndTag = 304999;
186 
187     // Max accepted atom id.
188     static const int32_t kMaxAtomTag = 200000;
189 
190     static const int64_t kInt64Max = 0x7fffffffffffffffLL;
191 
192     static const int32_t kMaxLoggedBucketDropEvents = 10;
193 
194     /**
195      * Report a new config has been received and report the static stats about the config.
196      *
197      * The static stats include: the count of metrics, conditions, matchers, and alerts.
198      * If the config is not valid, this config stats will be put into icebox immediately.
199      */
200     void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
201                             int matchersCount, int alertCount,
202                             const std::list<std::pair<const int64_t, const int32_t>>& annotations,
203                             bool isValid);
204     /**
205      * Report a config has been removed.
206      */
207     void noteConfigRemoved(const ConfigKey& key);
208     /**
209      * Report a config has been reset when ttl expires.
210      */
211     void noteConfigReset(const ConfigKey& key);
212 
213     /**
214      * Report a broadcast has been sent to a config owner to collect the data.
215      */
216     void noteBroadcastSent(const ConfigKey& key);
217 
218     /**
219      * Report that a config has become activated or deactivated.
220      * This can be different from whether or not a broadcast is sent if the
221      * guardrail prevented the broadcast from being sent.
222      */
223     void noteActiveStatusChanged(const ConfigKey& key, bool activate);
224 
225     /**
226      * Report a config's metrics data has been dropped.
227      */
228     void noteDataDropped(const ConfigKey& key, const size_t totalBytes);
229 
230     /**
231      * Report metrics data report has been sent.
232      *
233      * The report may be requested via StatsManager API, or through adb cmd.
234      */
235     void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes);
236 
237     /**
238      * Report the size of output tuple of a condition.
239      *
240      * Note: only report when the condition has an output dimension, and the tuple
241      * count > kDimensionKeySizeSoftLimit.
242      *
243      * [key]: The config key that this condition belongs to.
244      * [id]: The id of the condition.
245      * [size]: The output tuple size.
246      */
247     void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
248 
249     /**
250      * Report the size of output tuple of a metric.
251      *
252      * Note: only report when the metric has an output dimension, and the tuple
253      * count > kDimensionKeySizeSoftLimit.
254      *
255      * [key]: The config key that this metric belongs to.
256      * [id]: The id of the metric.
257      * [size]: The output tuple size.
258      */
259     void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
260 
261     /**
262      * Report the max size of output tuple of dimension in condition across dimensions in what.
263      *
264      * Note: only report when the metric has an output dimension in condition, and the max tuple
265      * count > kDimensionKeySizeSoftLimit.
266      *
267      * [key]: The config key that this metric belongs to.
268      * [id]: The id of the metric.
269      * [size]: The output tuple size.
270      */
271     void noteMetricDimensionInConditionSize(const ConfigKey& key, const int64_t& id, int size);
272 
273     /**
274      * Report a matcher has been matched.
275      *
276      * [key]: The config key that this matcher belongs to.
277      * [id]: The id of the matcher.
278      */
279     void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
280 
281     /**
282      * Report that an anomaly detection alert has been declared.
283      *
284      * [key]: The config key that this alert belongs to.
285      * [id]: The id of the alert.
286      */
287     void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
288 
289     /**
290      * Report an atom event has been logged.
291      */
292     void noteAtomLogged(int atomId, int32_t timeSec);
293 
294     /**
295      * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
296      */
297     void noteRegisteredAnomalyAlarmChanged();
298 
299     /**
300      * Report that statsd modified the periodic alarm registered with StatsCompanionService.
301      */
302     void noteRegisteredPeriodicAlarmChanged();
303 
304     /**
305      * Records the number of delta entries that are being dropped from the uid map.
306      */
307     void noteUidMapDropped(int deltas);
308 
309     /**
310      * Records that an app was deleted (from statsd's map).
311      */
312     void noteUidMapAppDeletionDropped();
313 
314     /**
315      * Updates the number of changes currently stored in the uid map.
316      */
317     void setUidMapChanges(int changes);
318     void setCurrentUidMapMemory(int bytes);
319 
320     /*
321      * Updates minimum interval between pulls for an pulled atom.
322      */
323     void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
324 
325     /*
326      * Notes an atom is pulled.
327      */
328     void notePull(int pullAtomId);
329 
330     /*
331      * Notes an atom is served from puller cache.
332      */
333     void notePullFromCache(int pullAtomId);
334 
335     /*
336      * Notify data error for pulled atom.
337      */
338     void notePullDataError(int pullAtomId);
339 
340     /*
341      * Records time for actual pulling, not including those served from cache and not including
342      * statsd processing delays.
343      */
344     void notePullTime(int pullAtomId, int64_t pullTimeNs);
345 
346     /*
347      * Records pull delay for a pulled atom, including those served from cache and including statsd
348      * processing delays.
349      */
350     void notePullDelay(int pullAtomId, int64_t pullDelayNs);
351 
352     /*
353      * Records pull exceeds timeout for the puller.
354      */
355     void notePullTimeout(int pullAtomId, int64_t pullUptimeMillis, int64_t pullElapsedMillis);
356 
357     /*
358      * Records pull exceeds max delay for a metric.
359      */
360     void notePullExceedMaxDelay(int pullAtomId);
361 
362     /*
363      * Records when system server restarts.
364      */
365     void noteSystemServerRestart(int32_t timeSec);
366 
367     /**
368      * Records statsd skipped an event.
369      */
370     void noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
371                      int32_t lastAtomTag, int32_t uid, int32_t pid);
372 
373     /**
374      * Records that the pull of an atom has failed. Eg, if the client indicated the pull failed, if
375      * the pull timed out, or if the outgoing binder call failed.
376      * This count will only increment if the puller was actually invoked.
377      *
378      * It does not include a pull not occurring due to not finding the appropriate
379      * puller. These cases are covered in other counts.
380      */
381     void notePullFailed(int atomId);
382 
383     /**
384      * Records that the pull of an atom has failed due to not having a uid provider.
385      */
386     void notePullUidProviderNotFound(int atomId);
387 
388     /**
389      * Records that the pull of an atom has failed due not finding a puller registered by a
390      * trusted uid.
391      */
392     void notePullerNotFound(int atomId);
393 
394     /**
395      * Records that the pull has failed due to the outgoing binder call failing.
396      */
397     void notePullBinderCallFailed(int atomId);
398 
399     /**
400      * A pull with no data occurred
401      */
402     void noteEmptyData(int atomId);
403 
404     /**
405      * Records that a puller callback for the given atomId was registered or unregistered.
406      *
407      * @param registered True if the callback was registered, false if was unregistered.
408      */
409     void notePullerCallbackRegistrationChanged(int atomId, bool registered);
410 
411     /**
412      * Hard limit was reached in the cardinality of an atom
413      */
414     void noteHardDimensionLimitReached(int64_t metricId);
415 
416     /**
417      * A log event was too late, arrived in the wrong bucket and was skipped
418      */
419     void noteLateLogEventSkipped(int64_t metricId);
420 
421     /**
422      * Buckets were skipped as time elapsed without any data for them
423      */
424     void noteSkippedForwardBuckets(int64_t metricId);
425 
426     /**
427      * An unsupported value type was received
428      */
429     void noteBadValueType(int64_t metricId);
430 
431     /**
432      * Buckets were dropped due to reclaim memory.
433      */
434     void noteBucketDropped(int64_t metricId);
435 
436     /**
437      * A condition change was too late, arrived in the wrong bucket and was skipped
438      */
439     void noteConditionChangeInNextBucket(int64_t metricId);
440 
441     /**
442      * A bucket has been tagged as invalid.
443      */
444     void noteInvalidatedBucket(int64_t metricId);
445 
446     /**
447      * Tracks the total number of buckets (include skipped/invalid buckets).
448      */
449     void noteBucketCount(int64_t metricId);
450 
451     /**
452      * For pulls at bucket boundaries, it represents the misalignment between the real timestamp and
453      * the end of the bucket.
454      */
455     void noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs);
456 
457     /**
458      * Number of buckets with unknown condition.
459      */
460     void noteBucketUnknownCondition(int64_t metricId);
461 
462     /* Reports one event has been dropped due to queue overflow, and the oldest event timestamp in
463      * the queue */
464     void noteEventQueueOverflow(int64_t oldestEventTimestampNs);
465 
466     /**
467      * Reports that the activation broadcast guardrail was hit for this uid. Namely, the broadcast
468      * should have been sent, but instead was skipped due to hitting the guardrail.
469      */
470      void noteActivationBroadcastGuardrailHit(const int uid);
471 
472      /**
473       * Reports that an atom is erroneous or cannot be parsed successfully by
474       * statsd. An atom tag of 0 indicates that the client did not supply the
475       * atom id within the encoding.
476       *
477       * For pushed atoms only, this call should be preceded by a call to
478       * noteAtomLogged.
479       */
480      void noteAtomError(int atomTag, bool pull=false);
481 
482     /**
483      * Reset the historical stats. Including all stats in icebox, and the tracked stats about
484      * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
485      * to collect stats after reset() has been called.
486      */
487     void reset();
488 
489     /**
490      * Output the stats in protobuf binary format to [buffer].
491      *
492      * [reset]: whether to clear the historical stats after the call.
493      */
494     void dumpStats(std::vector<uint8_t>* buffer, bool reset);
495 
496     /**
497      * Output statsd stats in human readable format to [out] file descriptor.
498      */
499     void dumpStats(int outFd) const;
500 
501     typedef struct PullTimeoutMetadata {
502         int64_t pullTimeoutUptimeMillis;
503         int64_t pullTimeoutElapsedMillis;
PullTimeoutMetadataPullTimeoutMetadata504         PullTimeoutMetadata(int64_t uptimeMillis, int64_t elapsedMillis) :
505             pullTimeoutUptimeMillis(uptimeMillis),
506             pullTimeoutElapsedMillis(elapsedMillis) {/* do nothing */}
507     } PullTimeoutMetadata;
508 
509     typedef struct {
510         long totalPull = 0;
511         long totalPullFromCache = 0;
512         long minPullIntervalSec = LONG_MAX;
513         int64_t avgPullTimeNs = 0;
514         int64_t maxPullTimeNs = 0;
515         long numPullTime = 0;
516         int64_t avgPullDelayNs = 0;
517         int64_t maxPullDelayNs = 0;
518         long numPullDelay = 0;
519         long dataError = 0;
520         long pullTimeout = 0;
521         long pullExceedMaxDelay = 0;
522         long pullFailed = 0;
523         long pullUidProviderNotFound = 0;
524         long pullerNotFound = 0;
525         long emptyData = 0;
526         long registeredCount = 0;
527         long unregisteredCount = 0;
528         int32_t atomErrorCount = 0;
529         long binderCallFailCount = 0;
530         std::list<PullTimeoutMetadata> pullTimeoutMetadata;
531     } PulledAtomStats;
532 
533     typedef struct {
534         long hardDimensionLimitReached = 0;
535         long lateLogEventSkipped = 0;
536         long skippedForwardBuckets = 0;
537         long badValueType = 0;
538         long conditionChangeInNextBucket = 0;
539         long invalidatedBucket = 0;
540         long bucketDropped = 0;
541         int64_t minBucketBoundaryDelayNs = 0;
542         int64_t maxBucketBoundaryDelayNs = 0;
543         long bucketUnknownCondition = 0;
544         long bucketCount = 0;
545     } AtomMetricStats;
546 
547 private:
548     StatsdStats();
549 
550     mutable std::mutex mLock;
551 
552     int32_t mStartTimeSec;
553 
554     // Track the number of dropped entries used by the uid map.
555     UidMapStats mUidMapStats;
556 
557     // The stats about the configs that are still in use.
558     // The map size is capped by kMaxConfigCount.
559     std::map<const ConfigKey, std::shared_ptr<ConfigStats>> mConfigStats;
560 
561     // Stores the stats for the configs that are no longer in use.
562     // The size of the vector is capped by kMaxIceBoxSize.
563     std::list<const std::shared_ptr<ConfigStats>> mIceBox;
564 
565     // Stores the number of times a pushed atom is logged.
566     // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
567     // out of that range will be put in mNonPlatformPushedAtomStats.
568     // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
569     std::vector<int> mPushedAtomStats;
570 
571     // Stores the number of times a pushed atom is logged for atom ids above kMaxPushedAtomId.
572     // The max size of the map is kMaxNonPlatformPushedAtoms.
573     std::unordered_map<int, int> mNonPlatformPushedAtomStats;
574 
575     // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
576     std::map<int, PulledAtomStats> mPulledAtomStats;
577 
578     // Stores the number of times a pushed atom was logged erroneously. The
579     // corresponding counts for pulled atoms are stored in PulledAtomStats.
580     // The max size of this map is kMaxAtomErrorsStatsSize.
581     std::map<int, int> mPushedAtomErrorStats;
582     int kMaxPushedAtomErrorStatsSize = 100;
583 
584     // Maps metric ID to its stats. The size is capped by the number of metrics.
585     std::map<int64_t, AtomMetricStats> mAtomMetricStats;
586 
587     // Maps uids to times when the activation changed broadcast not sent due to hitting the
588     // guardrail. The size is capped by the number of configs, and up to 20 times per uid.
589     std::map<int, std::list<int32_t>> mActivationBroadcastGuardrailStats;
590 
591     struct LogLossStats {
LogLossStatsLogLossStats592         LogLossStats(int32_t sec, int32_t count, int32_t error, int32_t tag, int32_t uid,
593                      int32_t pid)
594             : mWallClockSec(sec),
595               mCount(count),
596               mLastError(error),
597               mLastTag(tag),
598               mUid(uid),
599               mPid(pid) {
600         }
601         int32_t mWallClockSec;
602         int32_t mCount;
603         // error code defined in linux/errno.h
604         int32_t mLastError;
605         int32_t mLastTag;
606         int32_t mUid;
607         int32_t mPid;
608     };
609 
610     // Max of {(now - oldestEventTimestamp) when overflow happens}.
611     // This number is helpful to understand how SLOW statsd can be.
612     int64_t mMaxQueueHistoryNs = 0;
613 
614     // Min of {(now - oldestEventTimestamp) when overflow happens}.
615     // This number is helpful to understand how FAST the events floods to statsd.
616     int64_t mMinQueueHistoryNs = kInt64Max;
617 
618     // Total number of events that are lost due to queue overflow.
619     int32_t mOverflowCount = 0;
620 
621     // Timestamps when we detect log loss, and the number of logs lost.
622     std::list<LogLossStats> mLogLossStats;
623 
624     std::list<int32_t> mSystemServerRestartSec;
625 
626     // Stores the number of times statsd modified the anomaly alarm registered with
627     // StatsCompanionService.
628     int mAnomalyAlarmRegisteredStats = 0;
629 
630     // Stores the number of times statsd registers the periodic alarm changes
631     int mPeriodicAlarmRegisteredStats = 0;
632 
633     void noteConfigResetInternalLocked(const ConfigKey& key);
634 
635     void noteConfigRemovedInternalLocked(const ConfigKey& key);
636 
637     void resetInternalLocked();
638 
639     void noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec);
640 
641     void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes, int32_t timeSec);
642 
643     void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
644 
645     void noteActiveStatusChanged(const ConfigKey& key, bool activate, int32_t timeSec);
646 
647     void noteActivationBroadcastGuardrailHit(const int uid, int32_t timeSec);
648 
649     void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
650 
651     int getPushedAtomErrors(int atomId) const;
652 
653     /**
654      * Get a reference to AtomMetricStats for a metric. If none exists, create it. The reference
655      * will live as long as `this`.
656      */
657     StatsdStats::AtomMetricStats& getAtomMetricStats(int64_t metricId);
658 
659     FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
660     FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
661     FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
662     FRIEND_TEST(StatsdStatsTest, TestSubStats);
663     FRIEND_TEST(StatsdStatsTest, TestAtomLog);
664     FRIEND_TEST(StatsdStatsTest, TestNonPlatformAtomLog);
665     FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
666     FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
667     FRIEND_TEST(StatsdStatsTest, TestSystemServerCrash);
668     FRIEND_TEST(StatsdStatsTest, TestPullAtomStats);
669     FRIEND_TEST(StatsdStatsTest, TestAtomMetricsStats);
670     FRIEND_TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit);
671     FRIEND_TEST(StatsdStatsTest, TestAtomErrorStats);
672 
673     FRIEND_TEST(StatsLogProcessorTest, InvalidConfigRemoved);
674 };
675 
676 }  // namespace statsd
677 }  // namespace os
678 }  // namespace android
679