| // 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 <cobalt-client/cpp/collector.h> |
| #include <cobalt-client/cpp/counter-internal.h> |
| #include <cobalt-client/cpp/histogram-internal.h> |
| #include <cobalt-client/cpp/metric-options.h> |
| #include <cobalt-client/cpp/types-internal.h> |
| |
| #ifdef __Fuchsia__ |
| #include <cobalt-client/cpp/collector-internal.h> |
| |
| #include <fuchsia/cobalt/c/fidl.h> |
| #include <lib/fdio/fd.h> |
| #include <lib/fdio/fdio.h> |
| #include <lib/fdio/directory.h> |
| #include <lib/fidl/cpp/vector_view.h> |
| #include <lib/zx/channel.h> |
| #endif |
| |
| #include <utility> |
| |
| namespace cobalt_client { |
| namespace internal { |
| namespace { |
| |
| #ifdef __Fuchsia__ |
| internal::CobaltOptions MakeCobaltOptions(CollectorOptions options) { |
| ZX_DEBUG_ASSERT_MSG(options.load_config || options.project_id >= 0, |
| "Must define a load_config function or a valid project_id."); |
| internal::CobaltOptions cobalt_options; |
| cobalt_options.logger_deadline_first_attempt = options.initial_response_deadline; |
| cobalt_options.logger_deadline = options.response_deadline; |
| cobalt_options.project_id = options.project_id; |
| cobalt_options.config_reader = std::move(options.load_config); |
| cobalt_options.service_connect = [](const char* service_path, |
| zx::channel service) -> zx_status_t { |
| return fdio_service_connect(service_path, service.release()); |
| }; |
| cobalt_options.service_path.AppendPrintf("/svc/%s", fuchsia_cobalt_LoggerFactory_Name); |
| cobalt_options.release_stage = static_cast<internal::ReleaseStage>(options.release_stage); |
| return cobalt_options; |
| } |
| #else |
| // Host side implementation, which does nothing, just provides safety that all methods wont |
| // fault. |
| class HostLogger : public internal::Logger { |
| public: |
| ~HostLogger() override = default; |
| |
| bool Log(const RemoteMetricInfo& remote_info, const HistogramBucket* buckets, |
| size_t num_buckets) override { |
| return true; |
| }; |
| |
| bool Log(const RemoteMetricInfo& remote_info, int64_t count) override { return true; }; |
| }; |
| #endif // __Fuchsia__ |
| } // namespace |
| } // namespace internal |
| |
| #ifdef __Fuchsia__ |
| Collector::Collector(CollectorOptions options) |
| : logger_(std::make_unique<internal::CobaltLogger>( |
| internal::MakeCobaltOptions(std::move(options)))) { |
| flushing_.store(false); |
| } |
| #else |
| Collector::Collector(CollectorOptions options) : logger_(std::make_unique<internal::HostLogger>()) { |
| flushing_.store(false); |
| } |
| #endif // __Fuchsia__ |
| |
| Collector::Collector(std::unique_ptr<internal::Logger> logger) : logger_(std::move(logger)) { |
| flushing_.store(false); |
| } |
| |
| Collector::~Collector() { |
| if (logger_ != nullptr) { |
| Flush(); |
| } |
| } |
| |
| void Collector::Flush() { |
| // If we are already flushing we just return and do nothing. |
| // First come first serve. |
| if (flushing_.exchange(true)) { |
| return; |
| } |
| |
| for (internal::FlushInterface* flushable : flushables_) { |
| if (!flushable->Flush(logger_.get())) { |
| flushable->UndoFlush(); |
| } |
| } |
| |
| // Once we are finished we allow flushing again. |
| flushing_.store(false); |
| } |
| |
| void Collector::UnSubscribe(internal::FlushInterface* flushable) { |
| // TODO(gevalentino): Replace the vector for an unordered_map/hash_map. |
| for (size_t i = 0; i < flushables_.size(); ++i) { |
| if (flushable == flushables_[i]) { |
| flushables_.erase(i); |
| break; |
| } |
| } |
| } |
| |
| CollectorOptions CollectorOptions::GeneralAvailability() { |
| CollectorOptions options; |
| options.release_stage = static_cast<uint32_t>(internal::ReleaseStage::kGa); |
| return options; |
| } |
| |
| CollectorOptions CollectorOptions::Dogfood() { |
| CollectorOptions options; |
| options.release_stage = static_cast<uint32_t>(internal::ReleaseStage::kDogfood); |
| return options; |
| } |
| |
| CollectorOptions CollectorOptions::Fishfood() { |
| CollectorOptions options; |
| options.release_stage = static_cast<uint32_t>(internal::ReleaseStage::kFishfood); |
| return options; |
| } |
| |
| CollectorOptions CollectorOptions::Debug() { |
| CollectorOptions options; |
| options.release_stage = static_cast<uint32_t>(internal::ReleaseStage::kDebug); |
| return options; |
| } |
| |
| } // namespace cobalt_client |