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); } }
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); }
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); }
private int?GetProcessorCount() { try { return(cpuInfoReader.ReadLines().Count(x => x.Contains("processor"))); } catch (Exception error) { InternalErrorLogger.Warn(error); return(null); } }
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); } }
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); }
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); } }
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); } }
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); } }
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); }
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)); }