Example #1
0
        public static IProductConfiguration ApplyReleaseOrDevDefaults(this IProductConfiguration config)
        {
            const string EnvVarName = "DD_INTERNAL_USE_DEVELOPMENT_CONFIGURATION";
            const bool   ddInternalUseDevelopmentConfigurationValDefault = false;

            string ddInternalUseDevelopmentConfiguration = Environment.GetEnvironmentVariable(EnvVarName);

            if (
                ConfigurationProviderUtils.TryParseBooleanSettingStr(
                    ddInternalUseDevelopmentConfiguration,
                    ddInternalUseDevelopmentConfigurationValDefault,
                    out bool ddInternalUseDevelopmentConfigurationVal))
            {
                Log.Info(
                    LogComponentMoniker,
                    "Use-Dev-Config environment setting found and parsed.",
                    "Env var name",
                    EnvVarName,
                    "Parsed value",
                    ddInternalUseDevelopmentConfigurationVal);
            }
            else
            {
                Log.Info(
                    LogComponentMoniker,
                    "Use-Dev-Config environment setting not found or not parsed. Default will be used.",
                    "Env var name",
                    EnvVarName,
                    "Value",
                    ddInternalUseDevelopmentConfiguration,
                    "Used default value",
                    ddInternalUseDevelopmentConfigurationVal);
            }

            if (ddInternalUseDevelopmentConfigurationVal)
            {
                return(DevProductConfigurationProvider.ApplyDevDefaults(config));
            }
            else
            {
                return(DefaultReleaseProductConfigurationProvider.ApplyReleaseDefaults(config));
            }
        }
Example #2
0
        public static IProductConfiguration ApplyEnvironmentVariables(this IProductConfiguration config)
        {
            if (config == null)
            {
                return(null);
            }

            var mutableConfig = new MutableProductConfiguration(config);

            if (TryGetEnvironmentVariable("SIGNALFX_PROFILING_UPLOAD_PERIOD", out string envProfilesExportDefaultInterval))
            {
                if (int.TryParse(envProfilesExportDefaultInterval, out var profilesExportDefaultInterval))
                {
                    mutableConfig.ProfilesExport_DefaultInterval = TimeSpan.FromSeconds(profilesExportDefaultInterval);
                }
                else
                {
                    Log.Error(
                        Log.WithCallInfo(LogComponentMoniker),
                        "The environment variable \"SIGNALFX_PROFILING_UPLOAD_PERIOD\" is specified (\"",
                        envProfilesExportDefaultInterval,
                        "\") but cannot be parsed as an int. Using original value: ",
                        mutableConfig.ProfilesExport_DefaultInterval);
                }
            }

            if (TryGetEnvironmentVariable("SIGNALFX_PROFILING_OUTPUT_DIR", out string directory))
            {
                mutableConfig.ProfilesExport_LocalFiles_Directory = directory;
            }

            // If Ingestion Endpoint Url is specified, the Host, Port and ApiPath are ignored.
            // However, that logic is inside the export loop that actually interprets those values.
            // At this point we just extract all of the info that is contained in the environment variables.
            // If both, URL and Host-Port-Etc are specified, we will extract them all and leave the
            // priorization logic of what to use to the config consumer.
            if (TryGetEnvironmentVariable("SIGNALFX_TRACE_AGENT_URL", out string ddTraceAgentUrl))
            {
                mutableConfig.ProfilesIngestionEndpoint_Url = ddTraceAgentUrl;
            }

            if (TryGetEnvironmentVariable("SIGNALFX_AGENT_HOST", out string ddTraceAgentHost))
            {
                mutableConfig.ProfilesIngestionEndpoint_Host = ddTraceAgentHost;
            }

            if (TryGetEnvironmentVariable("SIGNALFX_TRACE_AGENT_PORT", out string szTraceAgentPort))
            {
                if (int.TryParse(szTraceAgentPort, out int port))
                {
                    mutableConfig.ProfilesIngestionEndpoint_Port = port;
                }
                else
                {
                    Log.Error(
                        Log.WithCallInfo(LogComponentMoniker),
                        "The environment variable \"SIGNALFX_TRACE_AGENT_PORT\" is specified (",
                        szTraceAgentPort,
                        ") but cannot be parsed as a number and will be ignored.");
                }
            }

            // Api Key is not required for agent-based ingestion scnarios; it IS required for agent-less ingestion.
            if (TryGetEnvironmentVariable("SIGNALFX_API_KEY", out string ddApiKey))
            {
                mutableConfig.ProfilesIngestionEndpoint_DatadogApiKey = ddApiKey;
            }

            if (TryGetEnvironmentVariable("SIGNALFX_HOSTNAME", out string ddHostName))
            {
                mutableConfig.DDDataTags_Host = ddHostName;
            }

            if (TryGetEnvironmentVariable("SIGNALFX_SERVICE", out string ddServiceName))
            {
                mutableConfig.DDDataTags_Service = ddServiceName;
            }

            if (TryGetEnvironmentVariable("SIGNALFX_ENV", out string ddEnvironment))
            {
                mutableConfig.DDDataTags_Env = ddEnvironment;
            }

            if (TryGetEnvironmentVariable("SIGNALFX_VERSION", out string ddServiceVersion))
            {
                mutableConfig.DDDataTags_Version = ddServiceVersion;
            }

            if (TryGetEnvironmentVariable("SIGNALFX_TAGS", out string ddTagsStr))
            {
                mutableConfig.DDDataTags_CustomTags = ParseAndMergeDdTags(mutableConfig.DDDataTags_CustomTags, ddTagsStr);
            }

            if (TryGetEnvironmentVariable("SIGNALFX_TRACE_DEBUG", out string envIsTraceDebugEnabled))
            {
                const bool isTraceDebugEnabled = true;
                if (
                    ConfigurationProviderUtils.TryParseBooleanSettingStr(
                        envIsTraceDebugEnabled,
                        isTraceDebugEnabled,
                        out bool ddIsTraceDebugEnabledVal))
                {
                    mutableConfig.Log_IsDebugEnabled = ddIsTraceDebugEnabledVal;
                }
                else
                {
                    Log.Error(
                        Log.WithCallInfo(LogComponentMoniker),
                        "The environment variable \"SIGNALFX_TRACE_DEBUG\" is specified (",
                        envIsTraceDebugEnabled,
                        $") but cannot be parsed as a boolean. Using {isTraceDebugEnabled.ToString()} as default");

                    mutableConfig.Log_IsDebugEnabled = isTraceDebugEnabled;
                }
            }

            if (TryGetEnvironmentVariable("SIGNALFX_PROFILING_LOG_DIR", out string ddTraceLogDirectory))
            {
                mutableConfig.Log_PreferredLogFileDirectory = ddTraceLogDirectory;
            }

            if (TryGetEnvironmentVariable("SIGNALFX_INTERNAL_OPERATIONAL_METRICS_ENABLED", out string envIsEnabled))
            {
                const bool isOperationalMetricsEnabled = false;
                if (ConfigurationProviderUtils.TryParseBooleanSettingStr(envIsEnabled, isOperationalMetricsEnabled, out bool isEnabled))
                {
                    mutableConfig.Metrics_Operational_IsEnabled = isEnabled;
                }
                else
                {
                    Log.Error(
                        Log.WithCallInfo(LogComponentMoniker),
                        "The environment variable \"SIGNALFX_INTERNAL_OPERATIONAL_METRICS_ENABLED\" is specified (",
                        envIsEnabled,
                        $") but cannot be parsed as a boolean. Using {isOperationalMetricsEnabled.ToString()} as default");

                    mutableConfig.Log_IsDebugEnabled = isOperationalMetricsEnabled;
                }
            }

            if (TryGetEnvironmentVariable("SIGNALFX_PROFILING_FRAMES_NATIVE_ENABLED", out string envFramesNativeIsEnabled))
            {
                const bool isFramesNativeEnabled = false;
                if (ConfigurationProviderUtils.TryParseBooleanSettingStr(envFramesNativeIsEnabled, isFramesNativeEnabled, out bool isEnabled))
                {
                    mutableConfig.FrameKinds_Native_IsEnabled = isEnabled;
                }
                else
                {
                    Log.Error(
                        Log.WithCallInfo(LogComponentMoniker),
                        "The environment variable \"SIGNALFX_PROFILING_FRAMES_NATIVE_ENABLED\" is specified (",
                        envFramesNativeIsEnabled,
                        $") but cannot be parsed as a boolean. Using isFramesNativeEnabled.ToString() as default");

                    mutableConfig.FrameKinds_Native_IsEnabled = isFramesNativeEnabled;
                }
            }

            return(mutableConfig.CreateImmutableSnapshot());
        }
Example #3
0
        public static IProductConfiguration ApplyDevDefaults(this IProductConfiguration config)
        {
            if (config == null)
            {
                return(null);
            }

            var mutableConfig = new MutableProductConfiguration(config);

            // mutableConfig.ProfilesExport_DefaultInterval = TimeSpan.FromSeconds(20);
            mutableConfig.ProfilesExport_DefaultInterval = TimeSpan.FromSeconds(60);

            // These bytes are counted as encoded in the buffer segment, i.e. each snapshot takes (26 + 9 per frame) bytes (see StackSnapshotResult.h).
            // Snapshots with 100 frames: 1 snapshot uses 926 bytes, 1MB holds 1132 such snapshots.
            // Snapshots with 50 frames:  1 snapshot uses 476 bytes, 1MB holds 2202 such snapshots
            // Snapshots with 35 frames:  1 snapshot uses 341 bytes, 1MB holds 3075 such snapshots.
            //
            // We will not sample 5 threads more often than once every 9 milliseconds.
            // Assuming 50 frames per snapshot on average (based on some ad-hoc tests with Computer01 demo
            // it is a safe upper bound for the average), we don't expect to generate more than ~33,333 (= 5 * 60 * 1000 / 9) snapshots per minute
            // --> which requires 33,333 / 2202 ~= 15 MB.
            // A 50 MB buffer will work for ~3+ minutes
            // 50,000 samples currespond to ~22 MB.
            mutableConfig.ProfilesExport_EarlyTriggerOnCollectedStackSnapshotsBytes = 50 * 1024 * 1024;  // 50 MBytes
            mutableConfig.ProfilesExport_EarlyTriggerOnCollectedStackSnapshotsCount = 50000;

            mutableConfig.ProfilesExport_LocalFiles_Directory = ConfigurationProviderUtils.GetOsSpecificDefaultPProfDirectory();

            // If Ingestion Endpoint Url is specified, the Host, Port and ApiPath are ignored.
            // mutableConfig.ProfilesIngestionEndpoint_Url = "https://intake.profile.datadoghq.com/v1/input";

            // --> to local agent that sends to staging
            // mutableConfig.ProfilesIngestionEndpoint_Host = "127.0.0.1";                       // Local agent (avoids the IPv4 wait that can occur when using "localhost")
            // mutableConfig.ProfilesIngestionEndpoint_Host = "localhost";                    // Local agent
            // mutableConfig.ProfilesIngestionEndpoint_Host = "intake.profile.datadoghq.com"; // Main DD ingestion endpoint for agent-less
            // mutableConfig.ProfilesIngestionEndpoint_Host = "intake.profile.datad0g.com";   // Staging DD ingestion endpoint for agent-less

            mutableConfig.ProfilesIngestionEndpoint_Port = 8126;   // Local agent's default port
            // mutableConfig.ProfilesIngestionEndpoint_Port = 0;   // Value <= 0 will result the defaut port for the protocol being used.

            mutableConfig.ProfilesIngestionEndpoint_ApiPath = "profiling/v1/input";  // Local agent's API path.
            // mutableConfig.ProfilesIngestionEndpoint_ApiPath = "v1/input";         // DD ingestion endpoint's API path (for agent-less scenarios)

            // Api Key is not required for agent-based ingestion scenarios; it IS required for agent-less ingestion.
            // mutableConfig.ProfilesIngestionEndpoint_DatadogApiKey = "xxx";
            // mutableConfig.ProfilesIngestionEndpoint_DatadogApiKey = null;

            // --> to preprod
            mutableConfig.ProfilesIngestionEndpoint_Url           = "https://intake.profile.datadoghq.com/v1/input";
            mutableConfig.ProfilesIngestionEndpoint_DatadogApiKey = string.Empty;

            string ddService = ConfigurationProviderUtils.GetDdServiceFallback();

            mutableConfig.DDDataTags_Host       = ConfigurationProviderUtils.GetMachineName();
            mutableConfig.DDDataTags_Service    = string.IsNullOrWhiteSpace(ddService) ? ".Net-Profiling-TestService01" : ddService;
            mutableConfig.DDDataTags_Env        = "APM-Profiling-Local";
            mutableConfig.DDDataTags_Version    = "Demo-Version-11";
            mutableConfig.DDDataTags_CustomTags = new KeyValuePair <string, string>[]
            {
                new KeyValuePair <string, string>("CustomTag A", string.Empty),
                new KeyValuePair <string, string>(null, "Some Value B"),
                new KeyValuePair <string, string>("CustomTag C", "Some Value C"),
                new KeyValuePair <string, string>("service", "Foo-Bar")
            };

            mutableConfig.Log_IsDebugEnabled            = true;
            mutableConfig.Log_PreferredLogFileDirectory = ConfigurationProviderUtils.GetOsSpecificDefaultLogDirectory();

            mutableConfig.Metrics_Operational_IsEnabled = false;

            mutableConfig.Metrics_StatsdAgent_Port = 8125;

            // For now, the default installation does not collect native frames.
            // The user can, however, enable it using an environment variable (see 'EnvironmentVariablesConfigurationProvider').
            // This should be changed once the UI supports appropriate filtering.
            mutableConfig.FrameKinds_Native_IsEnabled = false;

            return(mutableConfig.CreateImmutableSnapshot());
        }
        public static IProductConfiguration ApplyReleaseDefaults(this IProductConfiguration config)
        {
            if (config == null)
            {
                return(null);
            }

            var mutableConfig = new MutableProductConfiguration(config);

            mutableConfig.ProfilesExport_DefaultInterval = TimeSpan.FromSeconds(60);

            // These bytes are counted as encoded in the buffer segment, i.e. each snapshot takes (26 + 9 per frame) bytes (see StackSnapshotResult.h).
            // Snapshots with 100 frames: 1 snapshot uses 926 bytes, 1MB holds 1132 such snapshots.
            // Snapshots with 50 frames:  1 snapshot uses 476 bytes, 1MB holds 2202 such snapshots
            // Snapshots with 35 frames:  1 snapshot uses 341 bytes, 1MB holds 3075 such snapshots.
            //
            // We will not sample 5 threads more often than once every 9 milliseconds.
            // Assuming 50 frames per snapshot on average (based on some ad-hoc tests with Computer01 demo
            // it is a safe upper bound for the average), we don't expect to generate more than ~33333 (= 5 * 60 * 1000 / 9) snapshots per minute
            // --> which requires 33333 / 2202 ~= 15 MB.
            // A 500 MB buffer will work for ~33 minutes
            // 1,000,000 samples currespond to ~454 MB.
            //
            // Based on the above, we go with the magic numbers that will limit the buffer to 500 MB and 1 Mio samples
            // by triggering the profiles export if those thresholds are met.
            // These are round numbers that will keep the impact on the customer app in check during early beta stages.
            // During the public beta we need to validate these assumptions and see if the numbers need to be tweaked in either direction.
            mutableConfig.ProfilesExport_EarlyTriggerOnCollectedStackSnapshotsBytes = 500 * 1024 * 1024;  // 500 MBytes
            mutableConfig.ProfilesExport_EarlyTriggerOnCollectedStackSnapshotsCount = 1000000;            // 1,000,000 stack samples

            mutableConfig.ProfilesExport_LocalFiles_Directory = null;

            mutableConfig.ProfilesIngestionEndpoint_Url     = null;                   // If Ingestion Endpoint Url is specified, the Host, Port and ApiPath are ignored.
            mutableConfig.ProfilesIngestionEndpoint_Host    = "127.0.0.1";            // Local agent (avoids the IPv4 wait that can occur when using "localhost")
            mutableConfig.ProfilesIngestionEndpoint_Port    = 8126;                   // Local agent's default port
            mutableConfig.ProfilesIngestionEndpoint_ApiPath = "profiling/v1/input";   // Local agent's API path.

            // Api Key is not required for agent-based ingestion scnarios; it IS required for agent-less ingestion.
            mutableConfig.ProfilesIngestionEndpoint_DatadogApiKey = null;

            // For RELEASE, the we use defaults below, and better values need to be created by setting respective environment variables
            // (see the .ApplyEnvironmentVariables() API in EnvironmentVariablesConfigurationProvider).
            string ddService = ConfigurationProviderUtils.GetDdServiceFallback();

            mutableConfig.DDDataTags_Host       = ConfigurationProviderUtils.GetMachineName();
            mutableConfig.DDDataTags_Service    = string.IsNullOrWhiteSpace(ddService) ? "Unspecified-Service" : ddService;
            mutableConfig.DDDataTags_Env        = "Unspecified-Environment";
            mutableConfig.DDDataTags_Version    = "Unspecified-Version";
            mutableConfig.DDDataTags_CustomTags = new KeyValuePair <string, string> [0];

            // When we get to public beta, Debug-Logging should be DISABLED by default.
            // However, while we are still working towards that level of maturity, debug logs are almost always helpful.
            mutableConfig.Log_IsDebugEnabled            = true;
            mutableConfig.Log_PreferredLogFileDirectory = ConfigurationProviderUtils.GetOsSpecificDefaultLogDirectory();

            mutableConfig.Metrics_Operational_IsEnabled = false;

            mutableConfig.Metrics_StatsdAgent_Port = 8125;

            // For now, the default installation does not collect native frames.
            // The user can, however, enable it using an environment variable (see 'EnvironmentVariablesConfigurationProvider').
            // This should be changed once the UI supports appropriate filtering.
            mutableConfig.FrameKinds_Native_IsEnabled = false;

            return(mutableConfig.CreateImmutableSnapshot());
        }