| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/local_aggregation/event_aggregator.h" |
| |
| #include <algorithm> |
| #include <map> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "src/lib/util/datetime_util.h" |
| #include "src/lib/util/proto_util.h" |
| #include "src/lib/util/status_builder.h" |
| #include "src/public/lib/registry_identifiers.h" |
| #include "src/registry/packed_event_codes.h" |
| |
| namespace cobalt::local_aggregation { |
| |
| using logger::EventRecord; |
| using logger::ProjectContext; |
| |
| EventAggregator::EventAggregator(AggregateStore& aggregate_store) |
| : aggregate_store_(aggregate_store) {} |
| |
| Status EventAggregator::UpdateAggregationConfigs(const ProjectContext& project_context) { |
| Status status; |
| for (const auto& metric : project_context.metrics()) { |
| switch (metric.metric_type()) { |
| case MetricDefinition::EVENT_OCCURRED: { |
| for (const auto& report : metric.reports()) { |
| switch (report.report_type()) { |
| case ReportDefinition::UNIQUE_N_DAY_ACTIVES: { |
| status = |
| aggregate_store_.get().MaybeInsertReportConfig(project_context, metric, report); |
| if (!status.ok()) { |
| return status; |
| } |
| } break; |
| default: |
| continue; |
| } |
| } |
| } break; |
| case MetricDefinition::EVENT_COUNT: |
| case MetricDefinition::ELAPSED_TIME: |
| case MetricDefinition::FRAME_RATE: |
| case MetricDefinition::MEMORY_USAGE: { |
| for (const auto& report : metric.reports()) { |
| switch (report.report_type()) { |
| case ReportDefinition::PER_DEVICE_NUMERIC_STATS: |
| case ReportDefinition::PER_DEVICE_HISTOGRAM: { |
| status = |
| aggregate_store_.get().MaybeInsertReportConfig(project_context, metric, report); |
| if (!status.ok()) { |
| return status; |
| } |
| } break; |
| default: |
| continue; |
| } |
| } |
| } break; |
| default: |
| continue; |
| } |
| } |
| return Status::OkStatus(); |
| } |
| |
| // Helper functions for the Log*Event() methods. |
| namespace { |
| |
| // Checks that an Event has type |expected_event_type|. |
| bool ValidateEventType(Event::TypeCase expected_event_type, const Event& event) { |
| Event::TypeCase event_type = event.type_case(); |
| if (event_type != expected_event_type) { |
| LOG(ERROR) << "Expected Event type is " << expected_event_type << "; found " << event_type |
| << "."; |
| return false; |
| } |
| return true; |
| } |
| |
| } // namespace |
| |
| Status EventAggregator::AddUniqueActivesEvent(uint32_t report_id, const EventRecord& event_record) { |
| Event* event = event_record.event(); |
| if (!ValidateEventType(Event::kEventOccurredEvent, *event)) { |
| return util::StatusBuilder(StatusCode::INVALID_ARGUMENT, "Failed to validate arguments") |
| .WithContext("ReportId", report_id) |
| .WithContexts(event_record) |
| .Build(); |
| } |
| return aggregate_store_.get().SetActive(event_record.MetricIdentifier().ForReport(report_id), |
| event->event_occurred_event().event_code(), |
| event->day_index()); |
| } |
| |
| Status EventAggregator::AddEventCountEvent(uint32_t report_id, const EventRecord& event_record) { |
| Event* event = event_record.event(); |
| if (!ValidateEventType(Event::kEventCountEvent, *event)) { |
| return util::StatusBuilder(StatusCode::INVALID_ARGUMENT, "Failed to validate arguments") |
| .WithContext("ReportId", report_id) |
| .WithContexts(event_record) |
| .Build(); |
| } |
| |
| const EventCountEvent& event_count_event = event->event_count_event(); |
| |
| return aggregate_store_.get().UpdateNumericAggregate( |
| event_record.MetricIdentifier().ForReport(report_id), event_count_event.component(), |
| config::PackEventCodes(event_count_event.event_code()), event->day_index(), |
| event_count_event.count()); |
| } |
| |
| Status EventAggregator::AddElapsedTimeEvent(uint32_t report_id, const EventRecord& event_record) { |
| Event* event = event_record.event(); |
| if (!ValidateEventType(Event::kElapsedTimeEvent, *event)) { |
| return util::StatusBuilder(StatusCode::INVALID_ARGUMENT, "Failed to validate arguments") |
| .WithContext("ReportId", report_id) |
| .WithContexts(event_record) |
| .Build(); |
| } |
| |
| const ElapsedTimeEvent& elapsed_time_event = event->elapsed_time_event(); |
| |
| return aggregate_store_.get().UpdateNumericAggregate( |
| event_record.MetricIdentifier().ForReport(report_id), elapsed_time_event.component(), |
| config::PackEventCodes(elapsed_time_event.event_code()), event->day_index(), |
| elapsed_time_event.elapsed_micros()); |
| } |
| |
| Status EventAggregator::AddFrameRateEvent(uint32_t report_id, const EventRecord& event_record) { |
| Event* event = event_record.event(); |
| if (!ValidateEventType(Event::kFrameRateEvent, *event)) { |
| return util::StatusBuilder(StatusCode::INVALID_ARGUMENT, "Failed to validate arguments") |
| .WithContext("ReportId", report_id) |
| .WithContexts(event_record) |
| .Build(); |
| } |
| const FrameRateEvent& frame_rate_event = event->frame_rate_event(); |
| |
| return aggregate_store_.get().UpdateNumericAggregate( |
| event_record.MetricIdentifier().ForReport(report_id), frame_rate_event.component(), |
| config::PackEventCodes(frame_rate_event.event_code()), event->day_index(), |
| frame_rate_event.frames_per_1000_seconds()); |
| } |
| |
| Status EventAggregator::AddMemoryUsageEvent(uint32_t report_id, const EventRecord& event_record) { |
| Event* event = event_record.event(); |
| if (!ValidateEventType(Event::kMemoryUsageEvent, *event)) { |
| return util::StatusBuilder(StatusCode::INVALID_ARGUMENT, "Failed to validate arguments") |
| .WithContext("ReportId", report_id) |
| .WithContexts(event_record) |
| .Build(); |
| } |
| |
| const MemoryUsageEvent& memory_usage_event = event->memory_usage_event(); |
| |
| return aggregate_store_.get().UpdateNumericAggregate( |
| event_record.MetricIdentifier().ForReport(report_id), memory_usage_event.component(), |
| config::PackEventCodes(memory_usage_event.event_code()), event->day_index(), |
| memory_usage_event.bytes()); |
| } |
| } // namespace cobalt::local_aggregation |