All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.newrelic.agent.config.AgentConfigImpl Maven / Gradle / Ivy

There is a newer version: 8.14.0
Show newest version
/*
 *
 *  * Copyright 2020 New Relic Corporation. All rights reserved.
 *  * SPDX-License-Identifier: Apache-2.0
 *
 */

package com.newrelic.agent.config;

import com.google.common.base.Joiner;
import com.newrelic.agent.Agent;
import com.newrelic.agent.transaction.TransactionNamingScheme;
import com.newrelic.agent.transport.DataSenderImpl;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.regex.Pattern;

import static com.newrelic.agent.config.SpanEventsConfig.SERVER_SPAN_HARVEST_CONFIG;
import static com.newrelic.agent.config.SpanEventsConfig.SERVER_SPAN_HARVEST_LIMIT;

public class AgentConfigImpl extends BaseConfig implements AgentConfig {

    // root configs (alphabetized)
    public static final String AGENT_ENABLED = "agent_enabled";
    public static final String APDEX_T = "apdex_t";
    public static final String API_HOST = "api_host";
    public static final String API_PORT = "api_port";
    public static final String APP_NAME = "app_name";
    public static final String ASYNC_TIMEOUT = "async_timeout";
    public static final String CA_BUNDLE_PATH = "ca_bundle_path";
    public static final String COMPRESSED_CONTENT_ENCODING_PROPERTY = "compressed_content_encoding";
    public static final String CPU_SAMPLING_ENABLED = "cpu_sampling_enabled";
    public static final String ENABLED = "enabled";
    public static final String ENABLE_AUTO_APP_NAMING = "enable_auto_app_naming";
    public static final String ENABLE_AUTO_TRANSACTION_NAMING = "enable_auto_transaction_naming";
    public static final String ENABLE_BOOTSTRAP_CLASS_INSTRUMENTATION = "enable_bootstrap_class_instrumentation";
    public static final String ENABLE_CLASS_RETRANSFORMATION = "enable_class_retransformation";
    public static final String ENABLE_CUSTOM_TRACING = "enable_custom_tracing";
    public static final String EXT_CONFIG_DIR = "extensions.dir";
    public static final String HIGH_SECURITY = "high_security";
    public static final String HOST = "host";
    public static final String IBM_WORKAROUND = "ibm_iv25688_workaround";
    public static final String IGNORE_JARS = "ignore_jars";
    public static final String INSERT_API_KEY = "insert_api_key";
    public static final String JDBC_SUPPORT = "jdbc_support";
    public static final String LABELS = "labels";
    public static final String LANGUAGE = "language";
    public static final String LICENSE_KEY = "license_key";
    public static final String LITE_MODE = "lite_mode";
    public static final String LOG_DAILY = "log_daily";
    public static final String LOG_FILE_COUNT = "log_file_count";
    public static final String LOG_FILE_NAME = "log_file_name";
    public static final String LOG_FILE_PATH = "log_file_path";
    public static final String LOG_LEVEL = "log_level";
    public static final String LOG_LIMIT = "log_limit_in_kbytes";
    public static final String MAX_STACK_TRACE_LINES = "max_stack_trace_lines";
    public static final String METRIC_INGEST_URI = "metric_ingest_uri";
    public static final String EVENT_INGEST_URI = "event_ingest_uri";
    public static final String DEBUG = "newrelic.debug";
    public static final String METRIC_DEBUG = "metric_debug";
    public static final String PLATFORM_INFORMATION_ENABLED = "platform_information_enabled";
    public static final String PORT = "port";
    public static final String PROXY_HOST = "proxy_host";
    public static final String PROXY_PASS = "proxy_password";
    public static final String PROXY_PORT = "proxy_port";
    public static final String PROXY_SCHEME = "proxy_scheme";
    public static final String PROXY_USER = "proxy_user";
    public static final String PUT_FOR_DATA_SEND_PROPERTY = "put_for_data_send";
    public static final String REPORT_SQL_PARSER_ERRORS = "report_sql_parser_errors";
    public static final String LASP_TOKEN = "security_policies_token";
    public static final String SEND_DATA_ON_EXIT = "send_data_on_exit";
    public static final String SEND_DATA_ON_EXIT_THRESHOLD = "send_data_on_exit_threshold";
    public static final String SEND_ENVIRONMENT_INFO = "send_environment_info";
    public static final String SEND_JVM_PROPS = "send_jvm_props";
    public static final String SIMPLE_COMPRESSION_PROPERTY = "simple_compression";
    private static final String REQUEST_TIMEOUT_IN_SECONDS_PROPERTY = "timeout";
    public static final String STARTUP_LOG_LEVEL = "startup_log_level";
    public static final String STARTUP_TIMING = "startup_timing";
    public static final String STDOUT = "STDOUT";
    public static final String SYNC_STARTUP = "sync_startup";
    public static final String THREAD_CPU_TIME_ENABLED = "thread_cpu_time_enabled";
    public static final String TRACE_DATA_CALLS = "trace_data_calls";
    public static final String TRANSACTION_NAMING_SCHEME = "transaction_naming_scheme";
    public static final String TRANSACTION_SIZE_LIMIT = "transaction_size_limit";
    public static final String TRIM_STATS = "trim_stats";
    public static final String USE_PRIVATE_SSL = "use_private_ssl";
    public static final String WAIT_FOR_RPM_CONNECT = "wait_for_rpm_connect";
    public static final String WAIT_FOR_TRANSACTIONS = "wait_for_transactions";
    public static final String KEY_TRANSACTIONS = "web_transactions_apdex";

    // nested configs (alphabetized)
    public static final String ATTRIBUTES = "attributes";
    public static final String BROWSER_MONITORING = "browser_monitoring";
    public static final String CLASS_TRANSFORMER = "class_transformer";
    public static final String CROSS_APPLICATION_TRACER = "cross_application_tracer";
    public static final String CUSTOM_INSIGHT_EVENTS = "custom_insights_events";
    public static final String DATASTORE_TRACER = "datastore_tracer";
    public static final String DISTRIBUTED_TRACING = "distributed_tracing";
    public static final String ERROR_COLLECTOR = "error_collector";
    public static final String EXTENSIONS = "extensions";
    public static final String INSTRUMENTATION = "instrumentation";
    public static final String JAR_COLLECTOR = "jar_collector";
    public static final String JMX = "jmx";
    public static final String JFR = "jfr";
    public static final String OPEN_TRACING = "open_tracing";
    public static final String REINSTRUMENT = "reinstrument";
    public static final String SLOW_SQL = "slow_sql";
    public static final String SPAN_EVENTS = "span_events";
    public static final String STRIP_EXCEPTION_MESSAGES = "strip_exception_messages";
    public static final String THREAD_PROFILER = "thread_profiler";
    public static final String TRANSACTION_EVENTS = "transaction_events"; // replaces analytics_events
    public static final String TRANSACTION_SEGMENTS = "transaction_segments";
    public static final String TRANSACTION_TRACER = "transaction_tracer";

    // defaults (alphabetized)
    public static final double DEFAULT_APDEX_T = 1.0; // 1 second
    public static final String DEFAULT_API_HOST = "rpm.newrelic.com";
    public static final String DEFAULT_CA_BUNDLE_PATH = null;
    public static final String DEFAULT_COMPRESSED_CONTENT_ENCODING = DataSenderImpl.GZIP_ENCODING;
    public static final boolean DEFAULT_CPU_SAMPLING_ENABLED = true;
    public static final boolean DEFAULT_ENABLED = true;
    public static final boolean DEFAULT_ENABLE_AUTO_APP_NAMING = false;
    public static final boolean DEFAULT_ENABLE_AUTO_TRANSACTION_NAMING = true;
    public static final boolean DEFAULT_ENABLE_CUSTOM_TRACING = true;
    public static final boolean DEFAULT_HIGH_SECURITY = false;
    public static final boolean DEFAULT_METRIC_DEBUG = false;

    /*
     * If a customer wants to add a . to the end of their collector hostname to avoid one DNS lookup they can configure
     * host in newrelic.yml. This value makes the default behavior always work.
     */
    public static final String DEFAULT_HOST = "collector.newrelic.com";
    public static final boolean DEFAULT_IBM_WORKAROUND = IBMUtils.getIbmWorkaroundDefault();
    public static final String DEFAULT_INSERT_API_KEY = "";
    // jdbc support
    public static final String GENERIC_JDBC_SUPPORT = "generic";
    public static final String DEFAULT_JDBC_SUPPORT = GENERIC_JDBC_SUPPORT;
    public static final String DEFAULT_LANGUAGE = "java";
    public static final boolean DEFAULT_LOG_DAILY = false;
    public static final int DEFAULT_LOG_FILE_COUNT = 1;
    public static final String DEFAULT_LOG_FILE_NAME = "newrelic_agent.log";
    public static final String DEFAULT_LOG_LEVEL = "info";
    public static final int DEFAULT_LOG_LIMIT = 0;
    public static final int DEFAULT_MAX_STACK_TRACE_LINES = 30;
    public static final String DEFAULT_METRIC_INGEST_URI = "https://metric-api.newrelic.com/metric/v1";
    public static final String DEFAULT_EVENT_INGEST_URI = "https://insights-collector.newrelic.com/v1/accounts/events";
    public static final String EU_METRIC_INGEST_URI = "https://metric-api.eu.newrelic.com/metric/v1";
    public static final String EU_EVENT_INGEST_URI = "https://insights-collector.eu01.nr-data.net/v1/accounts/events";
    public static final boolean DEFAULT_PLATFORM_INFORMATION_ENABLED = true;
    public static final int DEFAULT_PORT = 80;
    public static final String DEFAULT_PROXY_HOST = null;
    public static final int DEFAULT_PROXY_PORT = 8080;
    public static final String DEFAULT_PROXY_SCHEME = null;
    public static final boolean DEFAULT_PUT_FOR_DATA_SEND_ENABLED = false;
    public static final String DEFAULT_SECURITY_POLICIES_TOKEN = "";
    public static final boolean DEFAULT_SEND_DATA_ON_EXIT = false;
    public static final int DEFAULT_SEND_DATA_ON_EXIT_THRESHOLD = 60;
    public static final boolean DEFAULT_SEND_ENVIRONMENT_INFO = true;
    public static final boolean DEFAULT_SIMPLE_COMPRESSION_ENABLED = false;
    public static final int DEFAULT_SSL_PORT = 443;
    public static final boolean DEFAULT_STARTUP_TIMING = true;
    public static final boolean DEFAULT_SYNC_STARTUP = false;
    public static final boolean DEFAULT_TRACE_DATA_CALLS = false;
    public static final int DEFAULT_TRANSACTION_SIZE_LIMIT = 2000;
    public static final boolean DEFAULT_TRIM_STATS = true;
    public static final boolean DEFAULT_WAIT_FOR_RPM_CONNECT = true;
    public static final int DEFAULT_WAIT_FOR_TRANSACTIONS = 0;
    private static final int DEFAULT_REQUEST_TIMEOUT_IN_SECONDS = 120;

    public static final String SYSTEM_PROPERTY_ROOT = "newrelic.config.";

    // per protocol 15+, region aware license keys must match this regex before constructing collector host
    public static final Pattern REGION_AWARE = Pattern.compile("^.+?x");

    // root configs (alphabetized)
    private final long apdexTInMillis;
    private final String appName;
    private final List appNames;
    private final boolean autoAppNamingEnabled;
    private final boolean autoTransactionNamingEnabled;
    private final String caBundlePath;
    private final String compressedContentEncoding;
    private final boolean cpuSamplingEnabled;
    private final boolean customInstrumentationEditorAllowed;
    private final boolean customParameters;
    private final boolean debug;
    private final boolean metricDebug;
    private final boolean enabled;
    private final boolean genericJdbcSupportEnabled;
    private final boolean highSecurity;
    private final String host;
    private final boolean ibmWorkaroundEnabled;
    private final List ignoreJars;
    private final String insertApiKey;
    private final boolean isApdexTSet;
    private final HashSet jdbcSupport;
    private final String licenseKey;
    private final boolean litemode;
    private final boolean logDaily;
    private final String logLevel;
    private final int maxStackTraceLines;
    private final String metricIngestUri;
    private final String eventIngestUri;
    private final boolean platformInformationEnabled;
    private final int port;
    private final String proxyHost;
    private final String proxyPass;
    private final Integer proxyPort;
    private final String proxyScheme;
    private final String proxyUser;
    private final boolean putForDataSend;
    private final int segmentTimeoutInSec;
    private final String securityPoliciesToken;
    private final boolean sendJvmProps;
    private final boolean simpleCompression;
    private final boolean startupTimingEnabled;
    private final int tokenTimeoutInSec;
    private final TransactionNamingScheme transactionNamingMode;
    private final int transactionSizeLimit;
    private final boolean trimStats;
    private final boolean waitForRPMConnect;
    private final int waitForTransactionsInMillis;
    private final int requestTimeoutInMillis;

    // nested configs (alphabetized)
    private final AttributesConfig attributesConfig;
    private final AuditModeConfig auditModeConfig;
    private final TransactionTracerConfigImpl backgroundTransactionTracerConfig;
    private final BrowserMonitoringConfig browserMonitoringConfig;
    private final ClassTransformerConfig classTransformerConfig;
    private final CircuitBreakerConfig circuitBreakerConfig;
    private final CrossProcessConfig crossProcessConfig;
    private final DatastoreConfig datastoreConfig;
    private final DistributedTracingConfig distributedTracingConfig;
    private final ErrorCollectorConfig errorCollectorConfig;
    private final ExtensionsConfig extensionsConfig;
    private final ExternalTracerConfig externalTracerConfig;
    private final InfiniteTracingConfig infiniteTracingConfig;
    private final InsightsConfig insightsConfig;
    private final Config instrumentationConfig;
    private final JarCollectorConfig jarCollectorConfig;
    private final JfrConfig jfrConfig;
    private final JmxConfig jmxConfig;
    private final KeyTransactionConfig keyTransactionConfig;
    private final LabelsConfig labelsConfig;
    private final NormalizationRuleConfig normalizationRuleConfig;
    private final OpenTracingConfig openTracingConfig;
    private final ReinstrumentConfig reinstrumentConfig;
    private final TransactionTracerConfigImpl requestTransactionTracerConfig;
    private final SpanEventsConfig spanEventsConfig;
    private final SqlTraceConfig sqlTraceConfig;
    private final StripExceptionConfig stripExceptionConfig;
    private final ThreadProfilerConfig threadProfilerConfig;
    private final TransactionEventsConfig transactionEventsConfig;
    private final TransactionTracerConfigImpl transactionTracerConfig;
    private final UtilizationDataConfig utilizationConfig;

    private final Map flattenedProperties;
    private final CommandParserConfig commandParserConfig;

    public static AgentConfig createAgentConfig(Map settings) {
        if (settings == null) {
            settings = Collections.emptyMap();
        }
        return new AgentConfigImpl(settings);
    }

    private AgentConfigImpl(Map props) {
        super(props, SYSTEM_PROPERTY_ROOT);
        // transaction_tracer.record_sql, request atts, and message atts are all affected by high security
        highSecurity = getProperty(HIGH_SECURITY, DEFAULT_HIGH_SECURITY);
        securityPoliciesToken = getProperty(LASP_TOKEN, DEFAULT_SECURITY_POLICIES_TOKEN);
        simpleCompression = getProperty(SIMPLE_COMPRESSION_PROPERTY, DEFAULT_SIMPLE_COMPRESSION_ENABLED);
        compressedContentEncoding = initCompressedContentEncoding();
        putForDataSend = getProperty(PUT_FOR_DATA_SEND_PROPERTY, DEFAULT_PUT_FOR_DATA_SEND_ENABLED);
        isApdexTSet = getProperty(APDEX_T) != null;
        apdexTInMillis = (long) (getDoubleProperty(APDEX_T, DEFAULT_APDEX_T) * 1000L);
        debug = Boolean.getBoolean(DEBUG);
        metricDebug = initMetricDebugConfig();
        enabled = getProperty(ENABLED, DEFAULT_ENABLED) && getProperty(AGENT_ENABLED, DEFAULT_ENABLED);
        licenseKey = getProperty(LICENSE_KEY);
        String region = parseRegion(licenseKey);
        host = parseHost(region);
        metricIngestUri = parseMetricIngestUri(region);
        eventIngestUri = parseEventIngestUri(region);
        ignoreJars = new ArrayList<>(getUniqueStrings(IGNORE_JARS, COMMA_SEPARATOR));
        insertApiKey = getProperty(INSERT_API_KEY, DEFAULT_INSERT_API_KEY);
        logLevel = initLogLevel();
        logDaily = getProperty(LOG_DAILY, DEFAULT_LOG_DAILY);
        port = getIntProperty(PORT, DEFAULT_SSL_PORT);
        proxyHost = getProperty(PROXY_HOST, DEFAULT_PROXY_HOST);
        proxyPort = getIntProperty(PROXY_PORT, DEFAULT_PROXY_PORT);
        proxyScheme = getProperty(PROXY_SCHEME, DEFAULT_PROXY_SCHEME);
        proxyUser = getStringPropertyOrNull(PROXY_USER);
        proxyPass = getStringPropertyOrNull(PROXY_PASS);
        appNames = new ArrayList<>(getUniqueStrings(APP_NAME, SEMI_COLON_SEPARATOR));
        appName = getPrimaryAppName();
        cpuSamplingEnabled = getProperty(CPU_SAMPLING_ENABLED, DEFAULT_CPU_SAMPLING_ENABLED);
        autoAppNamingEnabled = getProperty(ENABLE_AUTO_APP_NAMING, DEFAULT_ENABLE_AUTO_APP_NAMING);
        autoTransactionNamingEnabled = getProperty(ENABLE_AUTO_TRANSACTION_NAMING, DEFAULT_ENABLE_AUTO_TRANSACTION_NAMING);
        transactionSizeLimit = getIntProperty(TRANSACTION_SIZE_LIMIT, DEFAULT_TRANSACTION_SIZE_LIMIT) * 1024;
        waitForRPMConnect = getProperty(WAIT_FOR_RPM_CONNECT, DEFAULT_WAIT_FOR_RPM_CONNECT);
        startupTimingEnabled = getProperty(STARTUP_TIMING, DEFAULT_STARTUP_TIMING);
        sendJvmProps = getProperty(SEND_JVM_PROPS, true);
        litemode = getProperty(LITE_MODE, false);
        caBundlePath = initSSLConfig();
        trimStats = getProperty(TRIM_STATS, DEFAULT_TRIM_STATS);
        platformInformationEnabled = getProperty(PLATFORM_INFORMATION_ENABLED, DEFAULT_PLATFORM_INFORMATION_ENABLED);
        ibmWorkaroundEnabled = getProperty(IBM_WORKAROUND, DEFAULT_IBM_WORKAROUND);
        transactionNamingMode = parseTransactionNamingMode();
        maxStackTraceLines = getProperty(MAX_STACK_TRACE_LINES, DEFAULT_MAX_STACK_TRACE_LINES);
        String[] jdbcSupport = getProperty(JDBC_SUPPORT, DEFAULT_JDBC_SUPPORT).split(",");
        this.jdbcSupport = new HashSet<>(Arrays.asList(jdbcSupport));
        genericJdbcSupportEnabled = this.jdbcSupport.contains(GENERIC_JDBC_SUPPORT);
        requestTimeoutInMillis = getProperty(REQUEST_TIMEOUT_IN_SECONDS_PROPERTY, DEFAULT_REQUEST_TIMEOUT_IN_SECONDS) * 1000;
        instrumentationConfig = new BaseConfig(nestedProps(INSTRUMENTATION), SYSTEM_PROPERTY_ROOT + INSTRUMENTATION);
        transactionTracerConfig = initTransactionTracerConfig(apdexTInMillis, highSecurity);
        requestTransactionTracerConfig = transactionTracerConfig.createRequestTransactionTracerConfig(apdexTInMillis, highSecurity);
        backgroundTransactionTracerConfig = transactionTracerConfig.createBackgroundTransactionTracerConfig(apdexTInMillis, highSecurity);
        errorCollectorConfig = initErrorCollectorConfig();
        extensionsConfig = initExtensionsConfig();
        threadProfilerConfig = initThreadProfilerConfig();
        keyTransactionConfig = initKeyTransactionConfig(apdexTInMillis);
        sqlTraceConfig = initSqlTraceConfig();
        auditModeConfig = initAuditModeConfig();
        browserMonitoringConfig = initBrowserMonitoringConfig();
        classTransformerConfig = initClassTransformerConfig(litemode);
        crossProcessConfig = initCrossProcessConfig();
        stripExceptionConfig = initStripExceptionConfig(highSecurity);
        labelsConfig = new LabelsConfigImpl(getProperty(LABELS));
        utilizationConfig = initUtilizationConfig();
        datastoreConfig = initDatastoreConfig();
        externalTracerConfig = initExternalTracerConfig();
        jfrConfig = initJfrConfig();
        jmxConfig = initJmxConfig();
        jarCollectorConfig = initJarCollectorConfig();
        insightsConfig = initInsightsConfig();
        infiniteTracingConfig = initInfiniteTracingConfig(autoAppNamingEnabled);
        attributesConfig = initAttributesConfig();
        reinstrumentConfig = initReinstrumentConfig();
        circuitBreakerConfig = initCircuitBreakerConfig();
        segmentTimeoutInSec = initSegmentTimeout();
        tokenTimeoutInSec = initTokenTimeout();
        openTracingConfig = initOpenTracingConfig();
        distributedTracingConfig = initDistributedTracing();
        spanEventsConfig = initSpanEventsConfig(distributedTracingConfig.isEnabled());
        transactionEventsConfig = initTransactionEvents();
        commandParserConfig = initCommandParserConfig();
        normalizationRuleConfig = new NormalizationRuleConfig(props);

        Map flattenedProps = new HashMap<>();
        flatten("", props, flattenedProps);
        Map propsWithSystemProps = new HashMap<>();
        propsWithSystemProps.putAll(SystemPropertyFactory.getSystemPropertyProvider().getNewRelicPropertiesWithoutPrefix());
        propsWithSystemProps.putAll(SystemPropertyFactory.getSystemPropertyProvider().getNewRelicEnvVarsWithoutPrefix());
        flatten("", propsWithSystemProps, flattenedProps);
        checkHighSecurityPropsInFlattened(flattenedProps);
        setServerSpanHarvestLimit();
        this.flattenedProperties = Collections.unmodifiableMap(flattenedProps);
        this.waitForTransactionsInMillis = getProperty(WAIT_FOR_TRANSACTIONS, DEFAULT_WAIT_FOR_TRANSACTIONS);
        this.customInstrumentationEditorAllowed = getProperty(LaspPolicies.LASP_CUSTOM_INSTRUMENTATION_EDITOR, !highSecurity);
        this.customParameters = getProperty(LaspPolicies.LASP_CUSTOM_PARAMETERS, !highSecurity);

        if (getProperty(REPORT_SQL_PARSER_ERRORS) != null) {
            addDeprecatedProperty(new String[] { REPORT_SQL_PARSER_ERRORS }, null);
        }
    }

    private String initSSLConfig() {
        String caBundlePath = getProperty(CA_BUNDLE_PATH, DEFAULT_CA_BUNDLE_PATH);
        if (getProperty(USE_PRIVATE_SSL) != null) {
            if (caBundlePath != null) {
                Agent.LOG.log(Level.INFO, "use_private_ssl configuration setting has been removed.");
            } else {
                Agent.LOG.log(Level.SEVERE,
                        "The use_private_ssl configuration setting has been removed and will be ignored. The agent will use the JVM/JRE truststore by default unless you configure ca_bundle_path to use a different truststore.");
            }
        }
        return caBundlePath;
    }

    /**
     * The license key is hex encoded, so if it contains an 'x' then it must be protocol 15+, which means the first
     * 6 characters are the region. Format is: [A-Z]{2,3}[0-9]{2} with 'x' padding until it's 6 characters long.
     * The spec only requires it to pass the regex, and not to check length requirements, to maintain flexibility.
     */
    private String parseRegion(String licenseKey) {
        if (licenseKey != null) {
            licenseKey = licenseKey.toLowerCase();
            if (REGION_AWARE.matcher(licenseKey).find()) {
                return licenseKey.substring(0, licenseKey.indexOf("x")); // don't include the x's
            }
        }
        return "";
    }

    /**
     * If host was set explicitly, then always use it and don't construct the collector host from the region parsed from the
     * license key. If the license key doesn't conform to protocol 15+, then return the default host, otherwise construct the
     * new host using the region section of the license key.
     */
    private String parseHost(String region) {
        String host = getProperty(HOST);
        if (host != null) {
            Agent.LOG.log(Level.INFO, "Using configured collector host: {0}", host);
            return host;
        }

        if (region.isEmpty()) {
            Agent.LOG.log(Level.INFO, "Using default collector host: {0}", DEFAULT_HOST);
            return DEFAULT_HOST;
        }

        host = "collector." + region + ".nr-data.net";
        Agent.LOG.log(Level.INFO, "Using region aware collector host: {0}", host);

        return host;
    }

    /**
     * If metric ingest URI was set explicitly, then always use it and don't construct the metric ingest URI from the region parsed from the
     * license key. If the license key doesn't conform to protocol 15+, then return the default metric ingest URI, otherwise construct the
     * new metric ingest URI using the region section of the license key.
     *
     * US Prod metric ingest URI: https://metric-api.newrelic.com/metric/v1
     * EU Prod metric ingest URI: https://metric-api.eu.newrelic.com/metric/v1
     */
    private String parseMetricIngestUri(String region) {
        String metricIngestUri = getProperty(METRIC_INGEST_URI);
        if (metricIngestUri != null) {
            Agent.LOG.log(Level.INFO, "Using configured metric ingest URI: {0}", metricIngestUri);
            return metricIngestUri;
        }

        if (region.isEmpty()) {
            Agent.LOG.log(Level.INFO, "Using default metric ingest URI: {0}", DEFAULT_METRIC_INGEST_URI);
            return DEFAULT_METRIC_INGEST_URI;
        }

        if (region.toLowerCase().contains("eu")) {
            Agent.LOG.log(Level.INFO, "Using region aware metric ingest URI: {0}", EU_METRIC_INGEST_URI);
            return EU_METRIC_INGEST_URI;
        }

        Agent.LOG.log(Level.INFO,
                "Unrecognized region parsed from license_key, please explicitly set the {0} property. Currently using default metric ingest URI: {1}",
                METRIC_INGEST_URI, DEFAULT_METRIC_INGEST_URI);
        return DEFAULT_METRIC_INGEST_URI;
    }

    /**
     * If event ingest URI was set explicitly, then always use it and don't construct the event ingest URI from the region parsed from the
     * license key. If the license key doesn't conform to protocol 15+, then return the default event ingest URI, otherwise construct the
     * new event ingest URI using the region section of the license key.
     *
     * US Prod event ingest URI: https://insights-collector.newrelic.com/v1/accounts/events
     * EU Prod event ingest URI: https://insights-collector.eu01.nr-data.net/v1/accounts/events
     */
    private String parseEventIngestUri(String region) {
        String eventIngestUri = getProperty(EVENT_INGEST_URI);
        if (eventIngestUri != null) {
            Agent.LOG.log(Level.INFO, "Using configured event ingest URI: {0}", eventIngestUri);
            return eventIngestUri;
        }

        if (region.isEmpty()) {
            Agent.LOG.log(Level.INFO, "Using default event ingest URI: {0}", DEFAULT_EVENT_INGEST_URI);
            return DEFAULT_EVENT_INGEST_URI;
        }

        if (region.toLowerCase().contains("eu")) {
            Agent.LOG.log(Level.INFO, "Using region aware event ingest URI: {0}", EU_EVENT_INGEST_URI);
            return EU_EVENT_INGEST_URI;
        }

        Agent.LOG.log(Level.INFO,
                "Unrecognized region parsed from license_key, please explicitly set the {0} property. Currently using default event ingest URI: {1}",
                EVENT_INGEST_URI, DEFAULT_EVENT_INGEST_URI);
        return DEFAULT_EVENT_INGEST_URI;
    }

    private OpenTracingConfig initOpenTracingConfig() {
        Map openTracing = nestedProps(OPEN_TRACING);
        return new OpenTracingConfig(openTracing);
    }

    private DistributedTracingConfig initDistributedTracing() {
        Map distributedTracing = nestedProps(DISTRIBUTED_TRACING);
        return new DistributedTracingConfig(distributedTracing);
    }

    private SpanEventsConfig initSpanEventsConfig(boolean dtEnabled) {
        Map spanEvents = nestedProps(SPAN_EVENTS);
        return new SpanEventsConfig(spanEvents, dtEnabled);
    }

    private int initTokenTimeout() {
        if (getProperty(ASYNC_TIMEOUT) != null) {
            Agent.LOG.log(Level.INFO, "The property async_timeout is deprecated. Change to token_timeout");
            return getProperty("async_timeout", 180);
        }

        return getProperty("token_timeout", 180);
    }

    private int initSegmentTimeout() {
        // Segment API was previously known as TracedActivity.
        if (getProperty("traced_activity_timeout") != null) {
            Agent.LOG.log(Level.INFO, "The property traced_activity_timeout is deprecated. Change to segment_timeout");
            return getProperty("traced_activity_timeout", 10 * 60);
        }

        return getProperty("segment_timeout", 10 * 60);
    }

    private TransactionNamingScheme parseTransactionNamingMode() {
        TransactionNamingScheme mode = TransactionNamingScheme.LEGACY;

        String mode_name = getProperty(TRANSACTION_NAMING_SCHEME, "legacy");

        if (mode_name.equals("resource_based")) {
            mode = TransactionNamingScheme.RESOURCE_BASED;
        }

        return mode;
    }

    /*
     * This is here just in case someone uses get value to retrieve one of the properties which has been changed due to
     * high security.
     */
    private void checkHighSecurityPropsInFlattened(Map flattenedProps) {
        if (highSecurity && !flattenedProps.isEmpty()) {
            flattenedProps.put("transaction_tracer.record_sql", transactionTracerConfig.getRecordSql());
        }
    }

    private boolean initMetricDebugConfig() {
        Object val = getProperty(METRIC_DEBUG);
        if (val instanceof Boolean && (Boolean) val) {
            Agent.LOG.log(Level.INFO, "metric_debug is enabled");
        }
        return getProperty(METRIC_DEBUG, DEFAULT_METRIC_DEBUG);
    }

    private void setServerSpanHarvestLimit() {
        Map spanEventHarvestLimits = getProperty(SERVER_SPAN_HARVEST_CONFIG);
        if (spanEventHarvestLimits != null) {
            Long harvestLimit = (Long) spanEventHarvestLimits.get(SERVER_SPAN_HARVEST_LIMIT);
            spanEventsConfig.setMaxSamplesStoredByServerProp(harvestLimit.intValue());
        }
    }

    @SuppressWarnings("unchecked")
    private void flatten(String prefix, Map source, Map dest) {
        for (Map.Entry e : source.entrySet()) {
            if (e.getValue() instanceof Map) {
                flatten(prefix + e.getKey() + '.', (Map) e.getValue(), dest);
            } else {
                Object destinationValue = dest.get(prefix + e.getKey());
                if (!(destinationValue instanceof ServerProp)) {
                    dest.put(prefix + e.getKey(), e.getValue());
                }
            }
        }
    }

    @Override
    public  T getValue(String path) {
        return getValue(path, null);
    }

    @Override
    @SuppressWarnings("unchecked")
    public  T getValue(String path, T defaultValue) {
        Object value = flattenedProperties.get(path.replaceAll("[.-]", "_"));
        if (value == null) {
            value = flattenedProperties.get(path);
        }

        if (value == null) {
            return defaultValue;
        } else if (value instanceof ServerProp) {
            value = ((ServerProp) value).getValue();
            return castValue(path, value, defaultValue);
        } else if (value instanceof String && defaultValue instanceof Boolean) {
            // As noted below, the YAML parser interprets "on" as true and "off" as false.
            // It's unclear whether we should accept the strings "on" and "off" here.
            value = Boolean.valueOf((String) value);
            return (T) value;
        } else if (value instanceof String && defaultValue instanceof Integer) {
            value = Integer.valueOf((String) value);
            return (T) value;
        } else {
            try {
                return (T) value;
            } catch (ClassCastException ccx) {
                Agent.LOG.log(Level.FINE, "Using default value \"{0}\" for \"{1}\"", defaultValue, path);
                return defaultValue;
            }
        }
    }

    // even though getProperty returns `T` (here a String), that's a compile-time check.
    // Java generics at runtime allow any return value since it's only assigned to an Object.
    @SuppressWarnings("ConstantConditions")
    private String initLogLevel() {
        Object val = getProperty(LOG_LEVEL, DEFAULT_LOG_LEVEL);
        if (val instanceof Boolean) {
            // the YAML parser interprets "on" as true and "off" as false
            return "off";
        }
        return getProperty(LOG_LEVEL, DEFAULT_LOG_LEVEL).toLowerCase();
    }

    private String getPrimaryAppName() {
        Object val = getProperty(APP_NAME);
        if (val instanceof String) {
            String[] values = ((String) val).split(SEMI_COLON_SEPARATOR);
            if (values.length == 0) {
                return null;
            }
            String res = values[0].trim();
            if (res.length() == 0) {
                return null;
            }
            return res;
        }
        if (val instanceof Collection) {
            Collection values = (Collection) val;
            for (Object value : values) {
                String res = (String) value;
                res = res.trim();
                if (res.length() != 0) {
                    return res;
                }
                return null;
            }
        }
        return null;
    }

    private CrossProcessConfig initCrossProcessConfig() {
        Boolean prop = getProperty(CrossProcessConfigImpl.CROSS_APPLICATION_TRACING);
        Map props = nestedProps(CROSS_APPLICATION_TRACER);
        if (prop != null) {
            if (props == null) {
                props = new HashMap<>();
            }
            props.put(CrossProcessConfigImpl.CROSS_APPLICATION_TRACING, prop);
        }
        return CrossProcessConfigImpl.createCrossProcessConfig(props);
    }

    private StripExceptionConfig initStripExceptionConfig(boolean highSecurity) {
        Map props = nestedProps(STRIP_EXCEPTION_MESSAGES);
        return StripExceptionConfigImpl.createStripExceptionConfig(props, highSecurity);
    }

    private ThreadProfilerConfig initThreadProfilerConfig() {
        Map props = nestedProps(THREAD_PROFILER);
        return ThreadProfilerConfigImpl.createThreadProfilerConfig(props);
    }

    private KeyTransactionConfig initKeyTransactionConfig(long apdexTInMillis) {
        Map props = nestedProps(KEY_TRANSACTIONS);
        return KeyTransactionConfigImpl.createKeyTransactionConfig(props, apdexTInMillis);
    }

    private TransactionTracerConfigImpl initTransactionTracerConfig(long apdexTInMillis, boolean highSecurity) {
        Map props = nestedProps(TRANSACTION_TRACER);
        return TransactionTracerConfigImpl.createTransactionTracerConfig(props, apdexTInMillis, highSecurity);
    }

    private ErrorCollectorConfig initErrorCollectorConfig() {
        Map props = nestedProps(ERROR_COLLECTOR);
        return ErrorCollectorConfigImpl.createErrorCollectorConfig(props);
    }

    private ExtensionsConfig initExtensionsConfig() {
        Map props = nestedProps(EXTENSIONS);
        return ExtensionsConfigImpl.createExtensionsConfig(props);
    }

    private SqlTraceConfig initSqlTraceConfig() {
        Map props = nestedProps(SLOW_SQL);
        SqlTraceConfig sqlTraceConfig = SqlTraceConfigImpl.createSqlTraceConfig(props);
        if (sqlTraceConfig.isUsingLongerSqlId()) {
            Agent.LOG.info("Agent is configured to use longer sql id for sql traces");
        }
        return sqlTraceConfig;
    }

    private JfrConfig initJfrConfig() {
        Map props = nestedProps(JFR);
        return JfrConfigImpl.createJfrConfig(props);
    }

    private JmxConfig initJmxConfig() {
        Map props = nestedProps(JMX);
        return JmxConfigImpl.createJmxConfig(props);
    }

    private JarCollectorConfig initJarCollectorConfig() {
        Map props = nestedProps(JAR_COLLECTOR);
        return JarCollectorConfigImpl.createJarCollectorConfig(props);
    }

    private InsightsConfig initInsightsConfig() {
        Map props = nestedProps(CUSTOM_INSIGHT_EVENTS);
        return InsightsConfigImpl.createInsightsConfig(props, highSecurity);
    }

    private AttributesConfig initAttributesConfig() {
        Map props = nestedProps(ATTRIBUTES);
        return AttributesConfigImpl.createAttributesConfig(props);
    }

    private ReinstrumentConfig initReinstrumentConfig() {
        Map props = nestedProps(REINSTRUMENT);
        return ReinstrumentConfigImpl.createReinstrumentConfig(props);
    }

    private AuditModeConfig initAuditModeConfig() {
        Object auditMode = getProperty(AuditModeConfig.PROPERTY_NAME);

        if (auditMode instanceof Map) {
            // New, nested "audit_mode:" property
            Map props = nestedProps(AuditModeConfig.PROPERTY_NAME);
            return new AuditModeConfig(props);
        } else {
            // This is the "legacy" case where "audit_mode: true" is it's own single-level config property
            boolean auditModeEnabled = getProperty(AuditModeConfig.PROPERTY_NAME, AuditModeConfig.DEFAULT_ENABLED);
            boolean traceDataCalls = getProperty(TRACE_DATA_CALLS, DEFAULT_TRACE_DATA_CALLS);
            return new AuditModeConfig(auditModeEnabled, traceDataCalls);
        }
    }

    private BrowserMonitoringConfig initBrowserMonitoringConfig() {
        Map props = nestedProps(BROWSER_MONITORING);
        return BrowserMonitoringConfigImpl.createBrowserMonitoringConfig(props);
    }

    private ClassTransformerConfig initClassTransformerConfig(boolean liteMode) {
        boolean customTracingEnabled = getProperty(ENABLE_CUSTOM_TRACING, DEFAULT_ENABLE_CUSTOM_TRACING);
        Map props = nestedProps(CLASS_TRANSFORMER);
        return ClassTransformerConfigImpl.createClassTransformerConfig(props, customTracingEnabled, liteMode);
    }

    private CircuitBreakerConfig initCircuitBreakerConfig() {
        Map props = nestedProps(CircuitBreakerConfig.PROPERTY_NAME);
        return new CircuitBreakerConfig(props);
    }

    private UtilizationDataConfig initUtilizationConfig() {
        Map props = nestedProps(UtilizationDataConfig.PROPERTY_NAME);
        return new UtilizationDataConfig(props);
    }

    private DatastoreConfig initDatastoreConfig() {
        Map props = nestedProps(DatastoreConfigImpl.PROPERTY_NAME);
        return new DatastoreConfigImpl(props);
    }

    private ExternalTracerConfig initExternalTracerConfig() {
        Map props = nestedProps(ExternalTracerConfigImpl.PROPERTY_NAME);
        return new ExternalTracerConfigImpl(props);
    }

    private InfiniteTracingConfig initInfiniteTracingConfig(boolean autoAppNamingEnabled) {
        Map props = nestedProps(InfiniteTracingConfigImpl.ROOT);
        return new InfiniteTracingConfigImpl(props, autoAppNamingEnabled);
    }

    private TransactionEventsConfig initTransactionEvents() {
        Map transactionEvents = nestedProps(TRANSACTION_EVENTS);
        return new TransactionEventsConfig(transactionEvents);
    }

    private String initCompressedContentEncoding() {
        // The only available configuration options are gzip and deflate
        if (DataSenderImpl.DEFLATE_ENCODING.equals(getProperty(COMPRESSED_CONTENT_ENCODING_PROPERTY))) {
            return DataSenderImpl.DEFLATE_ENCODING;
        }
        return DEFAULT_COMPRESSED_CONTENT_ENCODING;
    }

    private CommandParserConfig initCommandParserConfig() {
        return new CommandParserConfigImpl(nestedProps(CommandParserConfigImpl.ROOT));
    }

    @Override
    public long getApdexTInMillis() {
        return apdexTInMillis;
    }

    @Override
    public long getApdexTInMillis(String transactionName) {
        return keyTransactionConfig.getApdexTInMillis(transactionName);
    }

    @Override
    public boolean isApdexTSet() {
        return isApdexTSet;
    }

    @Override
    public boolean isApdexTSet(String transactionName) {
        return keyTransactionConfig.isApdexTSet(transactionName);
    }

    @Override
    public boolean isAgentEnabled() {
        return enabled;
    }

    @Override
    public String getLicenseKey() {
        return licenseKey;
    }

    @Override
    public int getTimeoutInMilliseconds() {
        return requestTimeoutInMillis;
    }

    @Override
    public String getHost() {
        return host;
    }

    @Override
    public int getPort() {
        return port;
    }

    @Override
    public String getProxyHost() {
        return proxyHost;
    }

    @Override
    public Integer getProxyPort() {
        return proxyPort;
    }

    @Override
    public String getProxyScheme() {
        return proxyScheme;
    }

    @Override
    public String getProxyUser() {
        return proxyUser;
    }

    @Override
    public String getProxyPassword() {
        return proxyPass;
    }

    @Override
    public String getApiHost() {
        return getProperty(API_HOST, DEFAULT_API_HOST);
    }

    @Override
    public int getApiPort() {
        return getProperty(API_PORT, DEFAULT_SSL_PORT);
    }

    @Override
    public String getInsertApiKey() {
        return insertApiKey;
    }

    @Override
    public String getApplicationName() {
        return appName;
    }

    @Override
    public List getApplicationNames() {
        return appNames;
    }

    @Override
    public boolean isCpuSamplingEnabled() {
        return cpuSamplingEnabled;
    }

    @Override
    public boolean isAutoAppNamingEnabled() {
        return autoAppNamingEnabled;
    }

    @Override
    public boolean isAutoTransactionNamingEnabled() {
        return autoTransactionNamingEnabled;
    }

    @Override
    public boolean isDebugEnabled() {
        return debug;
    }

    @Override
    public boolean isDebugEnabled(String key) {
        return getProperty(key + "_debug", false);
    }

    @Override
    public String getLanguage() {
        return getProperty(LANGUAGE, DEFAULT_LANGUAGE);
    }

    @Override
    public boolean isSendDataOnExit() {
        return getProperty(SEND_DATA_ON_EXIT, DEFAULT_SEND_DATA_ON_EXIT);
    }

    @Override
    public long getSendDataOnExitThresholdInMillis() {
        int valueInSecs = getIntProperty(SEND_DATA_ON_EXIT_THRESHOLD, DEFAULT_SEND_DATA_ON_EXIT_THRESHOLD);
        return TimeUnit.MILLISECONDS.convert(valueInSecs, TimeUnit.SECONDS);
    }

    @Override
    public boolean isAuditMode() {
        return auditModeConfig.isEnabled();
    }

    @Override
    public AuditModeConfig getAuditModeConfig() {
        return auditModeConfig;
    }

    @Override
    public boolean liteMode() {
        return litemode;
    }

    @Override
    public int getSegmentTimeoutInSec() {
        return segmentTimeoutInSec;
    }

    @Override
    public int getTokenTimeoutInSec() {
        return tokenTimeoutInSec;
    }

    @Override
    public int waitForTransactionsInMillis() {
        return waitForTransactionsInMillis;
    }

    @Override
    public boolean laspEnabled() {
        return !securityPoliciesToken.isEmpty();
    }

    @Override
    public String securityPoliciesToken() {
        return securityPoliciesToken;
    }

    @Override
    public boolean isCustomInstrumentationEditorAllowed() {
        return customInstrumentationEditorAllowed;
    }

    @Override
    public boolean isCustomParametersAllowed() {
        return customParameters;
    }

    @Override
    public DistributedTracingConfig getDistributedTracingConfig() {
        return distributedTracingConfig;
    }

    @Override
    public ExtensionsConfig getExtensionsConfig() {
        return extensionsConfig;
    }

    @Override
    public SpanEventsConfig getSpanEventsConfig() {
        return spanEventsConfig;
    }

    @Override
    public CommandParserConfig getCommandParserConfig() {
        return commandParserConfig;
    }

    @Override
    public InfiniteTracingConfig getInfiniteTracingConfig() {
        return infiniteTracingConfig;
    }

    private Object findPropertyInMap(String[] property, Map map) {
        Object result = map;
        for (String component : property) {
            if (result == null) {
                break;
            }
            if (result instanceof Map) {
                Map resultMap = (Map) result;
                result = resultMap.getOrDefault(component, null);
            }
        }

        return result;
    }

    @Override
    public List logDeprecatedProperties(Map localSettings) {
        List messages = new LinkedList<>();
        Joiner stringJoiner = Joiner.on(".");
        for (DeprecatedProperty deprecatedProperty : deprecatedProperties.values()) {
            String joinedName = stringJoiner.join(deprecatedProperty.propertyName);

            String format = "Configuration {0} is deprecated and will be removed in the next major version.";
            if (getPropertyFromSystemEnvironment(joinedName, null) != null) {
                format += " It was set in the environment.";
            } else if (getPropertyFromSystemProperties(joinedName, null) != null) {
                format += " It was set as a system property.";
            } else if (findPropertyInMap(deprecatedProperty.propertyName, localSettings) != null) {
                format += " It was set in the configuration file.";
            } else {
                // value was not set, so no need to warn the user.
                continue;
            }

            if (deprecatedProperty.newPropertyName != null) {
                format += " Use " + stringJoiner.join(deprecatedProperty.newPropertyName) + " instead.";
            } else {
                format += " This property is obsolete.";
            }

            messages.add(MessageFormat.format(format, joinedName));
        }
        for (String message : messages) {
            Agent.LOG.log(Level.WARNING, message);
        }

        // We logged them once on startup; we don't need to do this again when merging server config.
        clearDeprecatedProperties();
        addDeprecatedProperties = false;
        return messages;
    }

    @Override
    public int getTransactionSizeLimit() {
        return transactionSizeLimit;
    }

    @Override
    public boolean waitForRPMConnect() {
        return waitForRPMConnect;
    }

    @Override
    public boolean isSyncStartup() {
        return getProperty(SYNC_STARTUP, DEFAULT_SYNC_STARTUP);
    }

    @Override
    public boolean isSendEnvironmentInfo() {
        return getProperty(SEND_ENVIRONMENT_INFO, DEFAULT_SEND_ENVIRONMENT_INFO);
    }

    @Override
    public boolean isLoggingToStdOut() {
        String logFileName = getLogFileName();
        return STDOUT.equalsIgnoreCase(logFileName);
    }

    @Override
    public int getLogFileCount() {
        return getIntProperty(LOG_FILE_COUNT, DEFAULT_LOG_FILE_COUNT);
    }

    @Override
    public String getLogFileName() {
        return getProperty(LOG_FILE_NAME, DEFAULT_LOG_FILE_NAME);
    }

    @Override
    public String getLogFilePath() {
        return getProperty(LOG_FILE_PATH);
    }

    @Override
    public String getLogLevel() {
        return logLevel;
    }

    @Override
    public int getLogLimit() {
        return getIntProperty(LOG_LIMIT, DEFAULT_LOG_LIMIT);
    }

    @Override
    public TransactionTracerConfig getTransactionTracerConfig() {
        return transactionTracerConfig;
    }

    @Override
    public TransactionTracerConfig getBackgroundTransactionTracerConfig() {
        return backgroundTransactionTracerConfig;
    }

    @Override
    public TransactionTracerConfig getRequestTransactionTracerConfig() {
        return requestTransactionTracerConfig;
    }

    @Override
    public ErrorCollectorConfig getErrorCollectorConfig() {
        return errorCollectorConfig;
    }

    @Override
    public SqlTraceConfig getSqlTraceConfig() {
        return sqlTraceConfig;
    }

    @Override
    public CrossProcessConfig getCrossProcessConfig() {
        return crossProcessConfig;
    }

    @Override
    public ThreadProfilerConfig getThreadProfilerConfig() {
        return threadProfilerConfig;
    }

    @Override
    public JfrConfig getJfrConfig() {
        return jfrConfig;
    }

    @Override
    public JmxConfig getJmxConfig() {
        return jmxConfig;
    }

    @Override
    public JarCollectorConfig getJarCollectorConfig() {
        return jarCollectorConfig;
    }

    @Override
    public InsightsConfig getInsightsConfig() {
        return insightsConfig;
    }

    @Override
    public AttributesConfig getAttributesConfig() {
        return attributesConfig;
    }

    @Override
    public ReinstrumentConfig getReinstrumentConfig() {
        return reinstrumentConfig;
    }

    @Override
    public BrowserMonitoringConfig getBrowserMonitoringConfig() {
        return browserMonitoringConfig;
    }

    @Override
    public ClassTransformerConfig getClassTransformerConfig() {
        return classTransformerConfig;
    }

    /**
     * Returns the jars which should be ignored.
     */
    @Override
    public List getIgnoreJars() {
        return ignoreJars;
    }

    /**
     * Gets the field obfuscateJvmProps.
     *
     * @return the obfuscateJvmProps
     */
    @Override
    public boolean isSendJvmProps() {
        return sendJvmProps;
    }

    @Override
    public String getCaBundlePath() {
        return caBundlePath;
    }

    @Override
    public boolean isLogDaily() {
        return logDaily;
    }

    @Override
    public boolean isTrimStats() {
        return trimStats;
    }

    @Override
    public boolean isPlatformInformationEnabled() {
        return platformInformationEnabled;
    }

    @Override
    public Set getJDBCSupport() {
        return jdbcSupport;
    }

    @Override
    public boolean isGenericJDBCSupportEnabled() {
        return genericJdbcSupportEnabled;
    }

    @Override
    public int getMaxStackTraceLines() {
        return maxStackTraceLines;
    }

    @Override
    public Config getInstrumentationConfig() {
        return instrumentationConfig;
    }

    @Override
    public String getMetricIngestUri() {
        return metricIngestUri;
    }

    @Override
    public String getEventIngestUri() {
        return eventIngestUri;
    }

    @Override
    public boolean isHighSecurity() {
        return highSecurity;
    }

    @Override
    public boolean isSimpleCompression() {
        return simpleCompression;
    }

    @Override
    public String getCompressedContentEncoding() {
        return compressedContentEncoding;
    }

    @Override
    public boolean isPutForDataSend() {
        return putForDataSend;
    }

    @Override
    public boolean getIbmWorkaroundEnabled() {
        return this.ibmWorkaroundEnabled;
    }

    @Override
    public LabelsConfig getLabelsConfig() {
        return labelsConfig;
    }

    @Override
    public NormalizationRuleConfig getNormalizationRuleConfig() {
        return normalizationRuleConfig;
    }

    @Override
    public boolean isStartupTimingEnabled() {
        return startupTimingEnabled;
    }

    @Override
    public CircuitBreakerConfig getCircuitBreakerConfig() {
        return this.circuitBreakerConfig;
    }

    @Override
    public StripExceptionConfig getStripExceptionConfig() {
        return stripExceptionConfig;
    }

    @Override
    public TransactionNamingScheme getTransactionNamingScheme() {
        return transactionNamingMode;
    }

    @Override
    public UtilizationDataConfig getUtilizationDataConfig() {
        return utilizationConfig;
    }

    @Override
    public DatastoreConfig getDatastoreConfig() {
        return datastoreConfig;
    }

    @Override
    public ExternalTracerConfig getExternalTracerConfig() {
        return externalTracerConfig;
    }

    @Override
    public boolean openTracingEnabled() {
        return openTracingConfig.isEnabled();
    }

    @Override
    public TransactionEventsConfig getTransactionEventsConfig() {
        return transactionEventsConfig;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy