// 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 #include #include #include #include #ifdef __Fuchsia__ #include #include #include #include #include #endif #include namespace cobalt_client { namespace internal { namespace { #ifdef __Fuchsia__ internal::CobaltOptions MakeCobaltOptions(CollectorOptions options) { ZX_DEBUG_ASSERT_MSG(options.load_config, "Must define a load_config function."); internal::CobaltOptions cobalt_options; cobalt_options.logger_deadline_first_attempt = options.initial_response_deadline; cobalt_options.logger_deadline = options.response_deadline; 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(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::MakeCobaltOptions(std::move(options)))) { flushing_.store(false); } #else Collector::Collector(CollectorOptions options) : logger_(std::make_unique()) { flushing_.store(false); } #endif // __Fuchsia__ Collector::Collector(std::unique_ptr 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(internal::ReleaseStage::kGa); return options; } CollectorOptions CollectorOptions::Dogfood() { CollectorOptions options; options.release_stage = static_cast(internal::ReleaseStage::kDogfood); return options; } CollectorOptions CollectorOptions::Fishfood() { CollectorOptions options; options.release_stage = static_cast(internal::ReleaseStage::kFishfood); return options; } CollectorOptions CollectorOptions::Debug() { CollectorOptions options; options.release_stage = static_cast(internal::ReleaseStage::kDebug); return options; } } // namespace cobalt_client