StatsdStats.cpp revision 203bbbf942e8675338b88ab67d49481d2bfcf904
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#define DEBUG false // STOPSHIP if true 17#include "Log.h" 18 19#include "StatsdStats.h" 20 21#include <android/util/ProtoOutputStream.h> 22#include "../stats_log_util.h" 23#include "statslog.h" 24#include "storage/StorageManager.h" 25 26namespace android { 27namespace os { 28namespace statsd { 29 30using android::util::FIELD_COUNT_REPEATED; 31using android::util::FIELD_TYPE_BOOL; 32using android::util::FIELD_TYPE_FLOAT; 33using android::util::FIELD_TYPE_INT32; 34using android::util::FIELD_TYPE_INT64; 35using android::util::FIELD_TYPE_MESSAGE; 36using android::util::FIELD_TYPE_STRING; 37using android::util::ProtoOutputStream; 38using std::lock_guard; 39using std::map; 40using std::shared_ptr; 41using std::string; 42using std::vector; 43 44const int FIELD_ID_BEGIN_TIME = 1; 45const int FIELD_ID_END_TIME = 2; 46const int FIELD_ID_CONFIG_STATS = 3; 47const int FIELD_ID_ATOM_STATS = 7; 48const int FIELD_ID_UIDMAP_STATS = 8; 49const int FIELD_ID_ANOMALY_ALARM_STATS = 9; 50// const int FIELD_ID_PULLED_ATOM_STATS = 10; // The proto is written in stats_log_util.cpp 51const int FIELD_ID_LOGGER_ERROR_STATS = 11; 52const int FIELD_ID_PERIODIC_ALARM_STATS = 12; 53const int FIELD_ID_SKIPPED_LOG_EVENT_STATS = 13; 54 55const int FIELD_ID_ATOM_STATS_TAG = 1; 56const int FIELD_ID_ATOM_STATS_COUNT = 2; 57 58const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1; 59const int FIELD_ID_PERIODIC_ALARMS_REGISTERED = 1; 60 61const int FIELD_ID_LOGGER_STATS_TIME = 1; 62const int FIELD_ID_LOGGER_STATS_ERROR_CODE = 2; 63 64const int FIELD_ID_SKIPPED_LOG_EVENT_STATS_TAG = 1; 65const int FIELD_ID_SKIPPED_LOG_EVENT_STATS_TIMESTAMP = 2; 66 67const int FIELD_ID_CONFIG_STATS_UID = 1; 68const int FIELD_ID_CONFIG_STATS_ID = 2; 69const int FIELD_ID_CONFIG_STATS_CREATION = 3; 70const int FIELD_ID_CONFIG_STATS_RESET = 19; 71const int FIELD_ID_CONFIG_STATS_DELETION = 4; 72const int FIELD_ID_CONFIG_STATS_METRIC_COUNT = 5; 73const int FIELD_ID_CONFIG_STATS_CONDITION_COUNT = 6; 74const int FIELD_ID_CONFIG_STATS_MATCHER_COUNT = 7; 75const int FIELD_ID_CONFIG_STATS_ALERT_COUNT = 8; 76const int FIELD_ID_CONFIG_STATS_VALID = 9; 77const int FIELD_ID_CONFIG_STATS_BROADCAST = 10; 78const int FIELD_ID_CONFIG_STATS_DATA_DROP = 11; 79const int FIELD_ID_CONFIG_STATS_DUMP_REPORT = 12; 80const int FIELD_ID_CONFIG_STATS_MATCHER_STATS = 13; 81const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14; 82const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15; 83const int FIELD_ID_CONFIG_STATS_ALERT_STATS = 16; 84const int FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS = 17; 85const int FIELD_ID_CONFIG_STATS_ANNOTATION = 18; 86const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT64 = 1; 87const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT32 = 2; 88 89const int FIELD_ID_MATCHER_STATS_ID = 1; 90const int FIELD_ID_MATCHER_STATS_COUNT = 2; 91const int FIELD_ID_CONDITION_STATS_ID = 1; 92const int FIELD_ID_CONDITION_STATS_COUNT = 2; 93const int FIELD_ID_METRIC_STATS_ID = 1; 94const int FIELD_ID_METRIC_STATS_COUNT = 2; 95const int FIELD_ID_ALERT_STATS_ID = 1; 96const int FIELD_ID_ALERT_STATS_COUNT = 2; 97 98const int FIELD_ID_UID_MAP_CHANGES = 1; 99const int FIELD_ID_UID_MAP_BYTES_USED = 2; 100const int FIELD_ID_UID_MAP_DROPPED_CHANGES = 3; 101const int FIELD_ID_UID_MAP_DELETED_APPS = 4; 102 103const std::map<int, std::pair<size_t, size_t>> StatsdStats::kAtomDimensionKeySizeLimitMap = { 104 {android::util::CPU_TIME_PER_UID_FREQ, {6000, 10000}}, 105}; 106 107// TODO: add stats for pulled atoms. 108StatsdStats::StatsdStats() { 109 mPushedAtomStats.resize(android::util::kMaxPushedAtomId + 1); 110 mStartTimeSec = getWallClockSec(); 111} 112 113StatsdStats& StatsdStats::getInstance() { 114 static StatsdStats statsInstance; 115 return statsInstance; 116} 117 118void StatsdStats::addToIceBoxLocked(shared_ptr<ConfigStats>& stats) { 119 // The size of mIceBox grows strictly by one at a time. It won't be > kMaxIceBoxSize. 120 if (mIceBox.size() == kMaxIceBoxSize) { 121 mIceBox.pop_front(); 122 } 123 mIceBox.push_back(stats); 124} 125 126void StatsdStats::noteConfigReceived( 127 const ConfigKey& key, int metricsCount, int conditionsCount, int matchersCount, 128 int alertsCount, const std::list<std::pair<const int64_t, const int32_t>>& annotations, 129 bool isValid) { 130 lock_guard<std::mutex> lock(mLock); 131 int32_t nowTimeSec = getWallClockSec(); 132 133 // If there is an existing config for the same key, icebox the old config. 134 noteConfigRemovedInternalLocked(key); 135 136 shared_ptr<ConfigStats> configStats = std::make_shared<ConfigStats>(); 137 configStats->uid = key.GetUid(); 138 configStats->id = key.GetId(); 139 configStats->creation_time_sec = nowTimeSec; 140 configStats->metric_count = metricsCount; 141 configStats->condition_count = conditionsCount; 142 configStats->matcher_count = matchersCount; 143 configStats->alert_count = alertsCount; 144 configStats->is_valid = isValid; 145 for (auto& v : annotations) { 146 configStats->annotations.emplace_back(v); 147 } 148 149 if (isValid) { 150 mConfigStats[key] = configStats; 151 } else { 152 configStats->deletion_time_sec = nowTimeSec; 153 addToIceBoxLocked(configStats); 154 } 155} 156 157void StatsdStats::noteConfigRemovedInternalLocked(const ConfigKey& key) { 158 auto it = mConfigStats.find(key); 159 if (it != mConfigStats.end()) { 160 int32_t nowTimeSec = getWallClockSec(); 161 it->second->deletion_time_sec = nowTimeSec; 162 addToIceBoxLocked(it->second); 163 mConfigStats.erase(it); 164 } 165} 166 167void StatsdStats::noteConfigRemoved(const ConfigKey& key) { 168 lock_guard<std::mutex> lock(mLock); 169 noteConfigRemovedInternalLocked(key); 170} 171 172void StatsdStats::noteConfigResetInternalLocked(const ConfigKey& key) { 173 auto it = mConfigStats.find(key); 174 if (it != mConfigStats.end()) { 175 it->second->reset_time_sec = getWallClockSec(); 176 } 177} 178 179void StatsdStats::noteConfigReset(const ConfigKey& key) { 180 lock_guard<std::mutex> lock(mLock); 181 noteConfigResetInternalLocked(key); 182} 183 184void StatsdStats::noteBroadcastSent(const ConfigKey& key) { 185 noteBroadcastSent(key, getWallClockSec()); 186} 187 188void StatsdStats::noteBroadcastSent(const ConfigKey& key, int32_t timeSec) { 189 lock_guard<std::mutex> lock(mLock); 190 auto it = mConfigStats.find(key); 191 if (it == mConfigStats.end()) { 192 ALOGE("Config key %s not found!", key.ToString().c_str()); 193 return; 194 } 195 if (it->second->broadcast_sent_time_sec.size() == kMaxTimestampCount) { 196 it->second->broadcast_sent_time_sec.pop_front(); 197 } 198 it->second->broadcast_sent_time_sec.push_back(timeSec); 199} 200 201void StatsdStats::noteDataDropped(const ConfigKey& key) { 202 noteDataDropped(key, getWallClockSec()); 203} 204 205void StatsdStats::noteDataDropped(const ConfigKey& key, int32_t timeSec) { 206 lock_guard<std::mutex> lock(mLock); 207 auto it = mConfigStats.find(key); 208 if (it == mConfigStats.end()) { 209 ALOGE("Config key %s not found!", key.ToString().c_str()); 210 return; 211 } 212 if (it->second->data_drop_time_sec.size() == kMaxTimestampCount) { 213 it->second->data_drop_time_sec.pop_front(); 214 } 215 it->second->data_drop_time_sec.push_back(timeSec); 216} 217 218void StatsdStats::noteMetricsReportSent(const ConfigKey& key) { 219 noteMetricsReportSent(key, getWallClockSec()); 220} 221 222void StatsdStats::noteMetricsReportSent(const ConfigKey& key, int32_t timeSec) { 223 lock_guard<std::mutex> lock(mLock); 224 auto it = mConfigStats.find(key); 225 if (it == mConfigStats.end()) { 226 ALOGE("Config key %s not found!", key.ToString().c_str()); 227 return; 228 } 229 if (it->second->dump_report_time_sec.size() == kMaxTimestampCount) { 230 it->second->dump_report_time_sec.pop_front(); 231 } 232 it->second->dump_report_time_sec.push_back(timeSec); 233} 234 235void StatsdStats::noteUidMapDropped(int deltas) { 236 lock_guard<std::mutex> lock(mLock); 237 mUidMapStats.dropped_changes += mUidMapStats.dropped_changes + deltas; 238} 239 240void StatsdStats::noteUidMapAppDeletionDropped() { 241 lock_guard<std::mutex> lock(mLock); 242 mUidMapStats.deleted_apps++; 243} 244 245void StatsdStats::setUidMapChanges(int changes) { 246 lock_guard<std::mutex> lock(mLock); 247 mUidMapStats.changes = changes; 248} 249 250void StatsdStats::setCurrentUidMapMemory(int bytes) { 251 lock_guard<std::mutex> lock(mLock); 252 mUidMapStats.bytes_used = bytes; 253} 254 255void StatsdStats::noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size) { 256 lock_guard<std::mutex> lock(mLock); 257 // if name doesn't exist before, it will create the key with count 0. 258 auto statsIt = mConfigStats.find(key); 259 if (statsIt == mConfigStats.end()) { 260 return; 261 } 262 263 auto& conditionSizeMap = statsIt->second->condition_stats; 264 if (size > conditionSizeMap[id]) { 265 conditionSizeMap[id] = size; 266 } 267} 268 269void StatsdStats::noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size) { 270 lock_guard<std::mutex> lock(mLock); 271 // if name doesn't exist before, it will create the key with count 0. 272 auto statsIt = mConfigStats.find(key); 273 if (statsIt == mConfigStats.end()) { 274 return; 275 } 276 auto& metricsDimensionMap = statsIt->second->metric_stats; 277 if (size > metricsDimensionMap[id]) { 278 metricsDimensionMap[id] = size; 279 } 280} 281 282void StatsdStats::noteMetricDimensionInConditionSize( 283 const ConfigKey& key, const int64_t& id, int size) { 284 lock_guard<std::mutex> lock(mLock); 285 // if name doesn't exist before, it will create the key with count 0. 286 auto statsIt = mConfigStats.find(key); 287 if (statsIt == mConfigStats.end()) { 288 return; 289 } 290 auto& metricsDimensionMap = statsIt->second->metric_dimension_in_condition_stats; 291 if (size > metricsDimensionMap[id]) { 292 metricsDimensionMap[id] = size; 293 } 294} 295 296void StatsdStats::noteMatcherMatched(const ConfigKey& key, const int64_t& id) { 297 lock_guard<std::mutex> lock(mLock); 298 299 auto statsIt = mConfigStats.find(key); 300 if (statsIt == mConfigStats.end()) { 301 return; 302 } 303 statsIt->second->matcher_stats[id]++; 304} 305 306void StatsdStats::noteAnomalyDeclared(const ConfigKey& key, const int64_t& id) { 307 lock_guard<std::mutex> lock(mLock); 308 auto statsIt = mConfigStats.find(key); 309 if (statsIt == mConfigStats.end()) { 310 return; 311 } 312 statsIt->second->alert_stats[id]++; 313} 314 315void StatsdStats::noteRegisteredAnomalyAlarmChanged() { 316 lock_guard<std::mutex> lock(mLock); 317 mAnomalyAlarmRegisteredStats++; 318} 319 320void StatsdStats::noteRegisteredPeriodicAlarmChanged() { 321 lock_guard<std::mutex> lock(mLock); 322 mPeriodicAlarmRegisteredStats++; 323} 324 325void StatsdStats::updateMinPullIntervalSec(int pullAtomId, long intervalSec) { 326 lock_guard<std::mutex> lock(mLock); 327 mPulledAtomStats[pullAtomId].minPullIntervalSec = intervalSec; 328} 329 330void StatsdStats::notePull(int pullAtomId) { 331 lock_guard<std::mutex> lock(mLock); 332 mPulledAtomStats[pullAtomId].totalPull++; 333} 334 335void StatsdStats::notePullFromCache(int pullAtomId) { 336 lock_guard<std::mutex> lock(mLock); 337 mPulledAtomStats[pullAtomId].totalPullFromCache++; 338} 339 340void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) { 341 lock_guard<std::mutex> lock(mLock); 342 343 if (atomId > android::util::kMaxPushedAtomId) { 344 ALOGW("not interested in atom %d", atomId); 345 return; 346 } 347 348 mPushedAtomStats[atomId]++; 349} 350 351void StatsdStats::noteLogEventSkipped(int tag, int64_t timestamp) { 352 lock_guard<std::mutex> lock(mLock); 353 // grows strictly one at a time. so it won't > kMaxSkippedLogEvents 354 if (mSkippedLogEvents.size() == kMaxSkippedLogEvents) { 355 mSkippedLogEvents.pop_front(); 356 } 357 mSkippedLogEvents.push_back(std::make_pair(tag, timestamp)); 358} 359 360void StatsdStats::noteLoggerError(int error) { 361 lock_guard<std::mutex> lock(mLock); 362 // grows strictly one at a time. so it won't > kMaxLoggerErrors 363 if (mLoggerErrors.size() == kMaxLoggerErrors) { 364 mLoggerErrors.pop_front(); 365 } 366 mLoggerErrors.push_back(std::make_pair(getWallClockSec(), error)); 367} 368 369void StatsdStats::reset() { 370 lock_guard<std::mutex> lock(mLock); 371 resetInternalLocked(); 372} 373 374void StatsdStats::resetInternalLocked() { 375 // Reset the historical data, but keep the active ConfigStats 376 mStartTimeSec = getWallClockSec(); 377 mIceBox.clear(); 378 std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), 0); 379 mAnomalyAlarmRegisteredStats = 0; 380 mPeriodicAlarmRegisteredStats = 0; 381 mLoggerErrors.clear(); 382 mSkippedLogEvents.clear(); 383 for (auto& config : mConfigStats) { 384 config.second->broadcast_sent_time_sec.clear(); 385 config.second->data_drop_time_sec.clear(); 386 config.second->dump_report_time_sec.clear(); 387 config.second->annotations.clear(); 388 config.second->matcher_stats.clear(); 389 config.second->condition_stats.clear(); 390 config.second->metric_stats.clear(); 391 config.second->metric_dimension_in_condition_stats.clear(); 392 config.second->alert_stats.clear(); 393 } 394} 395 396void StatsdStats::dumpStats(FILE* out) const { 397 lock_guard<std::mutex> lock(mLock); 398 time_t t = mStartTimeSec; 399 struct tm* tm = localtime(&t); 400 char timeBuffer[80]; 401 strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm); 402 fprintf(out, "Stats collection start second: %s\n", timeBuffer); 403 fprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size()); 404 for (const auto& configStats : mIceBox) { 405 fprintf(out, 406 "Config {%d_%lld}: creation=%d, deletion=%d, reset=%d, #metric=%d, #condition=%d, " 407 "#matcher=%d, #alert=%d, valid=%d\n", 408 configStats->uid, (long long)configStats->id, configStats->creation_time_sec, 409 configStats->deletion_time_sec, configStats->reset_time_sec, 410 configStats->metric_count, 411 configStats->condition_count, configStats->matcher_count, configStats->alert_count, 412 configStats->is_valid); 413 414 for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) { 415 fprintf(out, "\tbroadcast time: %d\n", broadcastTime); 416 } 417 418 for (const auto& dataDropTime : configStats->data_drop_time_sec) { 419 fprintf(out, "\tdata drop time: %d\n", dataDropTime); 420 } 421 } 422 fprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size()); 423 for (auto& pair : mConfigStats) { 424 auto& configStats = pair.second; 425 fprintf(out, 426 "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " 427 "#matcher=%d, #alert=%d, valid=%d\n", 428 configStats->uid, (long long)configStats->id, configStats->creation_time_sec, 429 configStats->deletion_time_sec, configStats->metric_count, 430 configStats->condition_count, configStats->matcher_count, configStats->alert_count, 431 configStats->is_valid); 432 for (const auto& annotation : configStats->annotations) { 433 fprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first, 434 annotation.second); 435 } 436 437 for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) { 438 fprintf(out, "\tbroadcast time: %d\n", broadcastTime); 439 } 440 441 for (const auto& dataDropTime : configStats->data_drop_time_sec) { 442 fprintf(out, "\tdata drop time: %d\n", dataDropTime); 443 } 444 445 for (const auto& dumpTime : configStats->dump_report_time_sec) { 446 fprintf(out, "\tdump report time: %d\n", dumpTime); 447 } 448 449 for (const auto& stats : pair.second->matcher_stats) { 450 fprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second); 451 } 452 453 for (const auto& stats : pair.second->condition_stats) { 454 fprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first, 455 stats.second); 456 } 457 458 for (const auto& stats : pair.second->condition_stats) { 459 fprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first, 460 stats.second); 461 } 462 463 for (const auto& stats : pair.second->alert_stats) { 464 fprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second); 465 } 466 } 467 fprintf(out, "********Disk Usage stats***********\n"); 468 StorageManager::printStats(out); 469 fprintf(out, "********Pushed Atom stats***********\n"); 470 const size_t atomCounts = mPushedAtomStats.size(); 471 for (size_t i = 2; i < atomCounts; i++) { 472 if (mPushedAtomStats[i] > 0) { 473 fprintf(out, "Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]); 474 } 475 } 476 477 fprintf(out, "********Pulled Atom stats***********\n"); 478 for (const auto& pair : mPulledAtomStats) { 479 fprintf(out, "Atom %d->%ld, %ld, %ld\n", (int)pair.first, (long)pair.second.totalPull, 480 (long)pair.second.totalPullFromCache, (long)pair.second.minPullIntervalSec); 481 } 482 483 if (mAnomalyAlarmRegisteredStats > 0) { 484 fprintf(out, "********AnomalyAlarmStats stats***********\n"); 485 fprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats); 486 } 487 488 if (mPeriodicAlarmRegisteredStats > 0) { 489 fprintf(out, "********SubscriberAlarmStats stats***********\n"); 490 fprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats); 491 } 492 493 fprintf(out, "UID map stats: bytes=%d, changes=%d, deleted=%d, changes lost=%d\n", 494 mUidMapStats.bytes_used, mUidMapStats.changes, mUidMapStats.deleted_apps, 495 mUidMapStats.dropped_changes); 496 497 for (const auto& error : mLoggerErrors) { 498 time_t error_time = error.first; 499 struct tm* error_tm = localtime(&error_time); 500 char buffer[80]; 501 strftime(buffer, sizeof(buffer), "%Y-%m-%d %I:%M%p\n", error_tm); 502 fprintf(out, "Logger error %d at %s\n", error.second, buffer); 503 } 504 for (const auto& skipped : mSkippedLogEvents) { 505 fprintf(out, "Log event (%d) skipped at %lld\n", skipped.first, (long long)skipped.second); 506 } 507} 508 509void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) { 510 uint64_t token = 511 proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS); 512 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_UID, configStats.uid); 513 proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ID, (long long)configStats.id); 514 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CREATION, configStats.creation_time_sec); 515 if (configStats.reset_time_sec != 0) { 516 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESET, configStats.reset_time_sec); 517 } 518 if (configStats.deletion_time_sec != 0) { 519 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DELETION, 520 configStats.deletion_time_sec); 521 } 522 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_METRIC_COUNT, configStats.metric_count); 523 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CONDITION_COUNT, 524 configStats.condition_count); 525 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_MATCHER_COUNT, configStats.matcher_count); 526 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ALERT_COUNT, configStats.alert_count); 527 proto->write(FIELD_TYPE_BOOL | FIELD_ID_CONFIG_STATS_VALID, configStats.is_valid); 528 529 for (const auto& broadcast : configStats.broadcast_sent_time_sec) { 530 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_BROADCAST | FIELD_COUNT_REPEATED, 531 broadcast); 532 } 533 534 for (const auto& drop : configStats.data_drop_time_sec) { 535 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DATA_DROP | FIELD_COUNT_REPEATED, 536 drop); 537 } 538 539 for (const auto& dump : configStats.dump_report_time_sec) { 540 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT | FIELD_COUNT_REPEATED, 541 dump); 542 } 543 544 for (const auto& annotation : configStats.annotations) { 545 uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | 546 FIELD_ID_CONFIG_STATS_ANNOTATION); 547 proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT64, 548 (long long)annotation.first); 549 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT32, annotation.second); 550 proto->end(token); 551 } 552 553 for (const auto& pair : configStats.matcher_stats) { 554 uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | 555 FIELD_ID_CONFIG_STATS_MATCHER_STATS); 556 proto->write(FIELD_TYPE_INT64 | FIELD_ID_MATCHER_STATS_ID, (long long)pair.first); 557 proto->write(FIELD_TYPE_INT32 | FIELD_ID_MATCHER_STATS_COUNT, pair.second); 558 proto->end(tmpToken); 559 } 560 561 for (const auto& pair : configStats.condition_stats) { 562 uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | 563 FIELD_ID_CONFIG_STATS_CONDITION_STATS); 564 proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_STATS_ID, (long long)pair.first); 565 proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONDITION_STATS_COUNT, pair.second); 566 proto->end(tmpToken); 567 } 568 569 for (const auto& pair : configStats.metric_stats) { 570 uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | 571 FIELD_ID_CONFIG_STATS_METRIC_STATS); 572 proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first); 573 proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second); 574 proto->end(tmpToken); 575 } 576 for (const auto& pair : configStats.metric_dimension_in_condition_stats) { 577 uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | 578 FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS); 579 proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first); 580 proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second); 581 proto->end(tmpToken); 582 } 583 584 for (const auto& pair : configStats.alert_stats) { 585 uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | 586 FIELD_ID_CONFIG_STATS_ALERT_STATS); 587 proto->write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_STATS_ID, (long long)pair.first); 588 proto->write(FIELD_TYPE_INT32 | FIELD_ID_ALERT_STATS_COUNT, pair.second); 589 proto->end(tmpToken); 590 } 591 592 proto->end(token); 593} 594 595void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { 596 lock_guard<std::mutex> lock(mLock); 597 598 ProtoOutputStream proto; 599 proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec); 600 proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)getWallClockSec()); 601 602 for (const auto& configStats : mIceBox) { 603 addConfigStatsToProto(*configStats, &proto); 604 } 605 606 for (auto& pair : mConfigStats) { 607 addConfigStatsToProto(*(pair.second), &proto); 608 } 609 610 const size_t atomCounts = mPushedAtomStats.size(); 611 for (size_t i = 2; i < atomCounts; i++) { 612 if (mPushedAtomStats[i] > 0) { 613 uint64_t token = 614 proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED); 615 proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i); 616 proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i]); 617 proto.end(token); 618 } 619 } 620 621 for (const auto& pair : mPulledAtomStats) { 622 android::os::statsd::writePullerStatsToStream(pair, &proto); 623 } 624 625 if (mAnomalyAlarmRegisteredStats > 0) { 626 uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS); 627 proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED, 628 mAnomalyAlarmRegisteredStats); 629 proto.end(token); 630 } 631 632 if (mPeriodicAlarmRegisteredStats > 0) { 633 uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PERIODIC_ALARM_STATS); 634 proto.write(FIELD_TYPE_INT32 | FIELD_ID_PERIODIC_ALARMS_REGISTERED, 635 mPeriodicAlarmRegisteredStats); 636 proto.end(token); 637 } 638 639 uint64_t uidMapToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS); 640 proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_CHANGES, mUidMapStats.changes); 641 proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_BYTES_USED, mUidMapStats.bytes_used); 642 proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DROPPED_CHANGES, mUidMapStats.dropped_changes); 643 proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DELETED_APPS, mUidMapStats.deleted_apps); 644 proto.end(uidMapToken); 645 646 for (const auto& error : mLoggerErrors) { 647 uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS | 648 FIELD_COUNT_REPEATED); 649 proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_TIME, error.first); 650 proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_ERROR_CODE, error.second); 651 proto.end(token); 652 } 653 654 for (const auto& skipped : mSkippedLogEvents) { 655 uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SKIPPED_LOG_EVENT_STATS | 656 FIELD_COUNT_REPEATED); 657 proto.write(FIELD_TYPE_INT32 | FIELD_ID_SKIPPED_LOG_EVENT_STATS_TAG, skipped.first); 658 proto.write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_LOG_EVENT_STATS_TIMESTAMP, 659 (long long)skipped.second); 660 proto.end(token); 661 } 662 663 output->clear(); 664 size_t bufferSize = proto.size(); 665 output->resize(bufferSize); 666 667 size_t pos = 0; 668 auto it = proto.data(); 669 while (it.readBuffer() != NULL) { 670 size_t toRead = it.currentToRead(); 671 std::memcpy(&((*output)[pos]), it.readBuffer(), toRead); 672 pos += toRead; 673 it.rp()->move(toRead); 674 } 675 676 if (reset) { 677 resetInternalLocked(); 678 } 679 680 VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)bufferSize); 681} 682 683} // namespace statsd 684} // namespace os 685} // namespace android 686