Пример #1
0
        public async Task <PingDataPoint> PingServerAsync(PingSetting setting)
        {
            using (var httpClient = _factory.BuildClient())
            {
                TimeSpan       responseTime;
                HttpStatusCode statusCode = HttpStatusCode.ServiceUnavailable;

                // Generate a request
                var httpContent = new HttpRequestMessage(
                    setting.GetMethodRequired ? HttpMethod.Get : HttpMethod.Head,
                    setting.ServerUrl
                    );

                var timer = new Stopwatch();
                timer.Start();

                var task = httpClient.SendAsync(httpContent);
                // Make sure task finishes in TotalMilliseconds milliseconds
                if (
                    await Task.WhenAny(
                        task,
                        Task.Delay(Convert.ToInt32(setting.MaxResponseTime.TotalMilliseconds))
                        ) == task
                    )
                {
                    var response = await task;

                    timer.Stop();

                    // Record time and code
                    responseTime = timer.Elapsed;
                    statusCode   = response.StatusCode;
                }

                if (
                    statusCode == HttpStatusCode.ServiceUnavailable ||
                    responseTime > setting.MaxResponseTime
                    )
                {
                    // Timeout/cancellation logic
                    // If problem occurred then set service unavailable.
                    responseTime = new TimeSpan(0);
                    statusCode   = HttpStatusCode.ServiceUnavailable;

                    // _logger.LogWarning(LoggingEvents.Ping.AsInt(), $"Resource {setting.ServerUrl} is unavailable. See stack trace.");
                }

                _logger.LogDebug(LoggingEvents.Ping.AsInt(), $"Ping completed for {setting.ServerUrl}");

                var metric = await _metrics.GetOrCreateMetricAsync(Metrics.Ping, new Uri(setting.ServerUrl).Host);

                return(new PingDataPoint
                {
                    Metric = metric,
                    ResponseTime = responseTime,
                    Success = statusCode.AsInt() / 100 == 2,                     // 2xx
                    Message = statusCode.AsInt() / 100 == 2 ? "OK" : "Failure"
                });
            }
        }
Пример #2
0
        public async Task <PingDataPoint> PingServerAsync(PingSetting setting)
        {
            using (var client = _factory.BuildClient())
            {
                var parameters = new Dictionary <string, string> {
                    { "url", setting.ServerUrl },
                    { "method", setting.GetMethodRequired ? "GET" : "HEAD" },
                    { "timeout", setting.MaxResponseTime.TotalMilliseconds.ToString() }
                };

                var result = await client.GetAsync(QueryHelpers.AddQueryString(_conf["Data:PingServerUrl"], parameters));

                var data = JsonConvert.DeserializeObject <RemotePingServerResponse>(
                    await result.Content.ReadAsStringAsync()
                    );

                _logger.LogDebug(LoggingEvents.Ping.AsInt(), $"Ping completed for {setting.ServerUrl}");

                var metric = await _metrics.GetOrCreateMetricAsync(Metrics.Ping, new Uri(setting.ServerUrl).Host);

                return
                    (data.IsError ?
                     new PingDataPoint
                {
                    Metric = metric,
                    ResponseTime = new TimeSpan(0),
                    Success = data.StatusCode / 100 == 2,                             // 2xx
                    Message = data.Error
                }:
                     new PingDataPoint
                {
                    Metric = metric,
                    ResponseTime = new TimeSpan(0, 0, 0, 0, data.Latency),
                    Success = data.StatusCode / 100 == 2,                             // 2xx
                    Message = "OK"
                });
            }
        }
Пример #3
0
        /// <summary>
        /// Populate properties with values read from config
        /// </summary>
        private void ReadConfiguration()
        {
            _autoLabels = ReadStaticValueFromConfiguration <AutoLabel, AutoLabels>(
                (label) => new AutoLabel
            {
                Id    = label.AsInt(),
                Title = _configuration[$"Data:AutoLabels:{label.ToString()}"]
            }
                );

            _manualLabels = ReadStaticValueFromConfiguration <ManualLabel, ManualLabels>(
                (label) => new ManualLabel
            {
                Id    = label.AsInt(),
                Title = _configuration[$"Data:ManualLabels:{label.ToString()}"]
            }
                );

            _compilationStages = ReadStaticValueFromConfiguration <CompilationStage, CompilationStages>(
                (label) => new CompilationStage
            {
                Id   = label.AsInt(),
                Name = _configuration[$"Data:CompilationStages:{label.ToString()}"]
            }
                );

            _logEntrySeverities = ReadStaticValueFromConfiguration <LogEntrySeverity, LogEntrySeverities>(
                (label) => new LogEntrySeverity
            {
                Id          = label.AsInt(),
                Description = _configuration[$"Data:LogEntrySeverities:{label.ToString()}"]
            }
                );

            _abstractMetrics = ReadStaticValueFromConfiguration <AbstractMetric, Metrics>(
                (label) => new AbstractMetric
            {
                Type   = label.AsInt(),
                Public = label == Metrics.CpuLoad || label == Metrics.Ping || label == Metrics.Health,
                Title  = _configuration[$"Data:Metrics:{label.ToString()}"]
            }
                );

            var pingConfig = _configuration.SectionsFromArray("Data:PingSettings");

            if (pingConfig.Count() > 0)
            {
                _pingSettings =
                    pingConfig
                    .Select(section =>
                {
                    var setting = new PingSetting
                    {
                        ServerUrl = section["ServerUrl"]
                    };
                    if (section["MaxResponseTime"] != null)
                    {
                        setting.MaxResponseTime = new TimeSpan(0, 0, 0, 0, Convert.ToInt32(section["MaxResponseTime"]));
                    }
                    if (section["MaxFailures"] != null)
                    {
                        setting.MaxFailures = Convert.ToInt32(section["MaxFailures"]);
                    }
                    if (section["GetMethodRequired"] != null)
                    {
                        setting.GetMethodRequired = Convert.ToBoolean(section["GetMethodRequired"]);
                    }

                    return(setting);
                })
                    .ToList();
            }
        }
Пример #4
0
        /// <summary>
        /// Traverses the lists of ping datapoints looking for places where ping failed a number of times defined
        /// in setting.
        /// </summary>
        /// <param name="pings">List of ping datapoints to traverse</param>
        /// <param name="setting">Ping setting used to determine how many times it is permissible to fail a ping</param>
        /// <param name="metric">Metric which will appear in a resulting discrepancy object</param>
        /// <returns>A list of discrepancies of type DiscrepancyType.PingFailedNTimes found</returns>
        internal List <Discrepancy> FindPingFailuresFromDataPoints(IEnumerable <PingDataPoint> pings, PingSetting setting, Metric metric)
        {
            if (pings.Count() == 0)
            {
                return(new List <Discrepancy>());
            }

            var failures = pings
                           .Select(p => new
            {
                StatusOK  = p.Success,
                Timestamp = p.Timestamp
            });

            if (!failures.Any(l => l.StatusOK))
            {
                // Means that server is dead for the whole timeframe
                // Discrepancy has been noticed already
                return(new List <Discrepancy>());
            }

            return(failures
                   .OrderBy(p => p.Timestamp)
                   .SkipWhile(p => !p.StatusOK)
                   .Aggregate(
                       new Stack <BoolIntDateTuple>(),
                       (rest, self) =>
            {
                if (rest.Count == 0 || rest.Peek().StateGood != self.StatusOK)
                {
                    rest.Push(new BoolIntDateTuple
                    {
                        StateGood = self.StatusOK,
                        DateFirstOffense = self.Timestamp
                    });
                }
                else
                {
                    rest.Peek().Count++;
                }
                return rest;
            }
                       )
                   .Where(t => !t.StateGood && t.Count > setting.MaxFailures)
                   .Select(x => new Discrepancy
            {
                DateFirstOffense = x.DateFirstOffense,
                Type = DiscrepancyType.PingFailedNTimes,
                MetricType = (Metrics)metric.Type,
                MetricSource = metric.Source
            })
                   .ToList());
        }