blob: fa3d0e48110646eb0df59830477a01ee436aba85 [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.
#include <fuchsia/cobalt/llcpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/vector_view.h>
#include <lib/zx/channel.h>
#include <zircon/errors.h>
#include <zircon/status.h>
#include <zircon/types.h>
#include <utility>
#include <cobalt-client/cpp/collector-internal.h>
#include <cobalt-client/cpp/histogram-internal.h>
#include <cobalt-client/cpp/types-internal.h>
namespace cobalt_client {
namespace internal {
namespace {
::llcpp::fuchsia::cobalt::CobaltEvent MetricIntoToCobaltEvent(const MetricInfo& metric_info) {
llcpp::fuchsia::cobalt::CobaltEvent event;
event.metric_id = metric_info.metric_id;
event.component = fidl::StringView(metric_info.component);
// Safe to do so, since the request is read only.
event.event_codes = fidl::VectorView<uint32_t>(
const_cast<uint32_t*>(metric_info.event_codes.data()), metric_info.event_codes.size());
return event;
}
} // namespace
std::string_view CobaltLogger::GetServiceName() {
return ::llcpp::fuchsia::cobalt::LoggerFactory::Name;
}
bool CobaltLogger::TryObtainLogger() {
if (logger_.is_valid()) {
return true;
}
zx::channel logger_factory_srv, logger_factory_client;
if (zx::channel::create(0, &logger_factory_client, &logger_factory_srv) != ZX_OK) {
return false;
}
if (options_.service_connect(options_.service_path.c_str(), std::move(logger_factory_srv)) !=
ZX_OK) {
return false;
}
zx::channel logger_svr;
if (zx::channel::create(0, &logger_, &logger_svr) != ZX_OK) {
return false;
}
// Obtain a logger service.
auto create_logger_result =
::llcpp::fuchsia::cobalt::LoggerFactory::Call::CreateLoggerFromProjectName(
zx::unowned_channel(logger_factory_client), fidl::StringView(options_.project_name),
static_cast<::llcpp::fuchsia::cobalt::ReleaseStage>(options_.release_stage),
std::move(logger_svr));
return create_logger_result.status() == ZX_OK &&
create_logger_result->status == ::llcpp::fuchsia::cobalt::Status::OK;
}
bool CobaltLogger::Log(const MetricInfo& metric_info, const HistogramBucket* buckets,
size_t bucket_count) {
if (!TryObtainLogger()) {
return false;
}
auto event = MetricIntoToCobaltEvent(metric_info);
// Safe because is read only.
event.payload.mutable_int_histogram() =
fidl::VectorView<HistogramBucket>(const_cast<HistogramBucket*>(buckets), bucket_count);
auto log_result = llcpp::fuchsia::cobalt::Logger::Call::LogCobaltEvent(
zx::unowned_channel(logger_), std::move(event));
if (log_result.status() == ZX_ERR_PEER_CLOSED) {
Reset();
}
return log_result.status() == ZX_OK && log_result->status == ::llcpp::fuchsia::cobalt::Status::OK;
}
bool CobaltLogger::Log(const MetricInfo& metric_info, RemoteCounter::Type count) {
if (!TryObtainLogger()) {
return false;
}
auto event = MetricIntoToCobaltEvent(metric_info);
event.payload.mutable_event_count() = {.period_duration_micros = 0, .count = count};
auto log_result = llcpp::fuchsia::cobalt::Logger::Call::LogCobaltEvent(
zx::unowned_channel(logger_), std::move(event));
if (log_result.status() == ZX_ERR_PEER_CLOSED) {
Reset();
}
return log_result.status() == ZX_OK && log_result->status == ::llcpp::fuchsia::cobalt::Status::OK;
}
} // namespace internal
} // namespace cobalt_client