blob: 350d0700e020a97c0ead7dd84987f10a4940ebd2 [file] [log] [blame]
// 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.
#ifndef COBALT_SRC_LOGGER_EVENT_RECORD_H_
#define COBALT_SRC_LOGGER_EVENT_RECORD_H_
#include <memory>
#include <third_party/abseil-cpp/absl/strings/str_cat.h>
#include "src/lib/util/status_builder.h"
#include "src/logger/project_context.h"
#include "src/logging.h"
#include "src/pb/common.pb.h"
#include "src/pb/event.pb.h"
#include "src/public/lib/registry_identifiers.h"
#include "src/public/lib/statusor/statusor.h"
#include "src/registry/metric_definition.pb.h"
namespace cobalt::logger {
// A container for an Event proto message and the ProjectContext and the metric within it for which
// that Event should be logged.
class EventRecord {
public:
static lib::statusor::StatusOr<std::unique_ptr<EventRecord>> MakeEventRecord(
std::shared_ptr<const ProjectContext> project_context, uint32_t metric_id) {
std::unique_ptr<EventRecord> record(new EventRecord(std::move(project_context), metric_id));
if (record->metric_) {
return record;
}
return Status(StatusCode::INVALID_ARGUMENT, "Provided metric_id (" + std::to_string(metric_id) +
") does not match a known metric");
}
~EventRecord() = default;
EventRecord(EventRecord&& rhs) = default;
// Get the ProjectContext associated with this Event.
[[nodiscard]] const ProjectContext* project_context() const { return project_context_.get(); }
// Get the Metric within the ProjectContext that this Event is for.
[[nodiscard]] const MetricDefinition* metric() const { return metric_; }
// Get the Event that is to be logged.
[[nodiscard]] Event* event() const { return event_.get(); }
// Get the SystemProfile that is to be logged with the event. Only used for Cobalt 1.1 metrics.
[[nodiscard]] SystemProfile* system_profile() const { return system_profile_.get(); }
[[nodiscard]] std::string GetLogDetails() const {
return absl::StrCat("project_id:", metric_->project_id(), " metric_id:", metric_->id());
}
[[nodiscard]] std::string FullMetricName() const {
return project_context_->FullMetricName(*metric_);
}
[[nodiscard]] lib::MetricIdentifier MetricIdentifier() const {
return project_context_->Identifier().ForMetric(metric_->id());
}
private:
EventRecord(std::shared_ptr<const ProjectContext> project_context, uint32_t metric_id)
: project_context_(std::move(project_context)),
event_(std::make_unique<Event>()),
system_profile_(std::make_unique<SystemProfile>()) {
metric_ = project_context_->GetMetric(metric_id);
}
const std::shared_ptr<const ProjectContext> project_context_;
const MetricDefinition* metric_;
std::unique_ptr<Event> event_;
std::unique_ptr<SystemProfile> system_profile_;
};
} // namespace cobalt::logger
namespace cobalt::util {
// Specialization of ContextFormatter for logger::EventRecord to give it default formatting and
// allow it to be passed to StatusBuilder::WithContexts.
//
// Will print by default:
// - With no metric: Project=<project_context()->FullyQualifiedName()>
// - With a metric: Metric=<FullMetricName()>
template <>
class ContextFormatter<logger::EventRecord> {
public:
explicit ContextFormatter(const logger::EventRecord& v) : v_(v) {}
std::string default_key() {
if (v_.metric()) {
return "Metric";
}
return "Project";
}
void write_value(std::ostream& stream) {
if (v_.metric()) {
stream << v_.FullMetricName();
} else {
stream << v_.project_context()->FullyQualifiedName();
}
}
private:
const logger::EventRecord& v_;
};
} // namespace cobalt::util
#endif // COBALT_SRC_LOGGER_EVENT_RECORD_H_