private static string GetSanitizedAppName(IProductConfiguration config)
        {
            string unsanitizedAppName = config.DDDataTags_Service;

            if (string.IsNullOrWhiteSpace(unsanitizedAppName))
            {
                try
                {
                    unsanitizedAppName = CurrentProcess.GetName();
                }
                catch
                {
                    unsanitizedAppName = "UnknownApp";
                }
            }

            // Sanitize app name:

            var appName = new StringBuilder(unsanitizedAppName);

            // Note that the 'appName' is likely to be based on the service name tag setting, which, in turn,
            // is likely to be based on the ASP.NET site name.
            // Common "unwished" characters that come up in site names, such as '/', '\\', ':' and others are
            // contained in the invalid chars arrays below, especially in 'invalidFilenameChars'.
            char[] invalidPathChars     = Path.GetInvalidPathChars();
            char[] invalidFilenameChars = Path.GetInvalidFileNameChars();

            for (int p = 0; p < appName.Length; p++)
            {
                char c         = appName[p];
                bool isInvalid = char.IsWhiteSpace(c) || c == '.';

                for (int i = 0; i < invalidPathChars.Length && !isInvalid; i++)
                {
                    isInvalid = (c == invalidPathChars[i]);
                }

                for (int i = 0; i < invalidFilenameChars.Length && !isInvalid; i++)
                {
                    isInvalid = (c == invalidFilenameChars[i]);
                }

                if (isInvalid)
                {
                    appName[p] = '_';
                }
            }

            return(appName.ToString());
        }
        /// <summary>
        /// Figure out what the DDSevice tag should be, if the user specified nothing.
        /// Try to get the same value as the Tracer does, so that the user gets the same value for the same app.
        /// However, under some circumstances, the Tracer uses tracer specific data.
        /// In such cases, we cannot have a completely identical name like for example:
        ///   - In some application servers, the Tracer considers whether the app makes GET or POST calls to downstream dependencies;
        ///   - Users may override the service tag programmatically on a per span basis.
        ///   - ...
        /// Note that if the SIGNALFX_SERVICE environment variable is set, then the value returned by this method will probably
        /// be overwritten anyway (<see cref="EnvironmentVariablesConfigurationProvider" />).
        /// </summary>
        public static string GetDdServiceFallback()
        {
            try
            {
                try
                {
                    if (TryGetClassicAspNetSiteName(out var aspNetSiteName))
                    {
                        return(aspNetSiteName);
                    }
                }
                catch
                {
                    // Just fall back to the next option.
                    // Also, note the doc comments on 'TryGetClassicAspNetSiteName(..)' about partial trust.
                }

                return(Assembly.GetEntryAssembly()?.GetName().Name.Trim() ?? CurrentProcess.GetName()?.Trim());
            }
            catch
            {
                return(null);
            }
        }