| // 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. |
| |
| #pragma once |
| |
| #include <limits.h> |
| #include <stdint.h> |
| |
| #include <cobalt-client/cpp/counter-internal.h> |
| #include <cobalt-client/cpp/histogram-internal.h> |
| #include <cobalt-client/cpp/types-internal.h> |
| #include <fbl/string_buffer.h> |
| #include <lib/zx/channel.h> |
| #include <lib/zx/time.h> |
| #include <lib/zx/vmo.h> |
| #include <zircon/types.h> |
| |
| namespace cobalt_client { |
| namespace internal { |
| |
| struct CobaltOptions { |
| // Service path to LoggerFactory interface. |
| fbl::StringBuffer<PATH_MAX> service_path; |
| |
| // Maximum time to wait for Cobalt Service to respond for the CreateLogger request. |
| // Unless the channel is closed, we will keep checking if the channel is readable. |
| zx::duration logger_deadline; |
| |
| // The maximum time to wait, after the request has been written to the channel. |
| // This allows amortizing the wait time in future calls. |
| zx::duration logger_deadline_first_attempt; |
| |
| // Sets the input VMO to point to the serialized config for this logger and the size |
| // of the serialized data. |
| fbl::Function<bool(zx::vmo*, size_t*)> config_reader; |
| |
| // Performs a connection to a service at a given path. |
| fbl::Function<zx_status_t(const char* service_path, zx::channel service)> service_connect; |
| |
| // Used to acquire a logger instance. |
| fbl::String project_name; |
| |
| // Which release stage to use for persisting metrics. |
| ReleaseStage release_stage; |
| }; |
| |
| class CobaltLogger : public Logger { |
| public: |
| CobaltLogger() = delete; |
| // instance from cobalt service; |
| explicit CobaltLogger(CobaltOptions options); |
| CobaltLogger(const CobaltLogger&) = delete; |
| CobaltLogger(CobaltLogger&&) = delete; |
| CobaltLogger& operator=(const CobaltLogger&) = delete; |
| CobaltLogger& operator=(CobaltLogger&&) = delete; |
| ~CobaltLogger() override {} |
| |
| // Returns true if the histogram was persisted. |
| bool Log(const RemoteMetricInfo& metric_info, const HistogramBucket* buckets, |
| size_t bucket_count) override; |
| |
| // Returns true if the counter was persisted. |
| bool Log(const RemoteMetricInfo& metric_info, int64_t count) override; |
| |
| bool IsListeningForReply() const { return logger_factory_.is_valid(); } |
| |
| // Blocks until the reply from LoggerFactory arrives into |logger_factory_| |
| // channel or the peer is closed. |observed| will be set to the observed signals |
| // if provided. Useful for testing to enforce a deterministic order of operations. |
| zx_status_t WaitForReply(zx_signals_t* observed = nullptr) const { |
| return zx_object_wait_one(logger_factory_.get(), |
| ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, |
| zx::time::infinite().get(), observed); |
| } |
| |
| protected: |
| // If returns true, a channel has been established with the endpoint, |
| // and the handshake to set up a logger started. |
| bool TrySendLoggerRequest(); |
| |
| // The service replied and the status is ok. |
| bool HasCobaltReplied(zx::duration deadline); |
| |
| // Returns true if the logger request has been sent, and Cobalt Service |
| // replied successfully already. If any error happens that prevents |
| // writing to the current channel(ZX_ERR_PEER_CLOSED), we guarantee |
| // the next time this method is called will return false. |
| bool IsLoggerReady(); |
| |
| // Set of options for this logger. |
| CobaltOptions options_; |
| |
| zx::channel logger_; |
| zx::channel logger_factory_; |
| |
| bool is_first_attempt_; |
| }; |
| |
| } // namespace internal |
| } // namespace cobalt_client |