/// <summary>
 /// Log a CloudWatch metric. The metric is picked up by CloudWatch logs and automatically ingested as a CloudWatch metric.
 /// </summary>
 /// <param name="logger">The <see cref="ILambdaSharpLogger"/> instance to use.</param>
 /// <param name="name">Metric name.</param>
 /// <param name="value">Metric value.</param>
 /// <param name="unit">Metric unit.</param>
 /// <param name="dimensionNames">Metric dimensions as comma-separated list (e.g. [ "A", "A,B" ]).</param>
 /// <param name="dimensionValues">Dictionary of dimesion name-value pairs.</param>
 public static void LogMetric(
     this ILambdaSharpLogger logger,
     string name,
     double value,
     LambdaMetricUnit unit,
     IEnumerable <string> dimensionNames,
     Dictionary <string, string> dimensionValues
     ) => logger.LogMetric(new[] { new LambdaMetric(name, value, unit) }, dimensionNames, dimensionValues);
        /// <summary>
        /// Log a CloudWatch metric. The metric is picked up by CloudWatch logs and automatically ingested as a CloudWatch metric.
        /// </summary>
        /// <param name="logger">The <see cref="ILambdaSharpLogger"/> instance to use.</param>
        /// <param name="metrics">Enumeration of metrics, including their name, value, and unit.</param>
        /// <param name="dimensionNames">Metric dimensions as comma-separated list (e.g. [ "A", "A,B" ]).</param>
        /// <param name="dimensionValues">Dictionary of dimesion name-value pairs.</param>
        public static void LogMetric(
            this ILambdaSharpLogger logger,
            IEnumerable <LambdaMetric> metrics,
            IEnumerable <string> dimensionNames,
            Dictionary <string, string> dimensionValues
            )
        {
            if (!metrics.Any())
            {
                return;
            }
            IEnumerable <string>        newDimensionNames;
            Dictionary <string, string> newDimensionValues;

            if (logger.Info.ModuleId != null)
            {
                if (logger.Info.FunctionName != null)
                {
                    // dimension the metric by 'Stack' and 'Function'
                    newDimensionNames  = dimensionNames.Union(new[] { "Stack", "Stack,Function" }).Distinct().ToList();
                    newDimensionValues = new Dictionary <string, string>(dimensionValues)
                    {
                        ["Stack"]    = logger.Info.ModuleId,
                        ["Function"] = logger.Info.FunctionName
                    };
                }
                else if (logger.Info.AppName != null)
                {
                    // dimension the metric by 'Stack' and 'App'
                    newDimensionNames  = dimensionNames.Union(new[] { "Stack", "Stack,App" }).Distinct().ToList();
                    newDimensionValues = new Dictionary <string, string>(dimensionValues)
                    {
                        ["Stack"] = logger.Info.ModuleId,
                        ["App"]   = logger.Info.AppName
                    };
                }
                else
                {
                    newDimensionNames  = new List <string>();
                    newDimensionValues = new Dictionary <string, string>(dimensionValues);
                }
            }
            else
            {
                if (logger.Info.FunctionName != null)
                {
                    // dimension the metric by 'Function' only
                    newDimensionNames  = dimensionNames.Union(new[] { "Function" }).Distinct().ToList();
                    newDimensionValues = new Dictionary <string, string>(dimensionValues)
                    {
                        ["Function"] = logger.Info.FunctionName
                    };
                }
                else if (logger.Info.AppName != null)
                {
                    // dimension the metric by 'App' only
                    newDimensionNames  = dimensionNames.Union(new[] { "App" }).Distinct().ToList();
                    newDimensionValues = new Dictionary <string, string>(dimensionValues)
                    {
                        ["App"] = logger.Info.AppName
                    };
                }
                else
                {
                    newDimensionNames  = new List <string>();
                    newDimensionValues = new Dictionary <string, string>(dimensionValues);
                }
            }

            // add git sha and git branch as extra metadata when available
            if (logger.Info.GitSha != null)
            {
                newDimensionValues["GitSha"] = logger.Info.GitSha;
            }
            if (logger.Info.GitBranch != null)
            {
                newDimensionValues["GitBranch"] = logger.Info.GitBranch;
            }
            logger.LogMetric($"Module:{logger.Info.GetModuleFullName()}", metrics, newDimensionNames, newDimensionValues);
        }
 /// <summary>
 /// Log a CloudWatch metric. The metric is picked up by CloudWatch logs and automatically ingested as a CloudWatch metric.
 /// </summary>
 /// <param name="logger">The <see cref="ILambdaSharpLogger"/> instance to use.</param>
 /// <param name="metrics">Enumeration of metrics, including their name, value, and unit.</param>
 public static void LogMetric(this ILambdaSharpLogger logger, IEnumerable <LambdaMetric> metrics)
 => logger.LogMetric(metrics, Array.Empty <string>(), new Dictionary <string, string>());
        //--- Extension Methods ---

        /// <summary>
        /// Log a CloudWatch metric. The metric is picked up by CloudWatch logs and automatically ingested as a CloudWatch metric.
        /// </summary>
        /// <param name="logger">The <see cref="ILambdaSharpLogger"/> instance to use.</param>
        /// <param name="name">Metric name.</param>
        /// <param name="value">Metric value.</param>
        /// <param name="unit">Metric unit.</param>
        public static void LogMetric(
            this ILambdaSharpLogger logger,
            string name,
            double value,
            LambdaMetricUnit unit
            ) => logger.LogMetric(new[] { new LambdaMetric(name, value, unit) });