prod/native/libcommon/code/ConfigurationManager.h (77 lines of code) (raw):

/* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #pragma once #include "ConfigurationSnapshot.h" #include "LoggerInterface.h" #include "basic_macros.h" #include <atomic> #include <chrono> #include <functional> #include <map> #include <memory> #include <optional> #include <string> #include <variant> namespace elasticapm::php { using namespace std::string_literals; //TODO default unit? //TODO sign class ConfigurationManager { public: using readIniValue_t = std::function<std::optional<std::string>(std::string_view)>; struct OptionMetadata { enum type { boolean, string, duration, loglevel, bytes } type; size_t offset; bool secret = false; }; using optionValue_t = std::variant<std::chrono::milliseconds, LogLevel, bool, std::string, std::size_t, std::nullopt_t>; ConfigurationManager(readIniValue_t readIniValue) : readIniValue_(readIniValue) { current_.revision = getNextRevision(); } //TODO class might be used in different threads, right now it is pretty safe as log is attached on globals init (for zts it should be in minit) void attachLogger(std::shared_ptr<LoggerInterface> logger) { logger_ = std::move(logger); } //TODO lock void update(); //TODO lock bool updateIfChanged(ConfigurationSnapshot &snapshot) { if (snapshot.revision != current_.revision) { snapshot = current_; return true; } return false; } std::map<std::string, OptionMetadata> const &getOptionMetadata() { return options_; } optionValue_t getOptionValue(std::string_view optionName, ConfigurationSnapshot const &snapshot) const; //TODO test static std::string accessOptionStringValueByMetadata(OptionMetadata const &metadata, ConfigurationSnapshot const &snapshot); private: std::optional<std::string> fetchStringValue(std::string_view name); uint64_t getNextRevision(); private: readIniValue_t readIniValue_; std::atomic_uint64_t upcomingConfigRevision_ = 0; ConfigurationSnapshot current_; std::shared_ptr<LoggerInterface> logger_; #define BUILD_METADATA(optname, type, secret) { EL_STRINGIFY(optname), {type, offsetof(ConfigurationSnapshot, optname), secret}} // clang-format off std::map<std::string, OptionMetadata> options_ = { BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_BOOTSTRAP_PHP_PART_FILE, OptionMetadata::type::string, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_ENABLED, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_LOG_FILE, OptionMetadata::type::string, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_LOG_LEVEL, OptionMetadata::type::loglevel, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_LOG_LEVEL_FILE, OptionMetadata::type::loglevel, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_LOG_LEVEL_STDERR, OptionMetadata::type::loglevel, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_LOG_LEVEL_SYSLOG, OptionMetadata::type::loglevel, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_LOG_FEATURES, OptionMetadata::type::string, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_DEBUG_DIAGNOSTICS_FILE, OptionMetadata::type::string, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_VERIFY_SERVER_CERT, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_MAX_SEND_QUEUE_SIZE, OptionMetadata::type::bytes, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_ASYNC_TRANSPORT, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_ASYNC_TRANSPORT_SHUTDOWN_TIMEOUT, OptionMetadata::type::duration, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_DEBUG_INSTRUMENT_ALL, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_DEBUG_PHP_HOOKS_ENABLED, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_INFERRED_SPANS_ENABLED, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_INFERRED_SPANS_REDUCTION_ENABLED, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_INFERRED_SPANS_STACKTRACE_ENABLED, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_INFERRED_SPANS_SAMPLING_INTERVAL, OptionMetadata::type::duration, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_INFERRED_SPANS_MIN_DURATION, OptionMetadata::type::duration, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_DEPENDENCY_AUTOLOADER_GUARD_ENABLED, OptionMetadata::type::boolean, false), BUILD_METADATA(ELASTIC_OTEL_CFG_OPT_NAME_NATIVE_OTLP_SERIALIZER_ENABLED, OptionMetadata::type::boolean, false) }; // clang-format on }; } // namespace elasticapm::php