| // Copyright 2022 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/lib/metrics_buffer/metrics_impl.h" |
| |
| #include <lib/component/incoming/cpp/protocol.h> |
| #include <lib/fidl/cpp/wire/channel.h> |
| |
| namespace cobalt { |
| |
| using fuchsia_metrics::MetricEventLogger; |
| using fuchsia_metrics::MetricEventLoggerFactory; |
| |
| using MetricsResult = ::fit::result<fidl::internal::ErrorsInImpl<fuchsia_metrics::Error>>; |
| |
| MetricsImpl::MetricsImpl(async_dispatcher_t* dispatcher, |
| fidl::ClientEnd<fuchsia_io::Directory> directory, uint32_t project_id) |
| : ServiceHubConnector(dispatcher), directory_(std::move(directory)), project_id_(project_id) {} |
| |
| void MetricsImpl::LogMetricEvents(std::vector<fuchsia_metrics::MetricEvent> events) { |
| Do([events = std::move(events)](fidl::Client<MetricEventLogger>& logger, DoResolver resolver) { |
| logger->LogMetricEvents({events}).Then( |
| [resolver = std::move(resolver)](MetricsResult result) mutable { |
| // Should retry if the result returns an error and the error is either a transport error |
| // of the request message or logger's local buffer is temporarily full. |
| resolver.resolve(result.is_error() && (result.error_value().is_framework_error() || |
| result.error_value().domain_error() == |
| fuchsia_metrics::Error::kBufferFull)); |
| }); |
| }); |
| } |
| |
| void MetricsImpl::ConnectToServiceHub(ServiceHubConnectResolver resolver) { |
| auto connection = component::ConnectAt<MetricEventLoggerFactory>(directory_); |
| if (connection.is_ok()) { |
| resolver.resolve(std::move(connection.value())); |
| } |
| } |
| |
| void MetricsImpl::ConnectToService(fidl::Client<MetricEventLoggerFactory>& factory, |
| ServiceConnectResolver resolver) { |
| auto endpoints = fidl::CreateEndpoints<MetricEventLogger>(); |
| |
| factory |
| ->CreateMetricEventLogger( |
| {fuchsia_metrics::ProjectSpec({.project_id = project_id_}), std::move(endpoints->server)}) |
| .Then([resolver = std::move(resolver), client_end = std::move(endpoints->client)]( |
| fidl::Result<MetricEventLoggerFactory::CreateMetricEventLogger>& response) mutable { |
| if (response.is_ok()) { |
| resolver.resolve(std::move(client_end)); |
| } else if (response.error_value().is_domain_error() && |
| response.error_value().domain_error() == fuchsia_metrics::Error::kShutDown) { |
| FX_LOGS(INFO) << "Stopping sending Cobalt events"; |
| resolver.resolve(std::nullopt); |
| } else { |
| FX_LOGS(WARNING) << "Failed to set up Cobalt: " << response.error_value(); |
| } |
| }); |
| } |
| |
| } // namespace cobalt |