public static void Shutdown()
        {
            _flushSchedulerHandler?.Dispose();

            _instance          = null;
            _httpClient        = null;
            _rootMetricsLogger = null;

            MetricsLoggers.Clear();

            while (MetricsQueue.TryDequeue(out _))
            {
            }
        }
        public static void Initialize(string serviceName, string env, string hostInfo)
        {
            if (!Dimensions.IsValidName(serviceName))
            {
                throw new ArgumentException(nameof(serviceName));
            }

            if (_instance != null)
            {
                return;
            }

            lock (Locker)
            {
                if (_instance != null)
                {
                    return;
                }

                _instance = new MetricsManager(serviceName, env, hostInfo);

                _environment = env;
                _hostInfo    = hostInfo;
                _serviceName = serviceName;

                var envDimension = GetEnvironmentDimension(env);

                LoadOptionsFromConfigFile();

                _rootMetricsLogger = GetOrAddRootMetricsLogger($"service={serviceName}{envDimension}");
                _httpClient        = ConfigureHttpClient();

                if (!Options.IsManualFlush)
                {
                    try
                    {
                        _flushSchedulerHandler = InitializeFlushScheduler();
                    }
                    catch (Exception e)
                    {
                        Logger.LogError(e.ToString());
                    }
                }

                Logger.LogInformation($"{nameof(MetricsManager)} successfuly initialized at {DateTime.UtcNow} UTC.");
            }
        }
        public void StopTimer(string timerName)
        {
            if (!Dimensions.IsValidName(timerName))
            {
                MetricsManager.ReportError($"Invalid timer name {timerName}");
                return;
            }

            if (!_metrics.ContainsKey(timerName))
            {
                return;
            }

            if (_metrics.TryGetValue(timerName, out var metric) && metric is ITimer tim)
            {
                tim.StopTimer();
            }
        }
        public void IncrementCounter(string counterName, int value)
        {
            if (!Dimensions.IsValidName(counterName))
            {
                MetricsManager.ReportError($"Invalid counter name: {counterName}");
                return;
            }

            if (_metrics.ContainsKey(counterName))
            {
                if (_metrics.TryGetValue(counterName, out var mtrc) && mtrc is ICounter cntr)
                {
                    cntr.IncrementCounter(value);
                }

                return;
            }

            var counter = new Counter();

            counter.IncrementCounter(value);
            _metrics.TryAdd(counterName, counter);
        }
        public TimerMetric StartTimer(string timerName)
        {
            if (!Dimensions.IsValidName(timerName))
            {
                MetricsManager.ReportError($"Invalid timer name {timerName}");
                return(null);
            }

            if (_metrics.ContainsKey(timerName))
            {
                if (_metrics.TryGetValue(timerName, out var metric) && metric is ITimer tim)
                {
                    tim.StartTimer();
                    return(new TimerMetric(this, timerName));
                }
            }

            var timer = new Timer();

            timer.StartTimer();
            _metrics.TryAdd(timerName, timer);

            return(new TimerMetric(this, timerName));
        }
        public void Record(string metricName, decimal value, Unit unit)
        {
            if (!Dimensions.IsValidName(metricName))
            {
                MetricsManager.ReportError($"Invalid metric name: {metricName}");
                return;
            }

            if (_metrics.ContainsKey(metricName))
            {
                if (_metrics.TryGetValue(metricName, out var metric) && metric is IRecorder rec)
                {
                    rec.Record(value, unit);
                }

                return;
            }

            var recorder = new Recorder(unit);

            recorder.Record(value, unit);

            _metrics.TryAdd(metricName, recorder);
        }
 public virtual void Flush()
 {
     MetricsManager.FlushMetricsLogger(this);
     MetricsManager.FlushToServer(DateTimeHelpers.GetTimeStampInSeconds());
 }