1 /*
2  * Copyright (C) 2021 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 package com.android.helpers;
18 
19 import androidx.annotation.VisibleForTesting;
20 
21 import com.android.os.nano.StatsLog;
22 
23 import java.util.HashMap;
24 import java.util.Map;
25 
26 /**
27  * StatsdStatsHelper consist of helper methods to set the Statsd metadata collection and retrieve
28  * the necessary information from statsd.
29  */
30 public class StatsdStatsHelper implements ICollectorHelper<Long> {
31 
32     static final String STATSDSTATS_PREFIX = "statsdstats";
33     static final String ATOM_STATS_PREFIX = "atom_stats";
34     static final String MATCHER_STATS_PREFIX = "matcher_stats";
35     static final String CONDITION_STATS_PREFIX = "condition_stats";
36     static final String METRIC_STATS_PREFIX = "metric_stats";
37     static final String ALERT_STATS_PREFIX = "alert_stats";
38     static final String CONFIG_STATS_PREFIX = "config_stats";
39     static final String ANOMALY_ALARM_STATS_PREFIX = "anomaly_alarm_stats";
40     static final String PULLED_ATOM_STATS_PREFIX = "pulled_atom_stats";
41     static final String ATOM_METRIC_STATS_PREFIX = "atom_metric_stats";
42     static final String DETECTED_LOG_LOSS_STATS_PREFIX = "detected_log_loss_stats";
43     static final String EVENT_QUEUE_OVERFLOW_STATS_PREFIX = "event_queue_overflow_stats";
44 
45     interface IStatsdHelper {
getStatsdStatsReport()46         StatsLog.StatsdStatsReport getStatsdStatsReport();
47     }
48 
49     private static class DefaultStatsdHelper implements IStatsdHelper {
50 
51         private StatsdHelper mStatsdHelper = new StatsdHelper();
52 
53         @Override
getStatsdStatsReport()54         public StatsLog.StatsdStatsReport getStatsdStatsReport() {
55             return mStatsdHelper.getStatsdStatsReport();
56         }
57     }
58 
59     private IStatsdHelper mStatsdHelper = new DefaultStatsdHelper();
60 
StatsdStatsHelper()61     public StatsdStatsHelper() {}
62 
63     /**
64      * Constructor to simulate an externally provided statsd helper instance. Should not be used
65      * except for testing.
66      */
67     @VisibleForTesting
StatsdStatsHelper(IStatsdHelper helper)68     StatsdStatsHelper(IStatsdHelper helper) {
69         mStatsdHelper = helper;
70     }
71 
72     /** Resets statsd metadata */
73     @Override
startCollecting()74     public boolean startCollecting() {
75         // TODO: http://b/204890512 implement metadata reset
76         return true;
77     }
78 
79     /** Collect the statsd metadata accumulated during the test run. */
80     @Override
getMetrics()81     public Map<String, Long> getMetrics() {
82         Map<String, Long> resultMap = new HashMap<>();
83 
84         final StatsLog.StatsdStatsReport report = mStatsdHelper.getStatsdStatsReport();
85         populateAtomStats(report.atomStats, resultMap);
86         populateConfigStats(report.configStats, resultMap);
87         populateAnomalyAlarmStats(report.anomalyAlarmStats, resultMap);
88         populatePulledAtomStats(report.pulledAtomStats, resultMap);
89         populateAtomMetricStats(report.atomMetricStats, resultMap);
90         populateDetectedLogLossStats(report.detectedLogLoss, resultMap);
91         populateEventQueueOverflowStats(report.queueOverflow, resultMap);
92 
93         return resultMap;
94     }
95 
96     @Override
stopCollecting()97     public boolean stopCollecting() {
98         return true;
99     }
100 
populateAtomStats( StatsLog.StatsdStatsReport.AtomStats[] stats, Map<String, Long> resultMap)101     private static void populateAtomStats(
102             StatsLog.StatsdStatsReport.AtomStats[] stats, Map<String, Long> resultMap) {
103         final String metricKeyPrefix =
104                 MetricUtility.constructKey(STATSDSTATS_PREFIX, ATOM_STATS_PREFIX);
105 
106         int summaryCount = 0;
107         int summaryErrorCount = 0;
108 
109         for (final StatsLog.StatsdStatsReport.AtomStats dataItem : stats) {
110             final String metricKeyPrefixWithTag =
111                     MetricUtility.constructKey(metricKeyPrefix, String.valueOf(dataItem.tag));
112 
113             resultMap.put(
114                     MetricUtility.constructKey(metricKeyPrefixWithTag, "count"),
115                     Long.valueOf(dataItem.count));
116             resultMap.put(
117                     MetricUtility.constructKey(metricKeyPrefixWithTag, "error_count"),
118                     Long.valueOf(dataItem.errorCount));
119 
120             summaryCount += dataItem.count;
121             summaryErrorCount += dataItem.errorCount;
122         }
123 
124         resultMap.put(
125                 MetricUtility.constructKey(metricKeyPrefix, "count"), Long.valueOf(summaryCount));
126         resultMap.put(
127                 MetricUtility.constructKey(metricKeyPrefix, "error_count"),
128                 Long.valueOf(summaryErrorCount));
129     }
130 
populateConfigStats( StatsLog.StatsdStatsReport.ConfigStats[] configStats, Map<String, Long> resultMap)131     private static void populateConfigStats(
132             StatsLog.StatsdStatsReport.ConfigStats[] configStats, Map<String, Long> resultMap) {
133         final String metricKeyPrefix =
134                 MetricUtility.constructKey(STATSDSTATS_PREFIX, CONFIG_STATS_PREFIX);
135 
136         for (final StatsLog.StatsdStatsReport.ConfigStats dataItem : configStats) {
137             final String metricKeyPrefixWithTag =
138                     MetricUtility.constructKey(metricKeyPrefix, String.valueOf(dataItem.id));
139 
140             resultMap.put(
141                     MetricUtility.constructKey(metricKeyPrefixWithTag, "metric_count"),
142                     Long.valueOf(dataItem.metricCount));
143             resultMap.put(
144                     MetricUtility.constructKey(metricKeyPrefixWithTag, "condition_count"),
145                     Long.valueOf(dataItem.conditionCount));
146             resultMap.put(
147                     MetricUtility.constructKey(metricKeyPrefixWithTag, "matcher_count"),
148                     Long.valueOf(dataItem.matcherCount));
149             resultMap.put(
150                     MetricUtility.constructKey(metricKeyPrefixWithTag, "alert_count"),
151                     Long.valueOf(dataItem.alertCount));
152 
153             populateMatcherStats(
154                     dataItem.matcherStats, resultMap, metricKeyPrefixWithTag, metricKeyPrefix);
155             populateConditionStats(
156                     dataItem.conditionStats, resultMap, metricKeyPrefixWithTag, metricKeyPrefix);
157             populateMetricStats(
158                     dataItem.metricStats, resultMap, metricKeyPrefixWithTag, metricKeyPrefix);
159             populateAlertStats(
160                     dataItem.alertStats, resultMap, metricKeyPrefixWithTag, metricKeyPrefix);
161         }
162     }
163 
populateMetricStats( StatsLog.StatsdStatsReport.MetricStats[] stats, Map<String, Long> resultMap, String metricKeyPrefixWithTag, String metricKeyPrefix)164     private static void populateMetricStats(
165             StatsLog.StatsdStatsReport.MetricStats[] stats,
166             Map<String, Long> resultMap,
167             String metricKeyPrefixWithTag,
168             String metricKeyPrefix) {
169         int summaryCount = 0;
170 
171         for (final StatsLog.StatsdStatsReport.MetricStats dataItem : stats) {
172             final String metricKey =
173                     MetricUtility.constructKey(
174                             metricKeyPrefixWithTag,
175                             METRIC_STATS_PREFIX,
176                             String.valueOf(dataItem.id),
177                             "max_tuple_counts");
178             resultMap.put(metricKey, Long.valueOf(dataItem.maxTupleCounts));
179 
180             summaryCount += dataItem.maxTupleCounts;
181         }
182 
183         final String metricKey =
184                 MetricUtility.constructKey(
185                         metricKeyPrefix, METRIC_STATS_PREFIX, "max_tuple_counts");
186         resultMap.put(metricKey, Long.valueOf(summaryCount));
187     }
188 
populateConditionStats( StatsLog.StatsdStatsReport.ConditionStats[] stats, Map<String, Long> resultMap, String metricKeyPrefixWithTag, String metricKeyPrefix)189     private static void populateConditionStats(
190             StatsLog.StatsdStatsReport.ConditionStats[] stats,
191             Map<String, Long> resultMap,
192             String metricKeyPrefixWithTag,
193             String metricKeyPrefix) {
194         int summaryCount = 0;
195 
196         for (final StatsLog.StatsdStatsReport.ConditionStats dataItem : stats) {
197             final String metricKey =
198                     MetricUtility.constructKey(
199                             metricKeyPrefixWithTag,
200                             CONDITION_STATS_PREFIX,
201                             String.valueOf(dataItem.id),
202                             "max_tuple_counts");
203             resultMap.put(metricKey, Long.valueOf(dataItem.maxTupleCounts));
204 
205             summaryCount += dataItem.maxTupleCounts;
206         }
207 
208         final String metricKey =
209                 MetricUtility.constructKey(
210                         metricKeyPrefix, CONDITION_STATS_PREFIX, "max_tuple_counts");
211         resultMap.put(metricKey, Long.valueOf(summaryCount));
212     }
213 
populateMatcherStats( StatsLog.StatsdStatsReport.MatcherStats[] stats, Map<String, Long> resultMap, String metricKeyPrefixWithTag, String metricKeyPrefix)214     private static void populateMatcherStats(
215             StatsLog.StatsdStatsReport.MatcherStats[] stats,
216             Map<String, Long> resultMap,
217             String metricKeyPrefixWithTag,
218             String metricKeyPrefix) {
219         int summaryCount = 0;
220 
221         for (final StatsLog.StatsdStatsReport.MatcherStats dataItem : stats) {
222             final String metricKey =
223                     MetricUtility.constructKey(
224                             metricKeyPrefixWithTag,
225                             MATCHER_STATS_PREFIX,
226                             String.valueOf(dataItem.id),
227                             "matched_times");
228             resultMap.put(metricKey, Long.valueOf(dataItem.matchedTimes));
229 
230             final String sumPerIdMetricKey =
231                     MetricUtility.constructKey(
232                             metricKeyPrefix,
233                             MATCHER_STATS_PREFIX,
234                             String.valueOf(dataItem.id),
235                             "matched_times");
236             resultMap.merge(sumPerIdMetricKey, Long.valueOf(dataItem.matchedTimes), Long::sum);
237 
238             summaryCount += dataItem.matchedTimes;
239         }
240 
241         final String metricKey =
242                 MetricUtility.constructKey(metricKeyPrefix, MATCHER_STATS_PREFIX, "matched_times");
243         resultMap.merge(metricKey, Long.valueOf(summaryCount), Long::sum);
244     }
245 
populateAlertStats( StatsLog.StatsdStatsReport.AlertStats[] stats, Map<String, Long> resultMap, String metricKeyPrefixWithTag, String metricKeyPrefix)246     private static void populateAlertStats(
247             StatsLog.StatsdStatsReport.AlertStats[] stats,
248             Map<String, Long> resultMap,
249             String metricKeyPrefixWithTag,
250             String metricKeyPrefix) {
251         int summaryCount = 0;
252 
253         for (final StatsLog.StatsdStatsReport.AlertStats dataItem : stats) {
254             final String metricKey =
255                     MetricUtility.constructKey(
256                             metricKeyPrefixWithTag,
257                             ALERT_STATS_PREFIX,
258                             String.valueOf(dataItem.id),
259                             "alerted_times");
260             resultMap.put(metricKey, Long.valueOf(dataItem.alertedTimes));
261 
262             summaryCount += dataItem.alertedTimes;
263         }
264 
265         final String metricKey =
266                 MetricUtility.constructKey(metricKeyPrefix, ALERT_STATS_PREFIX, "alerted_times");
267         resultMap.merge(metricKey, Long.valueOf(summaryCount), Long::sum);
268     }
269 
populateAnomalyAlarmStats( StatsLog.StatsdStatsReport.AnomalyAlarmStats anomalyAlarmStats, Map<String, Long> resultMap)270     private static void populateAnomalyAlarmStats(
271             StatsLog.StatsdStatsReport.AnomalyAlarmStats anomalyAlarmStats,
272             Map<String, Long> resultMap) {
273         if (anomalyAlarmStats == null) {
274             return;
275         }
276         final String metricKey =
277                 MetricUtility.constructKey(
278                         STATSDSTATS_PREFIX, ANOMALY_ALARM_STATS_PREFIX, "alarms_registered");
279         resultMap.put(metricKey, Long.valueOf(anomalyAlarmStats.alarmsRegistered));
280     }
281 
populatePulledAtomStats( StatsLog.StatsdStatsReport.PulledAtomStats[] stats, Map<String, Long> resultMap)282     private static void populatePulledAtomStats(
283             StatsLog.StatsdStatsReport.PulledAtomStats[] stats, Map<String, Long> resultMap) {
284         final String metricKeyPrefix =
285                 MetricUtility.constructKey(STATSDSTATS_PREFIX, PULLED_ATOM_STATS_PREFIX);
286 
287         long summaryTotalPull = 0;
288         long summaryTotalPullFromCache = 0;
289         long summaryDataError = 0;
290         long summaryPullTimeout = 0;
291         long summaryExceedMaxDelay = 0;
292         long summaryFailed = 0;
293         long summaryEmptyData = 0;
294         long summaryAtomErrorCount = 0;
295         long summaryBinderCallFailed = 0;
296         long summaryFailedUIDProviderNotFound = 0;
297         long summaryPullerNotFound = 0;
298 
299         for (final StatsLog.StatsdStatsReport.PulledAtomStats dataItem : stats) {
300             final String metricKeyWithTag =
301                     MetricUtility.constructKey(metricKeyPrefix, String.valueOf(dataItem.atomId));
302             resultMap.put(
303                     MetricUtility.constructKey(metricKeyWithTag, "total_pull"),
304                     Long.valueOf(dataItem.totalPull));
305             resultMap.put(
306                     MetricUtility.constructKey(metricKeyWithTag, "total_pull_from_cache"),
307                     Long.valueOf(dataItem.totalPullFromCache));
308             resultMap.put(
309                     MetricUtility.constructKey(metricKeyWithTag, "min_pull_interval_sec"),
310                     Long.valueOf(dataItem.minPullIntervalSec));
311             resultMap.put(
312                     MetricUtility.constructKey(metricKeyWithTag, "average_pull_time_nanos"),
313                     Long.valueOf(dataItem.averagePullTimeNanos));
314             resultMap.put(
315                     MetricUtility.constructKey(metricKeyWithTag, "max_pull_time_nanos"),
316                     Long.valueOf(dataItem.maxPullTimeNanos));
317             resultMap.put(
318                     MetricUtility.constructKey(metricKeyWithTag, "average_pull_delay_nanos"),
319                     Long.valueOf(dataItem.averagePullDelayNanos));
320             resultMap.put(
321                     MetricUtility.constructKey(metricKeyWithTag, "data_error"),
322                     Long.valueOf(dataItem.dataError));
323             resultMap.put(
324                     MetricUtility.constructKey(metricKeyWithTag, "pull_timeout"),
325                     Long.valueOf(dataItem.pullTimeout));
326             resultMap.put(
327                     MetricUtility.constructKey(metricKeyWithTag, "pull_exceed_max_delay"),
328                     Long.valueOf(dataItem.pullExceedMaxDelay));
329             resultMap.put(
330                     MetricUtility.constructKey(metricKeyWithTag, "pull_failed"),
331                     Long.valueOf(dataItem.pullFailed));
332             resultMap.put(
333                     MetricUtility.constructKey(metricKeyWithTag, "empty_data"),
334                     Long.valueOf(dataItem.emptyData));
335             resultMap.put(
336                     MetricUtility.constructKey(metricKeyWithTag, "pull_registered_count"),
337                     Long.valueOf(dataItem.registeredCount));
338             resultMap.put(
339                     MetricUtility.constructKey(metricKeyWithTag, "pull_unregistered_count"),
340                     Long.valueOf(dataItem.unregisteredCount));
341             resultMap.put(
342                     MetricUtility.constructKey(metricKeyWithTag, "atom_error_count"),
343                     Long.valueOf(dataItem.atomErrorCount));
344             resultMap.put(
345                     MetricUtility.constructKey(metricKeyWithTag, "binder_call_failed"),
346                     Long.valueOf(dataItem.binderCallFailed));
347             resultMap.put(
348                     MetricUtility.constructKey(metricKeyWithTag, "failed_uid_provider_not_found"),
349                     Long.valueOf(dataItem.failedUidProviderNotFound));
350             resultMap.put(
351                     MetricUtility.constructKey(metricKeyWithTag, "puller_not_found"),
352                     Long.valueOf(dataItem.pullerNotFound));
353 
354             summaryTotalPull += dataItem.totalPull;
355             summaryTotalPullFromCache += dataItem.totalPullFromCache;
356             summaryDataError += dataItem.dataError;
357             summaryPullTimeout += dataItem.pullTimeout;
358             summaryExceedMaxDelay += dataItem.pullExceedMaxDelay;
359             summaryFailed += dataItem.pullFailed;
360             summaryEmptyData += dataItem.emptyData;
361             summaryAtomErrorCount += dataItem.atomErrorCount;
362             summaryBinderCallFailed += dataItem.binderCallFailed;
363             summaryFailedUIDProviderNotFound += dataItem.failedUidProviderNotFound;
364             summaryPullerNotFound += dataItem.pullerNotFound;
365         }
366 
367         resultMap.put(MetricUtility.constructKey(metricKeyPrefix, "total_pull"), summaryTotalPull);
368         resultMap.put(
369                 MetricUtility.constructKey(metricKeyPrefix, "total_pull_from_cache"),
370                 summaryTotalPullFromCache);
371         resultMap.put(MetricUtility.constructKey(metricKeyPrefix, "data_error"), summaryDataError);
372         resultMap.put(
373                 MetricUtility.constructKey(metricKeyPrefix, "pull_timeout"), summaryPullTimeout);
374         resultMap.put(
375                 MetricUtility.constructKey(metricKeyPrefix, "pull_exceed_max_delay"),
376                 summaryExceedMaxDelay);
377         resultMap.put(MetricUtility.constructKey(metricKeyPrefix, "pull_failed"), summaryFailed);
378         resultMap.put(MetricUtility.constructKey(metricKeyPrefix, "empty_data"), summaryEmptyData);
379         resultMap.put(
380                 MetricUtility.constructKey(metricKeyPrefix, "atom_error_count"),
381                 summaryAtomErrorCount);
382         resultMap.put(
383                 MetricUtility.constructKey(metricKeyPrefix, "binder_call_failed"),
384                 summaryBinderCallFailed);
385         resultMap.put(
386                 MetricUtility.constructKey(metricKeyPrefix, "failed_uid_provider_not_found"),
387                 summaryFailedUIDProviderNotFound);
388         resultMap.put(
389                 MetricUtility.constructKey(metricKeyPrefix, "puller_not_found"),
390                 summaryPullerNotFound);
391     }
392 
populateAtomMetricStats( StatsLog.StatsdStatsReport.AtomMetricStats[] stats, Map<String, Long> resultMap)393     private static void populateAtomMetricStats(
394             StatsLog.StatsdStatsReport.AtomMetricStats[] stats, Map<String, Long> resultMap) {
395         final String metricKeyPrefix =
396                 MetricUtility.constructKey(STATSDSTATS_PREFIX, ATOM_METRIC_STATS_PREFIX);
397 
398         long summaryHardDimensionLimitReached = 0;
399         long summaryLateLogEventSkipped = 0;
400         long summarySkippedForwardBuckets = 0;
401         long summaryBadValueType = 0;
402         long summaryConditionChangeInNextBucket = 0;
403         long summaryInvalidatedBucket = 0;
404         long summaryBucketDropped = 0;
405         long summaryBucketUnknownCondition = 0;
406 
407         for (StatsLog.StatsdStatsReport.AtomMetricStats dataItem : stats) {
408             final String metricKeyPrefixWithTag =
409                     MetricUtility.constructKey(metricKeyPrefix, String.valueOf(dataItem.metricId));
410 
411             resultMap.put(
412                     MetricUtility.constructKey(
413                             metricKeyPrefixWithTag, "hard_dimension_limit_reached"),
414                     dataItem.hardDimensionLimitReached);
415             resultMap.put(
416                     MetricUtility.constructKey(metricKeyPrefixWithTag, "late_log_event_skipped"),
417                     dataItem.lateLogEventSkipped);
418             resultMap.put(
419                     MetricUtility.constructKey(metricKeyPrefixWithTag, "skipped_forward_buckets"),
420                     dataItem.skippedForwardBuckets);
421             resultMap.put(
422                     MetricUtility.constructKey(metricKeyPrefixWithTag, "bad_value_type"),
423                     dataItem.badValueType);
424             resultMap.put(
425                     MetricUtility.constructKey(
426                             metricKeyPrefixWithTag, "condition_change_in_next_bucket"),
427                     dataItem.conditionChangeInNextBucket);
428             resultMap.put(
429                     MetricUtility.constructKey(metricKeyPrefixWithTag, "invalidated_bucket"),
430                     dataItem.invalidatedBucket);
431             resultMap.put(
432                     MetricUtility.constructKey(metricKeyPrefixWithTag, "bucket_dropped"),
433                     dataItem.bucketDropped);
434             resultMap.put(
435                     MetricUtility.constructKey(
436                             metricKeyPrefixWithTag, "min_bucket_boundary_delay_ns"),
437                     dataItem.minBucketBoundaryDelayNs);
438             resultMap.put(
439                     MetricUtility.constructKey(
440                             metricKeyPrefixWithTag, "max_bucket_boundary_delay_ns"),
441                     dataItem.maxBucketBoundaryDelayNs);
442             resultMap.put(
443                     MetricUtility.constructKey(metricKeyPrefixWithTag, "bucket_unknown_condition"),
444                     dataItem.bucketUnknownCondition);
445             resultMap.put(
446                     MetricUtility.constructKey(metricKeyPrefixWithTag, "bucket_count"),
447                     dataItem.bucketCount);
448 
449             summaryHardDimensionLimitReached += dataItem.hardDimensionLimitReached;
450             summaryLateLogEventSkipped += dataItem.lateLogEventSkipped;
451             summarySkippedForwardBuckets += dataItem.skippedForwardBuckets;
452             summaryBadValueType += dataItem.badValueType;
453             summaryConditionChangeInNextBucket += dataItem.conditionChangeInNextBucket;
454             summaryInvalidatedBucket += dataItem.invalidatedBucket;
455             summaryBucketDropped += dataItem.bucketDropped;
456             summaryBucketUnknownCondition += dataItem.bucketUnknownCondition;
457         }
458 
459         resultMap.put(
460                 MetricUtility.constructKey(metricKeyPrefix, "hard_dimension_limit_reached"),
461                 summaryHardDimensionLimitReached);
462         resultMap.put(
463                 MetricUtility.constructKey(metricKeyPrefix, "late_log_event_skipped"),
464                 summaryLateLogEventSkipped);
465         resultMap.put(
466                 MetricUtility.constructKey(metricKeyPrefix, "skipped_forward_buckets"),
467                 summarySkippedForwardBuckets);
468         resultMap.put(
469                 MetricUtility.constructKey(metricKeyPrefix, "bad_value_type"), summaryBadValueType);
470         resultMap.put(
471                 MetricUtility.constructKey(metricKeyPrefix, "condition_change_in_next_bucket"),
472                 summaryConditionChangeInNextBucket);
473         resultMap.put(
474                 MetricUtility.constructKey(metricKeyPrefix, "invalidated_bucket"),
475                 summaryInvalidatedBucket);
476         resultMap.put(
477                 MetricUtility.constructKey(metricKeyPrefix, "bucket_dropped"),
478                 summaryBucketDropped);
479         resultMap.put(
480                 MetricUtility.constructKey(metricKeyPrefix, "bucket_unknown_condition"),
481                 summaryBucketUnknownCondition);
482     }
483 
populateDetectedLogLossStats( StatsLog.StatsdStatsReport.LogLossStats[] detectedLogLoss, Map<String, Long> resultMap)484     private static void populateDetectedLogLossStats(
485             StatsLog.StatsdStatsReport.LogLossStats[] detectedLogLoss,
486             Map<String, Long> resultMap) {
487         final String metricKeyPrefix =
488                 MetricUtility.constructKey(STATSDSTATS_PREFIX, DETECTED_LOG_LOSS_STATS_PREFIX);
489 
490         for (final StatsLog.StatsdStatsReport.LogLossStats dataItem : detectedLogLoss) {
491             final String metricKeyPrefixWithTag =
492                     MetricUtility.constructKey(
493                             metricKeyPrefix, String.valueOf(dataItem.detectedTimeSec));
494 
495             resultMap.put(
496                     MetricUtility.constructKey(metricKeyPrefixWithTag, "count"),
497                     Long.valueOf(dataItem.count));
498             resultMap.put(
499                     MetricUtility.constructKey(metricKeyPrefixWithTag, "last_error"),
500                     Long.valueOf(dataItem.lastError));
501             resultMap.put(
502                     MetricUtility.constructKey(metricKeyPrefixWithTag, "last_tag"),
503                     Long.valueOf(dataItem.lastTag));
504             resultMap.put(
505                     MetricUtility.constructKey(metricKeyPrefixWithTag, "uid"),
506                     Long.valueOf(dataItem.uid));
507             resultMap.put(
508                     MetricUtility.constructKey(metricKeyPrefixWithTag, "pid"),
509                     Long.valueOf(dataItem.pid));
510         }
511     }
512 
populateEventQueueOverflowStats( StatsLog.StatsdStatsReport.EventQueueOverflow queueOverflow, Map<String, Long> resultMap)513     private static void populateEventQueueOverflowStats(
514             StatsLog.StatsdStatsReport.EventQueueOverflow queueOverflow,
515             Map<String, Long> resultMap) {
516         if (queueOverflow == null) {
517             return;
518         }
519         final String metricKeyPrefix =
520                 MetricUtility.constructKey(STATSDSTATS_PREFIX, EVENT_QUEUE_OVERFLOW_STATS_PREFIX);
521 
522         resultMap.put(
523                 MetricUtility.constructKey(metricKeyPrefix, "count"),
524                 Long.valueOf(queueOverflow.count));
525         resultMap.put(
526                 MetricUtility.constructKey(metricKeyPrefix, "max_queue_history_nanos"),
527                 Long.valueOf(queueOverflow.maxQueueHistoryNs));
528         resultMap.put(
529                 MetricUtility.constructKey(metricKeyPrefix, "min_queue_history_nanos"),
530                 Long.valueOf(queueOverflow.minQueueHistoryNs));
531     }
532 
533 }
534