blob: 246cbd17d81cfa83119605f4f3859f33c73198a2 [file] [log] [blame]
// Copyright 2019 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.
#ifndef COBALT_SRC_PUBLIC_COBALT_CONFIG_H_
#define COBALT_SRC_PUBLIC_COBALT_CONFIG_H_
#include <memory>
#include "src/lib/clearcut/uploader.h"
#include "src/lib/util/clock.h"
#include "src/lib/util/file_system.h"
#include "src/local_aggregation_1_1/local_aggregate_storage/local_aggregate_storage.h"
#include "src/logger/project_context.h"
#include "src/pb/common.pb.h"
#include "src/public/activity_listener_interface.h"
#include "src/public/lib/http_client.h"
#include "src/registry/metric_definition.pb.h"
#include "src/system_data/client_secret.h"
#include "src/system_data/configuration_data.h"
namespace cobalt {
constexpr char kDefaultClearcutEndpoint[] = "https://play.googleapis.com/staging/log";
constexpr char kProductionClearcutEndpoint[] = "https://play.googleapis.com/log";
constexpr size_t kDefaultClearcutMaxRetries = 5;
using StorageStrategy = local_aggregation::LocalAggregateStorage::StorageStrategy;
class TargetPipelineInterface {
public:
explicit TargetPipelineInterface(system_data::Environment environment)
: environment_(environment){};
virtual ~TargetPipelineInterface() = default;
// The target environment for the pipeline. Used to determine where to send the data.
[[nodiscard]] system_data::Environment environment() const { return environment_; }
// An encoded CobaltEncryptionKey proto representing the encryption key to be used for envelopes
// sent to the shuffler. (Or nullopt for no encryption)
[[nodiscard]] virtual std::optional<std::string> shuffler_encryption_key() const {
return std::nullopt;
}
// An encoded CobaltEncryptionKey proto representing the encryption key to be used for
// observations sent to the analyzer. (Or nullopt for no encryption)
[[nodiscard]] virtual std::optional<std::string> analyzer_encryption_key() const {
return std::nullopt;
}
// The URL for the desired clearcut endpoint.
[[nodiscard]] virtual std::string clearcut_endpoint() const { return ""; };
// Returns an implementation of lib::HTTPClient. Will be used for uploading data in the
// ShippingManager.
//
// Note, that it is used to create cobalt::lib::ClearcutUploader that uses HTTP
// requests for uploading to clearcut.
// If TakeClearcutUploader is overridden then there is no need to override this method.
[[nodiscard]] virtual std::unique_ptr<lib::HTTPClient> TakeHttpClient() { return nullptr; }
// Returns an implementation of lib::clearcut::ClearcutUploaderInterface. Will be used for
// uploading data in the ShippingManager. If it is not set uploader will be created using
// parameters in the config.
[[nodiscard]] virtual std::unique_ptr<lib::clearcut::ClearcutUploaderInterface>
TakeClearcutUploader() {
return nullptr;
}
// How many times should the clearcut upload be reattempted, before returning the observations to
// the ObservationStore.
[[nodiscard]] virtual size_t clearcut_max_retries() const { return 0; }
private:
system_data::Environment environment_;
};
class LocalPipeline : public TargetPipelineInterface {
public:
LocalPipeline() : TargetPipelineInterface(system_data::Environment::LOCAL) {}
~LocalPipeline() override = default;
};
class TargetPipeline : public TargetPipelineInterface {
public:
TargetPipeline(system_data::Environment environment, std::string shuffler_encryption_key,
std::string analyzer_encryption_key, std::unique_ptr<lib::HTTPClient> http_client,
size_t clearcut_max_retries = kDefaultClearcutMaxRetries)
: TargetPipelineInterface(environment),
shuffler_encryption_key_(std::move(shuffler_encryption_key)),
analyzer_encryption_key_(std::move(analyzer_encryption_key)),
http_client_(std::move(http_client)),
clearcut_max_retries_(clearcut_max_retries) {}
~TargetPipeline() override = default;
[[nodiscard]] std::optional<std::string> shuffler_encryption_key() const override {
if (shuffler_encryption_key_.empty()) {
return std::optional<std::string>();
}
return shuffler_encryption_key_;
}
[[nodiscard]] std::optional<std::string> analyzer_encryption_key() const override {
if (analyzer_encryption_key_.empty()) {
return std::optional<std::string>();
}
return analyzer_encryption_key_;
}
[[nodiscard]] std::string clearcut_endpoint() const override {
if (environment() == system_data::Environment::PROD) {
return kProductionClearcutEndpoint;
}
return kDefaultClearcutEndpoint;
};
[[nodiscard]] std::unique_ptr<lib::HTTPClient> TakeHttpClient() override {
return std::move(http_client_);
}
[[nodiscard]] size_t clearcut_max_retries() const override { return clearcut_max_retries_; }
private:
std::string shuffler_encryption_key_;
std::string analyzer_encryption_key_;
std::unique_ptr<lib::HTTPClient> http_client_;
size_t clearcut_max_retries_;
};
// These four values are provided to the UploadScheduler of the shipping manager.
// REQUIRED:
// 0 <= min_interval <= target_interval <= kMaxSeconds
// 0 <= upload_jitter < 1
struct UploadScheduleConfig {
// |target_interval|: How frequently should ShippingManager perform regular periodic sends to the
// Shuffler? Set to kMaxSeconds to effectively disable periodic sends.
std::chrono::seconds target_interval;
// |min_interval|: Used as the basis for exponentially increasing the upload interval. The
// resulting interval starts at this value, and then is multiplied by 2 each time until the value
// is greater than or equal to |target_interval|.
std::chrono::seconds min_interval;
//
// |initial_interval| The upload scheduler thread will initially perform more frequent uploads at
// this interval and then exponentially back off until it reaches a periodic
// rhythm of |target_interval|.
std::chrono::seconds initial_interval;
// |jitter|: Used to mitigate risk of synchronized uploads between devices
// and hide information about reboot time. Each interval is increased
// or decreased by a random value n distributed between 0 and
// |jitter| * current_interval.
float jitter;
};
struct CobaltConfig {
// |product_name|: The value to use for the |product_name| field of the SystemProfile.
std::string product_name = "";
// |board_name_suggestion|: A suggestion for the value to use for the |board_name| field of the
// SystemProfile. This may be ignored if SystemData is able to determine the board name directly.
// A value of "" indicates that the caller has no information about board name, so one should be
// guessed.
std::string board_name_suggestion = "";
// |version|: The version of the running system. The use of this field is system-specific. For
// example on Fuchsia a possible value for |version| is "20190220_01_RC00".
std::string version = "";
// |build_type|: The build type of the running system. The use of this field
// is system-specific. Fuchsia can have possible values of "eng", "user", and
// "user_debug".
SystemProfile::BuildType build_type = SystemProfile::UNKNOWN_TYPE;
// |release_stage|: The ReleaseStage of the running system.
ReleaseStage release_stage = ReleaseStage::GA;
// |file_system|: The FileSystem implementation to be used for all file system operations in
// Cobalt.
std::unique_ptr<util::FileSystem> file_system;
// |use_memory_observation_store|: If true, the ObservaitonStore used will be memory backed intead
// of file backed.
bool use_memory_observation_store = false;
// These three values are provided to the ObservationStore.
//
//|max_bytes_per_event|: Attempting to log an event that is larger than this value will result in
// an error code kObservationTooBig. (See observation_store.h)
//
// |max_bytes_per_envelope|: When pooling together Observaitons into an Envelope, the
// ObservationStore will try not to form envelopes larger than this size. This value is used to
// avoid sending messages over HTTP that are too large. (see observation_store.h)
//
// |max_bytes_total|: This is the maximum size of the Observations in the ObservationStore. If the
// size of the accumulated Observation data reaches this value, then ObservationStore will not
// accept any more Observations, resulting in an error code of kStoreFull. (See
// observaiton_store.h)
//
// REQUIRED:
// 0 <= max_bytes_per_event <= max_bytes_per_envelope <= max_bytes_total
// 0 <= max_bytes_per_envelope
size_t max_bytes_per_event;
size_t max_bytes_per_envelope;
size_t max_bytes_total;
// |observation_store_directory|: If |use_memory_observation_store| is false, this is the absolute
// path to the directory the observation_store will use to store observations. This directory
// doesn't need to exist yet, but its parent directory must already exist.
std::string observation_store_directory;
// |local_aggregate_proto_store_path|: The absolute path to a file where the local aggregate proto
// should be stored. The directory this file is in must already exist.
std::string local_aggregate_proto_store_path;
// |obs_history_proto_store_path|: The absolute path to a file where the observation history proto
// should be stored. The directory this file is in must already exist.
std::string obs_history_proto_store_path;
// |local_aggregate_store_dir|: The absolute path to the directory where the local aggregate store
// for Cobalt 1.1 should be stored. This directory doesn't need to exist yet, but its parent
// directory must already exist.
std::string local_aggregate_store_dir;
// |local_aggregate_store_strategy|: The strategy to use for LocalAggregateStorage.
//
// Immediate: Always write to disk immediately after every modification. (The default)
// Delayed: Writes to disk every 5 seconds if there have been any modifications. (Note: This
// implementation has more potential to lose data. Only use this on systems where
// Immediate performs poorly)
StorageStrategy local_aggregate_store_strategy = StorageStrategy::Immediate;
// |system_data_cache_path|: The absolute path where the MetadataBuilder will cache its previously
// seen SystemData.
std::string system_data_cache_path;
// |upload_schedule|: config values provided to the UploadScheduler.
UploadScheduleConfig upload_schedule_cfg;
// |target_pipeline|: Used to determine where to send observations, and how to encrypt them.
std::unique_ptr<TargetPipelineInterface> target_pipeline;
// |local_shipping_manager_path|: If |environments| is equal to {LOCAL}, the observations will be
// written to this path, instead of being shipped to clearcut.
std::string local_shipping_manager_path;
// |api_key|: An API key included in each request to the Shuffler. If the API key is unrecognized
// on the server, the observations may be discarded.
std::string api_key;
// |client_secret|: The ClientSecret for this device.
system_data::ClientSecret client_secret;
// |global_registry|: The complete registry of all customers, projects, metrics, and reports.
std::unique_ptr<CobaltRegistry> global_registry = nullptr;
// |local_aggregation_backfill_days|: The number of past days for which the AggregateStore
// generates and sends Observations, in addition to a requested day index.
size_t local_aggregation_backfill_days;
// |validated_clock|: A reference to a ValidatedClockInterface, used to determine when the system
// has a clock that we can rely on.
util::ValidatedClockInterface* validated_clock;
// |activity_listener|: The interface to receive information on the current device state.
std::unique_ptr<ActivityListenerInterface> activity_listener;
// |enable_replacement_metrics|: Determines wether or not replacement_metric_id should be honored
bool enable_replacement_metrics = false;
// |start_worker_threads|: Determines whether or not to start the worker threads.
bool start_worker_threads = true;
};
} // namespace cobalt
#endif // COBALT_SRC_PUBLIC_COBALT_CONFIG_H_