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)); } }
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()); }
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()); }