Exemple #1
0
        public SentryStats(ContainerStatsResponse response)
        {
            ContainerId = response.ID;
            Time        = response.Read;
            Pids        = response.PidsStats.Current;
            // cpu
            if (response.CPUStats.SystemUsage - response.PreCPUStats.SystemUsage > 0 &&
                response.CPUStats.CPUUsage.TotalUsage - response.PreCPUStats.CPUUsage.TotalUsage >= 0)
            {
                CpuPercent = (((decimal)(response.CPUStats.CPUUsage.TotalUsage - response.PreCPUStats.CPUUsage.TotalUsage) /
                               (decimal)(response.CPUStats.SystemUsage - response.PreCPUStats.SystemUsage)) * 100M).ToFixed(2);
            }

            // 缓存
            var cache = 0UL;

            if (response.MemoryStats.Stats.TryGetValue("cache", out var c))
            {
                cache = c;
            }
            var memoryByte = response.MemoryStats.Usage - cache;

            MemoryValue   = ByteUnitConvert(memoryByte);
            MemoryPercent = ((decimal)memoryByte / (decimal)response.MemoryStats.MaxUsage * 100M).ToFixed(2);
            MemoryLimit   = ByteUnitConvert(response.MemoryStats.Limit);
            // net
            Nets = response.Networks?.ToDictionary(
                x => x.Key,
                x =>
                new SentryStatsReadWrite
            {
                Read  = ByteUnitConvert(x.Value.RxBytes, 1000, 1),
                Write = ByteUnitConvert(x.Value.TxBytes, 1000, 1)
            }
                );
            // block
            Block = new SentryStatsReadWrite
            {
                Read = ByteUnitConvert(response.BlkioStats.IoServiceBytesRecursive
                                       .Where(x => x.Op == "Read")
                                       .Sum(x => (decimal)x.Value), 1000, 1),
                Write = ByteUnitConvert(response.BlkioStats.IoServiceBytesRecursive
                                        .Where(x => x.Op == "Write")
                                        .Sum(x => (decimal)x.Value), 1000, 1)
            };
        }
        /// <summary>
        /// Formats the statistics data as required and writes to elasticsearch
        /// </summary>
        /// <param name="stats">Statistics for the container</param>
        private void GetPerformanceStats(ContainerStatsResponse stats)
        {
            if (stats == null)
            {
                return;
            }

            var perfData = new PerfData
            {
                TotalCpuUsage    = stats.CPUStats?.CPUUsage?.TotalUsage,
                TotalMemoryUsage = stats.MemoryStats?.Usage,
                ReadBytes        = stats.StorageStats?.ReadSizeBytes,
                WriteBytes       = stats.StorageStats?.WriteSizeBytes,
                Timestamp        = stats.Read,
                ContainerName    = stats.Name.Trim('/'),
                ContainerId      = stats.ID
            };

            Console.WriteLine("Writing data to elasticsearch");
            _elasticClient.WriteToEs(perfData);
        }
        private void GetPerformanceStats(ContainerStatsResponse stats)
        {
            if (stats == null)
            {
                return;
            }

            var perfData = new PerfData
            {
                TotalCpuUsage    = stats.CPUStats?.CPUUsage?.TotalUsage,
                TotalMemoryUsage = stats.MemoryStats?.Usage,
                MemoryLimit      = stats.MemoryStats?.Limit,
                ReadBytes        = stats.StorageStats?.ReadSizeBytes,
                WriteBytes       = stats.StorageStats?.WriteSizeBytes,
                Timestamp        = stats.Read,
                ContainerName    = stats.Name.Trim('/'),
                ContainerId      = stats.ID
            };

            // Console.WriteLine("Writing data to PerfDictByName, and Container ID is:" + perfData.ContainerId.ToString());
            //_elasticClient.WriteToEs(perfData);
            if (PerfDictByName.ContainsKey(perfData.ContainerName))
            {
                PerfDictByName[perfData.ContainerName] = perfData;
            }
            else
            {
                PerfDictByName.Add(perfData.ContainerName, perfData);
            }

            if (PerfDictByID.ContainsKey(perfData.ContainerId))
            {
                PerfDictByID[perfData.ContainerId] = perfData;
            }
            else
            {
                PerfDictByID.Add(perfData.ContainerId, perfData);
            }
        }
Exemple #4
0
        private void UpdateResourceMetrics(ContainerTrackerResourceMetrics metrics, ContainerInspectResponse container, ContainerStatsResponse resources)
        {
            // The resource reporting is very different for different operating systems.
            // This field is only used on Windows. We assume a container can't exist with 0 memory.
            bool isWindowsContainer = resources.MemoryStats.Commit != 0;

            // CPU usage
            // The mechanism of calculation is the rate of increase in container CPU time versus available ("system") CPU time.
            // The idea here is that we build two series - one counting used CPU in whatever units
            // the other counting potentially available CPU in whatever units. The % always comes right.
            // Docker CPU usage on Windows counts 100ns ticks.
            // Docker CPU usage on Linux counts unspecified ticks in relation to some other stats.
            // See https://github.com/moby/moby/blob/eb131c5383db8cac633919f82abad86c99bffbe5/cli/command/container/stats_helpers.go#L175
            if (isWindowsContainer)
            {
                // To compensate for core count on Windows, we normalize the container usage to a single core.
                // We also normalize the available CPU time to a single core.
                // This way the Windows calculation is always per-core averaged.
                // A .NET DateTimeOffset tick is 100ns, exactly, so matches what Docker uses.
                metrics.CpuCapacity.Set(CpuBaselineTimer.Elapsed.Ticks);
                metrics.CpuUsage.Set(resources.CPUStats.CPUUsage.TotalUsage / resources.NumProcs);
            }
            else
            {
                // This is counting all cores (right?).
                metrics.CpuCapacity.Set(resources.CPUStats.SystemUsage);
                metrics.CpuUsage.Set(resources.CPUStats.CPUUsage.TotalUsage);
            }

            // Memory usage
            if (isWindowsContainer)
            {
                // Windows reports Private Working Set in Docker stats... but seems to use Commit Bytes to enforce limit!
                // We want to report the same metric that is limited, so there we go.
                metrics.MemoryUsage.Set(resources.MemoryStats.Commit);
            }
            else
            {
                metrics.MemoryUsage.Set(resources.MemoryStats.Usage);
            }

            // Network I/O
            if (resources.Networks == null)
            {
                metrics.TotalNetworkBytesIn.Set(0);
                metrics.TotalNetworkBytesOut.Set(0);
            }
            else
            {
                metrics.TotalNetworkBytesIn.Set(resources.Networks.Values.Sum(n => (double)n.RxBytes));
                metrics.TotalNetworkBytesOut.Set(resources.Networks.Values.Sum(n => (double)n.TxBytes));
            }

            // Disk I/O
            if (isWindowsContainer)
            {
                metrics.TotalDiskBytesRead.Set(resources.StorageStats.ReadSizeBytes);
                metrics.TotalDiskBytesWrite.Set(resources.StorageStats.WriteSizeBytes);
            }
            else
            {
                var readEntries = resources.BlkioStats.IoServiceBytesRecursive?
                                  .Where(entry => entry.Op.Equals("read", StringComparison.InvariantCultureIgnoreCase))
                                  .ToArray();

                var writeEntries = resources.BlkioStats.IoServiceBytesRecursive?
                                   .Where(entry => entry.Op.Equals("write", StringComparison.InvariantCultureIgnoreCase))
                                   .ToArray();

                var totalRead  = readEntries == null ? 0 : readEntries.Any() ? readEntries.Sum(entry => (long)entry.Value) : 0;
                var totalWrite = writeEntries == null ? 0 : writeEntries.Any() ? writeEntries.Sum(entry => (long)entry.Value) : 0;

                metrics.TotalDiskBytesRead.Set(totalRead);
                metrics.TotalDiskBytesWrite.Set(totalWrite);
            }
        }