blob: 557a7ad819474799c26b5f4fd35253a2a27cd992 [file] [log] [blame]
#include "src/cobalt/bin/app/logger_impl.h"
#include "src/cobalt/bin/app/utils.h"
namespace cobalt {
LoggerImpl::LoggerImpl(std::unique_ptr<logger::ProjectContext> project_context,
logger::Encoder* encoder,
logger::EventAggregator* event_aggregator,
logger::ObservationWriter* observation_writer,
TimerManager* timer_manager,
logger::LoggerInterface* internal_logger)
: logger_(std::move(project_context), encoder, event_aggregator,
observation_writer, internal_logger),
timer_manager_(timer_manager) {}
void LoggerImpl::LogEvent(
uint32_t metric_id, uint32_t event_code,
fuchsia::cobalt::LoggerBase::LogEventCallback callback) {
callback(ToCobaltStatus(logger_.LogEvent(metric_id, event_code)));
}
void LoggerImpl::LogEventCount(
uint32_t metric_id, uint32_t event_code, std::string component,
int64_t period_duration_micros, int64_t count,
fuchsia::cobalt::LoggerBase::LogEventCountCallback callback) {
callback(ToCobaltStatus(logger_.LogEventCount(
metric_id, event_code, component, period_duration_micros, count)));
}
void LoggerImpl::LogElapsedTime(
uint32_t metric_id, uint32_t event_code, std::string component,
int64_t elapsed_micros,
fuchsia::cobalt::LoggerBase::LogElapsedTimeCallback callback) {
callback(ToCobaltStatus(logger_.LogElapsedTime(metric_id, event_code,
component, elapsed_micros)));
}
void LoggerImpl::LogFrameRate(
uint32_t metric_id, uint32_t event_code, std::string component, float fps,
fuchsia::cobalt::LoggerBase::LogFrameRateCallback callback) {
callback(ToCobaltStatus(
logger_.LogFrameRate(metric_id, event_code, component, fps)));
}
void LoggerImpl::LogMemoryUsage(
uint32_t metric_id, uint32_t event_code, std::string component,
int64_t bytes,
fuchsia::cobalt::LoggerBase::LogMemoryUsageCallback callback) {
callback(ToCobaltStatus(
logger_.LogMemoryUsage(metric_id, event_code, component, bytes)));
}
void LoggerImpl::LogString(
uint32_t metric_id, std::string s,
fuchsia::cobalt::LoggerBase::LogStringCallback callback) {
callback(ToCobaltStatus(logger_.LogString(metric_id, s)));
}
void LoggerImpl::LogIntHistogram(
uint32_t metric_id, uint32_t event_code, std::string component,
std::vector<fuchsia::cobalt::HistogramBucket> histogram,
fuchsia::cobalt::Logger::LogIntHistogramCallback callback) {
logger::HistogramPtr histogram_ptr(
new google::protobuf::RepeatedPtrField<HistogramBucket>());
for (auto it = histogram.begin(); histogram.end() != it; it++) {
auto bucket = histogram_ptr->Add();
bucket->set_index((*it).index);
bucket->set_count((*it).count);
}
callback(ToCobaltStatus(logger_.LogIntHistogram(
metric_id, event_code, component, std::move(histogram_ptr))));
}
void LoggerImpl::LogIntHistogram(
uint32_t metric_id, uint32_t event_code, std::string component,
std::vector<uint32_t> bucket_indices, std::vector<uint64_t> bucket_counts,
fuchsia::cobalt::LoggerSimple::LogIntHistogramCallback callback) {
if (bucket_indices.size() != bucket_counts.size()) {
FXL_LOG(ERROR) << "[" << metric_id
<< "]: bucket_indices.size() != bucket_counts.size().";
callback(Status::INVALID_ARGUMENTS);
return;
}
logger::HistogramPtr histogram_ptr(
new google::protobuf::RepeatedPtrField<HistogramBucket>());
for (auto i = 0; i < bucket_indices.size(); i++) {
auto bucket = histogram_ptr->Add();
bucket->set_index(bucket_indices.at(i));
bucket->set_count(bucket_counts.at(i));
}
callback(ToCobaltStatus(logger_.LogIntHistogram(
metric_id, event_code, component, std::move(histogram_ptr))));
}
void LoggerImpl::LogCustomEvent(
uint32_t metric_id,
std::vector<fuchsia::cobalt::CustomEventValue> event_values,
fuchsia::cobalt::Logger::LogCustomEventCallback callback) {
logger::EventValuesPtr inner_event_values(
new google::protobuf::Map<std::string, CustomDimensionValue>());
for (auto it = event_values.begin(); event_values.end() != it; it++) {
CustomDimensionValue value;
if (it->value.is_string_value()) {
value.set_string_value(it->value.string_value());
} else if (it->value.is_int_value()) {
value.set_int_value(it->value.int_value());
} else if (it->value.is_double_value()) {
value.set_double_value(it->value.double_value());
} else if (it->value.is_index_value()) {
value.set_index_value(it->value.index_value());
}
auto pair = google::protobuf::MapPair(it->dimension_name, value);
inner_event_values->insert(pair);
}
callback(ToCobaltStatus(
logger_.LogCustomEvent(metric_id, std::move(inner_event_values))));
}
template <class CB>
void LoggerImpl::AddTimerObservationIfReady(
std::unique_ptr<TimerVal> timer_val_ptr, CB callback) {
if (!TimerManager::isReady(timer_val_ptr)) {
// TimerManager has not received both StartTimer and EndTimer calls. Return
// OK status and wait for the other call.
callback(Status::OK);
return;
}
callback(ToCobaltStatus(logger_.LogElapsedTime(
timer_val_ptr->metric_id, timer_val_ptr->event_code,
timer_val_ptr->component,
timer_val_ptr->end_timestamp - timer_val_ptr->start_timestamp)));
}
void LoggerImpl::StartTimer(
uint32_t metric_id, uint32_t event_code, std::string component,
std::string timer_id, uint64_t timestamp, uint32_t timeout_s,
fuchsia::cobalt::LoggerBase::StartTimerCallback callback) {
std::unique_ptr<TimerVal> timer_val_ptr;
auto status = timer_manager_->GetTimerValWithStart(
metric_id, event_code, component, 0, timer_id, timestamp, timeout_s,
&timer_val_ptr);
if (status != Status::OK) {
callback(status);
return;
}
AddTimerObservationIfReady(std::move(timer_val_ptr), std::move(callback));
}
void LoggerImpl::EndTimer(
std::string timer_id, uint64_t timestamp, uint32_t timeout_s,
fuchsia::cobalt::LoggerBase::EndTimerCallback callback) {
std::unique_ptr<TimerVal> timer_val_ptr;
auto status = timer_manager_->GetTimerValWithEnd(timer_id, timestamp,
timeout_s, &timer_val_ptr);
if (status != Status::OK) {
callback(status);
return;
}
AddTimerObservationIfReady(std::move(timer_val_ptr), std::move(callback));
}
using fuchsia::cobalt::EventPayload;
void LoggerImpl::LogCobaltEvent(
fuchsia::cobalt::CobaltEvent event,
fuchsia::cobalt::Logger::LogCobaltEventCallback callback) {
switch (event.payload.Which()) {
case EventPayload::Tag::kEventCount:
callback(ToCobaltStatus(logger_.LogEventCount(
event.metric_id, event.event_codes, event.component,
event.payload.event_count().period_duration_micros,
event.payload.event_count().count)));
return;
case EventPayload::Tag::kElapsedMicros:
callback(ToCobaltStatus(logger_.LogElapsedTime(
event.metric_id, event.event_codes, event.component,
event.payload.elapsed_micros())));
return;
case EventPayload::Tag::kFps:
callback(ToCobaltStatus(
logger_.LogFrameRate(event.metric_id, event.event_codes,
event.component, event.payload.fps())));
return;
case EventPayload::Tag::kMemoryBytesUsed:
callback(ToCobaltStatus(logger_.LogMemoryUsage(
event.metric_id, event.event_codes, event.component,
event.payload.memory_bytes_used())));
return;
case EventPayload::Tag::kStringEvent:
callback(ToCobaltStatus(
logger_.LogString(event.metric_id, event.payload.string_event())));
return;
case EventPayload::Tag::kIntHistogram: {
auto histogram = std::move(event.payload.int_histogram());
logger::HistogramPtr histogram_ptr(
new google::protobuf::RepeatedPtrField<HistogramBucket>());
for (auto it = histogram.begin(); histogram.end() != it; it++) {
auto bucket = histogram_ptr->Add();
bucket->set_index((*it).index);
bucket->set_count((*it).count);
}
callback(ToCobaltStatus(
logger_.LogIntHistogram(event.metric_id, event.event_codes,
event.component, std::move(histogram_ptr))));
return;
}
default:
callback(Status::INVALID_ARGUMENTS);
return;
}
}
void LoggerImpl::LogCobaltEvents(
std::vector<fuchsia::cobalt::CobaltEvent> events,
fuchsia::cobalt::Logger::LogCobaltEventCallback callback) {
auto failures = 0;
auto end = std::make_move_iterator(events.end());
for (auto it = std::make_move_iterator(events.begin()); it != end; it++) {
LogCobaltEvent(std::move(*it), [failures](Status status) mutable {
if (status != Status::OK) {
failures += 1;
}
});
}
if (failures == 0) {
callback(Status::OK);
} else {
callback(Status::INTERNAL_ERROR);
}
}
} // namespace cobalt