protected override void OnEventWritten(EventWrittenEventArgs @event)
        {
            if (!observable.HasObservers)
            {
                return;
            }

            try
            {
                switch (@event.EventId)
                {
                case GCStartEventId:
                    OnGCStart(@event);
                    break;

                case GCEndEventId:
                    OnGCEnd(@event);
                    break;
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }
        }
예제 #2
0
        private ProcessStat ReadProcessStat()
        {
            var result = new ProcessStat();

            try
            {
                if (FileParser.TrySplitLine(processStatReader.ReadFirstLine(), 15, out var parts))
                {
                    if (ulong.TryParse(parts[13], out var utime))
                    {
                        result.UserTime = utime;
                    }

                    if (ulong.TryParse(parts[14], out var stime))
                    {
                        result.SystemTime = stime;
                    }
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }

            return(result);
        }
예제 #3
0
        private SystemStat ReadSystemStat()
        {
            var result = new SystemStat();

            try
            {
                if (FileParser.TrySplitLine(systemStatReader.ReadFirstLine(), 5, out var parts) && parts[0] == "cpu")
                {
                    if (ulong.TryParse(parts[1], out var utime))
                    {
                        result.UserTime = utime;
                    }

                    if (ulong.TryParse(parts[3], out var stime))
                    {
                        result.SystemTime = stime;
                    }

                    if (ulong.TryParse(parts[4], out var itime))
                    {
                        result.IdleTime = itime;
                    }
                }

                result.CpuCount = systemStatReader.ReadLines().Count(line => line.StartsWith("cpu")) - 1;
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }

            return(result);
        }
예제 #4
0
 private int?GetProcessorCount()
 {
     try
     {
         return(cpuInfoReader.ReadLines().Count(x => x.Contains("processor")));
     }
     catch (Exception error)
     {
         InternalErrorLogger.Warn(error);
         return(null);
     }
 }
예제 #5
0
        private MemoryInfo ReadMemoryInfo()
        {
            var result = new MemoryInfo();

            try
            {
                foreach (var line in memoryReader.ReadLines())
                {
                    if (FileParser.TryParseLong(line, "MemTotal", out var memTotal))
                    {
                        result.TotalMemory = memTotal * 1024;
                    }

                    if (FileParser.TryParseLong(line, "MemAvailable", out var memAvailable))
                    {
                        result.AvailableMemory = memAvailable * 1024;
                    }

                    if (FileParser.TryParseLong(line, "Cached", out var memCached))
                    {
                        result.CacheMemory = memCached * 1024;
                    }

                    if (FileParser.TryParseLong(line, "Slab", out var memKernel))
                    {
                        result.KernelMemory = memKernel * 1024;
                    }

                    if (FileParser.TryParseLong(line, "MemFree", out var memFree))
                    {
                        result.FreeMemory = memFree * 1024;
                    }
                }

                foreach (var line in vmStatReader.ReadLines())
                {
                    if (FileParser.TryParseLong(line, "pgmajfault", out var hardPageFaultCount))
                    {
                        result.MajorPageFaultCount = hardPageFaultCount;
                    }
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }

            return(result);
        }
        private static void CollectHandlesCount(CurrentProcessMetrics metrics)
        {
            try
            {
                if (!GetProcessHandleCount(CurrentProcessHandle, out var handleCount))
                {
                    WinMetricsCollectorHelper.ThrowOnError();
                }

                metrics.HandlesCount = (int)handleCount;
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }
        }
        private static unsafe void CollectMemoryMetrics(CurrentProcessMetrics metrics)
        {
            try
            {
                if (!GetProcessMemoryInfo(CurrentProcessHandle, out var memoryCounters, sizeof(PROCESS_MEMORY_COUNTERS_EX)))
                {
                    WinMetricsCollectorHelper.ThrowOnError();
                }

                metrics.MemoryResident = (long)memoryCounters.WorkingSetSize;
                metrics.MemoryPrivate  = (long)memoryCounters.PrivateUsage;
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }
        }
예제 #8
0
        private PerformanceInfo ReadPerformanceInfo()
        {
            var result = new PerformanceInfo();

            try
            {
                var processDirectories = Directory.EnumerateDirectories("/proc/")
                                         .Where(x => pidRegex.IsMatch(x));

                var processCount = 0;
                var threadCount  = 0;

                foreach (var processDirectory in processDirectories)
                {
                    try
                    {
                        threadCount += Directory.EnumerateDirectories(Path.Combine(processDirectory, "task")).Count();
                    }
                    catch (DirectoryNotFoundException)
                    {
                        // NOTE: Ignored due to process already exited so we don't have to count it's threads and just want to continue.
                        continue;
                    }

                    processCount++;
                }

                result.ProcessCount = processCount;
                result.ThreadCount  = threadCount;

                if (FileParser.TrySplitLine(descriptorInfoReader.ReadFirstLine(), 3, out var parts) &&
                    int.TryParse(parts[0], out var allocatedDescriptors) &&
                    int.TryParse(parts[1], out var freeDescriptors))
                {
                    result.HandleCount = allocatedDescriptors - freeDescriptors;
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }

            return(result);
        }
예제 #9
0
        private void UpdateMountMap()
        {
            mountDiskMap = new Dictionary <string, string>();

            try
            {
                foreach (var mountLine in mountsReaderLinux.ReadLines())
                {
                    if (FileParser.TrySplitLine(mountLine, 2, out var parts) && parts[0].Contains("/dev/"))
                    {
                        mountDiskMap[parts[1]] = parts[0];
                    }
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }
        }
예제 #10
0
        private ProcessStatus ReadProcessStatus()
        {
            var result = new ProcessStatus();

            try
            {
                result.FileDescriptorsCount = Directory.EnumerateFiles("/proc/self/fd/").Count();
            }
            catch (DirectoryNotFoundException)
            {
                // NOTE: Ignored due to process already exited so we don't have to count it's file descriptors count.
                result.FileDescriptorsCount = 0;
            }

            try
            {
                foreach (var line in processStatusReader.ReadLines())
                {
                    if (FileParser.TryParseLong(line, "RssAnon", out var vmRss))
                    {
                        result.VirtualMemoryResident = vmRss * 1024L;
                    }

                    if (FileParser.TryParseLong(line, "VmData", out var vmData))
                    {
                        result.VirtualMemoryData = vmData * 1024L;
                    }

                    if (result.Filled)
                    {
                        break;
                    }
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }

            return(result);
        }
        private static bool TryReadSpeed(string interfaceName, out string result)
        {
            var path = $"/sys/class/net/{interfaceName}/speed";

            try
            {
                result = File.ReadAllText(path);
                return(true);
            }
            catch (Exception error)
            {
                // NOTE: We expect teaming interface to not be able to read speed directly.
                if (!IsTeamingInterface(interfaceName))
                {
                    InternalErrorLogger.Warn(error);
                }

                result = null;
                return(false);
            }
        }
예제 #12
0
        private IEnumerable <DiskSpaceInfo> GetDiskSpaceInfos()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                UpdateMountMap();
            }

            // NOTE: We are trying to get information from disks which are not ready. This is made for docker compatibility (some of the drives are shown as NotReady for some reason).
            // NOTE: Also, the fact that drive has IsReady set to true doesn't mean much: it can still throw IOExceptions.
            // NOTE: See https://docs.microsoft.com/en-us/dotnet/api/system.io.driveinfo.isready for details.
            foreach (var drive in DriveInfo.GetDrives().Where(x => systemFilter(x) && x.DriveType == DriveType.Fixed))
            {
                var result = new DiskSpaceInfo();

                try
                {
                    result.DiskName           = nameFormatter(drive.Name);
                    result.RootDirectory      = drive.RootDirectory.FullName;
                    result.FreeBytes          = drive.TotalFreeSpace;
                    result.TotalCapacityBytes = drive.TotalSize;
                    if (result.TotalCapacityBytes != 0)
                    {
                        result.FreePercent = result.FreeBytes * 100d / result.TotalCapacityBytes;
                    }
                }
                catch (Exception error)
                {
                    if (drive.IsReady)
                    {
                        InternalErrorLogger.Warn(error);
                    }
                    continue;
                }

                yield return(result);
            }
        }
        private void CollectCpuUtilization(CurrentProcessMetrics metrics)
        {
            try
            {
                if (!WinMetricsCollectorHelper.GetSystemTimes(out _, out var systemKernel, out var systemUser))
                {
                    WinMetricsCollectorHelper.ThrowOnError();
                }

                if (!GetProcessTimes(CurrentProcessHandle, out _, out _, out var processKernel, out var processUser))
                {
                    WinMetricsCollectorHelper.ThrowOnError();
                }

                var systemTime  = systemKernel.ToUInt64() + systemUser.ToUInt64();
                var processTime = processKernel.ToUInt64() + processUser.ToUInt64();

                cpuCollector.Collect(metrics, systemTime, processTime);
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }
        }
예제 #14
0
        private SystemStat ReadSystemStat()
        {
            var result = new SystemStat();

            try
            {
                if (FileParser.TrySplitLine(systemStatReader.ReadFirstLine(), 7, out var parts) && parts[0] == "cpu")
                {
                    if (ulong.TryParse(parts[1], out var utime))
                    {
                        result.UserTime = utime;
                    }

                    if (ulong.TryParse(parts[2], out var ntime))
                    {
                        result.NicedTime = ntime;
                    }

                    if (ulong.TryParse(parts[3], out var stime))
                    {
                        result.SystemTime = stime;
                    }

                    if (ulong.TryParse(parts[4], out var itime))
                    {
                        result.IdleTime = itime;
                    }
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }

            return(result);
        }
예제 #15
0
        private List <DiskStats> ParseDiskstats(IEnumerable <string> diskstats)
        {
            var disksStats = new List <DiskStats>();

            try
            {
                foreach (var line in diskstats)
                {
                    // NOTE: In the most basic form there are 14 parts.
                    // NOTE: See https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats for details.
                    if (FileParser.TrySplitLine(line, 14, out var parts) && IsDiskNumber(parts[0]) && IsWholeDiskNumber(parts[1]))
                    {
                        var stats = new DiskStats {
                            DiskName = parts[2]
                        };

                        if (long.TryParse(parts[3], out var readsCount))
                        {
                            stats.ReadsCount = readsCount;
                        }

                        if (long.TryParse(parts[5], out var sectorsRead))
                        {
                            stats.SectorsReadCount = sectorsRead;
                        }

                        if (long.TryParse(parts[6], out var msSpentReading))
                        {
                            stats.MsSpentReading = msSpentReading;
                        }

                        if (long.TryParse(parts[7], out var writesCount))
                        {
                            stats.WritesCount = writesCount;
                        }

                        if (long.TryParse(parts[9], out var sectorsWritten))
                        {
                            stats.SectorsWrittenCount = sectorsWritten;
                        }

                        if (long.TryParse(parts[10], out var msSpentWriting))
                        {
                            stats.MsSpentWriting = msSpentWriting;
                        }

                        if (long.TryParse(parts[11], out var currentQueueLength))
                        {
                            stats.CurrentQueueLength = currentQueueLength;
                        }

                        if (long.TryParse(parts[12], out var msSpentDoingIo))
                        {
                            stats.MsSpentDoingIo = msSpentDoingIo;
                        }

                        disksStats.Add(stats);
                    }
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }

            return(disksStats);
        }
        private IEnumerable <NetworkUsage> ParseNetworkUsage()
        {
            var networkInterfacesUsage = new Dictionary <string, NetworkUsage>();

            // NOTE: 'eth' stands for ethernet interface.
            // NOTE: 'en' stands for ethernet interface in 'Predictable network interface device names scheme'.
            // NOTE: 'em' stands for Lan-On-Motherboard interfaces.
            // NOTE: 'p' stands for PCI add-in interfaces.
            bool ShouldBeCounted(string interfaceName)
            => interfaceName.StartsWith("eth") ||
            interfaceName.StartsWith("en") ||
            interfaceName.StartsWith("em") ||
            interfaceName.StartsWith("p") ||
            IsTeamingInterface(interfaceName);

            IEnumerable <NetworkUsage> FilterDisabledInterfaces(IEnumerable <NetworkUsage> interfaceUsages)
            => interfaceUsages.Where(x => x.NetworkMaxMBitsPerSecond != -1);

            NetworkUsage CreateNetworkUsage(string interfaceName, long receivedBytes, long sentBytes) =>
            IsTeamingInterface(interfaceName)
                    ? new TeamingNetworkUsage
            {
                InterfaceName = interfaceName,
                ReceivedBytes = receivedBytes,
                SentBytes     = sentBytes
            }

                    : new NetworkUsage
            {
                InterfaceName = interfaceName,
                ReceivedBytes = receivedBytes,
                SentBytes     = sentBytes
            };

            try
            {
                // NOTE: Skip first 2 lines because they contain format info. See https://man7.org/linux/man-pages/man5/proc.5.html for details.
                foreach (var line in networkUsageReader.ReadLines().Skip(2))
                {
                    if (FileParser.TrySplitLine(line, 17, out var parts) &&
                        ShouldBeCounted(parts[0]) &&
                        long.TryParse(parts[1], out var receivedBytes) &&
                        long.TryParse(parts[9], out var sentBytes))
                    {
                        var interfaceName = parts[0].TrimEnd(':');
                        networkInterfacesUsage[interfaceName] = CreateNetworkUsage(interfaceName, receivedBytes, sentBytes);
                    }
                }

                // NOTE: See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-net for details.
                // NOTE: This value equals -1 if interface is disabled, so we will filter this values out later.
                foreach (var networkUsage in networkInterfacesUsage.Values)
                {
                    if (TryReadSpeed(networkUsage.InterfaceName, out var result) && int.TryParse(result, out var speed))
                    {
                        networkUsage.NetworkMaxMBitsPerSecond = speed;
                    }
                    else
                    {
                        // NOTE: We don't need zero values. Mark this interface disabled for now. It's speed may be calculated later if it is a teaming interface.
                        networkUsage.NetworkMaxMBitsPerSecond = -1;
                    }
                }

                // NOTE: We don't check if interface speed was already calculated because we need ChildInterfaces property in any case.
                var teamingInterfaces = networkInterfacesUsage.Values.OfType <TeamingNetworkUsage>();

                foreach (var teamingInterface in teamingInterfaces)
                {
                    if (!TryFillTeamingInfo(networkInterfacesUsage, teamingInterface, out var error))
                    {
                        InternalErrorLogger.Warn(error);
                    }
                }
            }
            catch (Exception error)
            {
                InternalErrorLogger.Warn(error);
            }

            return(FilterDisabledInterfaces(networkInterfacesUsage.Values));
        }