blob: f3e528df8d7fd081954a981bb41eef01d60b1542 [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 {
fuchsia_cobalt::wire::CobaltEvent MetricIntoToCobaltEvent(const MetricOptions& metric_info) {
fuchsia_cobalt::wire::CobaltEvent event;
event.metric_id = metric_info.metric_id;
event.component = fidl::StringView::FromExternal(metric_info.component);
// Safe to do so, since the request is read only.
event.event_codes = fidl::VectorView<uint32_t>::FromExternal(
const_cast<uint32_t*>(metric_info.event_codes.data()), metric_info.metric_dimensions);
return event;
}
} // namespace
std::string_view CobaltLogger::GetServiceName() {
return fidl::DiscoverableProtocolName<fuchsia_cobalt::LoggerFactory>;
}
bool CobaltLogger::TryObtainLogger() {
if (logger_.client_end().is_valid()) {
return true;
}
auto factory_endpoints = fidl::CreateEndpoints<fuchsia_cobalt::LoggerFactory>();
if (factory_endpoints.is_error()) {
return false;
}
auto [logger_factory_client, logger_factory_srv] = *std::move(factory_endpoints);
if (options_.service_connect(options_.service_path.c_str(), logger_factory_srv.TakeChannel()) !=
ZX_OK) {
return false;
}
// Obtain a logger service for the project ID.
auto logger_endpoints = fidl::CreateEndpoints<fuchsia_cobalt::Logger>();
if (logger_endpoints.is_error()) {
return false;
}
auto [logger_client, logger_server] = *std::move(logger_endpoints);
auto create_logger_result =
fidl::WireCall(logger_factory_client)
.CreateLoggerFromProjectId(options_.project_id, std::move(logger_server));
if (create_logger_result.status() == ZX_OK &&
create_logger_result->status == fuchsia_cobalt::wire::Status::OK) {
logger_ = fidl::BindSyncClient(std::move(logger_client));
return true;
}
return false;
}
bool CobaltLogger::Log(const MetricOptions& metric_info, const HistogramBucket* buckets,
size_t bucket_count) {
if (!TryObtainLogger()) {
return false;
}
auto event = MetricIntoToCobaltEvent(metric_info);
// Safe because is read only.
auto int_histogram = fidl::VectorView<HistogramBucket>::FromExternal(
const_cast<HistogramBucket*>(buckets), bucket_count);
event.payload.set_int_histogram(
fidl::ObjectView<fidl::VectorView<HistogramBucket>>::FromExternal(&int_histogram));
auto log_result = logger_.LogCobaltEvent(std::move(event));
if (log_result.status() == ZX_ERR_PEER_CLOSED) {
Reset();
}
return log_result.status() == ZX_OK && log_result->status == fuchsia_cobalt::wire::Status::OK;
}
bool CobaltLogger::Log(const MetricOptions& metric_info, RemoteCounter::Type count) {
if (!TryObtainLogger()) {
return false;
}
auto event = MetricIntoToCobaltEvent(metric_info);
fuchsia_cobalt::wire::CountEvent event_count{.period_duration_micros = 0, .count = count};
event.payload.set_event_count(
fidl::ObjectView<fuchsia_cobalt::wire::CountEvent>::FromExternal(&event_count));
auto log_result = logger_.LogCobaltEvent(std::move(event));
if (log_result.status() == ZX_ERR_PEER_CLOSED) {
Reset();
}
return log_result.status() == ZX_OK && log_result->status == fuchsia_cobalt::wire::Status::OK;
}
bool CobaltLogger::LogInteger(const MetricOptions& metric_info, RemoteCounter::Type value) {
if (!TryObtainLogger()) {
return false;
}
auto event = MetricIntoToCobaltEvent(metric_info);
event.payload.set_memory_bytes_used(fidl::ObjectView<RemoteCounter::Type>::FromExternal(&value));
// Cobalt 1.0 does not support integer. The closest to integer is memory
// usage. So, we use MemoryUsage until we have a better support for integer(in
// version 1.1).
auto log_result =
logger_.LogMemoryUsage(event.metric_id, event.event_codes[0], event.component, value);
if (log_result.status() == ZX_ERR_PEER_CLOSED) {
Reset();
}
return log_result.status() == ZX_OK && log_result->status == fuchsia_cobalt::wire::Status::OK;
}
} // namespace internal
} // namespace cobalt_client