/// <inheritdoc/> public override async Task ObserveAsync(CancellationToken token) { // If set, this observer will only run during the supplied interval. // See Settings.xml, CertificateObserverConfiguration section, RunInterval parameter for an example. if (RunInterval > TimeSpan.MinValue && DateTime.Now.Subtract(LastRunDateTime) < RunInterval) { return; } bool initialized = Initialize(); Token = token; if (!initialized) { HealthReporter.ReportFabricObserverServiceHealth( FabricServiceContext.ServiceName.OriginalString, ObserverName, HealthState.Warning, "This observer was unable to initialize correctly due to missing configuration info."); return; } try { perfCounters = new WindowsPerfCounters(); diskUsage = new DiskUsage(); foreach (var app in targetList) { Token.ThrowIfCancellationRequested(); if (string.IsNullOrWhiteSpace(app.Target) && string.IsNullOrWhiteSpace(app.TargetType)) { continue; } await MonitorAppAsync(app).ConfigureAwait(true); } await ReportAsync(token).ConfigureAwait(true); LastRunDateTime = DateTime.Now; } finally { // Clean up. diskUsage?.Dispose(); diskUsage = null; perfCounters?.Dispose(); perfCounters = null; } }
/// <inheritdoc/> public override async Task ObserveAsync(CancellationToken token) { // If set, this observer will only run during the supplied interval. // See Settings.xml, CertificateObserverConfiguration section, RunInterval parameter for an example... if (this.RunInterval > TimeSpan.MinValue && DateTime.Now.Subtract(this.LastRunDateTime) < this.RunInterval) { return; } this.SetErrorWarningThresholds(); DriveInfo[] allDrives = DriveInfo.GetDrives(); var diskUsage = new DiskUsage(); if (ObserverManager.ObserverWebAppDeployed) { this.diskInfo = new StringBuilder(); } try { int readyCount = 0; foreach (var d in allDrives) { token.ThrowIfCancellationRequested(); if (d.IsReady) { readyCount++; // This section only needs to run if you have the FabricObserverWebApi app installed... if (ObserverManager.ObserverWebAppDeployed) { this.diskInfo.AppendFormat("\n\nDrive Name: {0}\n", d.Name); // Logging... this.diskInfo.AppendFormat("Drive Type: {0}\n", d.DriveType); this.diskInfo.AppendFormat(" Volume Label : {0}\n", d.VolumeLabel); this.diskInfo.AppendFormat(" Filesystem : {0}\n", d.DriveFormat); this.diskInfo.AppendFormat(" Total Disk Size: {0} GB\n", d.TotalSize / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" Root Directory : {0}\n", d.RootDirectory); this.diskInfo.AppendFormat(" Free User : {0} GB\n", d.AvailableFreeSpace / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" Free Total: {0} GB\n", d.TotalFreeSpace / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" % Used : {0}%\n", diskUsage.GetCurrentDiskSpaceUsedPercent(d.Name)); } // Setup monitoring data structures... string id = d.Name.Substring(0, 1); // Since these live across iterations, do not duplicate them in the containing list... // Disk space %... if (!this.diskSpacePercentageUsageData.Any(data => data.Id == id)) { this.diskSpacePercentageUsageData.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.DiskSpaceUsagePercentage, id)); } if (!this.diskSpaceUsageData.Any(data => data.Id == id)) { this.diskSpaceUsageData.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.DiskSpaceUsageMB, id)); } if (!this.diskSpaceAvailableData.Any(data => data.Id == id)) { this.diskSpaceAvailableData.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.DiskSpaceAvailableMB, id)); } if (!this.diskSpaceTotalData.Any(data => data.Id == id)) { this.diskSpaceTotalData.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.DiskSpaceTotalMB, id)); } // Current disk queue length... if (!this.diskAverageQueueLengthData.Any(data => data.Id == id)) { this.diskAverageQueueLengthData.Add(new FabricResourceUsageData <float>(ErrorWarningProperty.DiskAverageQueueLength, id)); } // Generate data over time (_monitorDuration...) for use in ReportAsync health analysis... this.stopWatch?.Start(); while (this.stopWatch?.Elapsed <= this.monitorDuration) { token.ThrowIfCancellationRequested(); this.diskSpacePercentageUsageData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetCurrentDiskSpaceUsedPercent(id)); this.diskSpaceUsageData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetUsedDiskSpace(id, SizeUnit.Megabytes)); this.diskSpaceAvailableData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetAvailabeDiskSpace(id, SizeUnit.Megabytes)); this.diskSpaceTotalData.FirstOrDefault( x => x.Id == id) .Data.Add(DiskUsage.GetTotalDiskSpace(id, SizeUnit.Megabytes)); this.diskAverageQueueLengthData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetAverageDiskQueueLength(d.Name.Substring(0, 2))); Thread.Sleep(250); } // This section only needs to run if you have the FabricObserverWebApi app installed... if (ObserverManager.ObserverWebAppDeployed) { this.diskInfo.AppendFormat( "{0}", this.GetWindowsPerfCounterDetailsText( this.diskAverageQueueLengthData.FirstOrDefault( x => x.Id == d.Name.Substring(0, 1)).Data, "Avg. Disk Queue Length")); } this.stopWatch.Stop(); this.stopWatch.Reset(); } } } finally { diskUsage.Dispose(); diskUsage = null; } await this.ReportAsync(token).ConfigureAwait(true); this.LastRunDateTime = DateTime.Now; }
private void GetComputerInfo(CancellationToken token) { ManagementObjectSearcher win32OSInfo = null; ManagementObjectCollection results = null; var sb = new StringBuilder(); var diskUsage = new DiskUsage(); string osName = string.Empty; string osVersion = string.Empty; string numProcs = "-1"; string lastBootTime = string.Empty; string installDate = string.Empty; int driveCount = 0; try { win32OSInfo = new ManagementObjectSearcher("SELECT Caption,Version,Status,OSLanguage,NumberOfProcesses,FreePhysicalMemory,FreeVirtualMemory,TotalVirtualMemorySize,TotalVisibleMemorySize,InstallDate,LastBootUpTime FROM Win32_OperatingSystem"); results = win32OSInfo.Get(); sb.AppendLine($"\nOS Info:\n"); foreach (var prop in results) { token.ThrowIfCancellationRequested(); foreach (var p in prop.Properties) { token.ThrowIfCancellationRequested(); string n = p.Name; string v = p.Value.ToString(); if (string.IsNullOrEmpty(n) || string.IsNullOrEmpty(v)) { continue; } if (n.ToLower() == "caption") { n = "OS"; osName = v; } if (n.ToLower() == "numberofprocesses") { // Number of running processes numProcs = v; // Also show number of processors on machine (logical cores)... sb.AppendLine($"LogicalProcessorCount: {Environment.ProcessorCount}"); } if (n.ToLower() == "status") { this.osStatus = v; } if (n.ToLower() == "version") { osVersion = v; } if (n.ToLower().Contains("bootuptime")) { v = ManagementDateTimeConverter.ToDateTime(v).ToString(); lastBootTime = v; } if (n.ToLower().Contains("date")) { v = ManagementDateTimeConverter.ToDateTime(v).ToString(); installDate = v; } if (n.ToLower().Contains("memory")) { if (n.ToLower().Contains("freephysical") || n.ToLower().Contains("freevirtual")) { continue; } // For output... int i = int.Parse(v) / 1024 / 1024; v = i.ToString() + " GB"; // TotalVisible only needs to be set once... if (n.ToLower().Contains("totalvisible")) { this.totalVisibleMemoryGB = i; } } sb.AppendLine($"{n}: {v}"); } } try { // We only care about ready drives (so, things like an empty DVD drive are not interesting...) driveCount = DriveInfo.GetDrives().Where(d => d.IsReady).Count(); sb.AppendLine($"LogicalDriveCount: {driveCount}"); } catch (ArgumentException) { } catch (IOException) { } catch (UnauthorizedAccessException) { } this.osReport = sb.ToString(); // Active, bound ports... int activePorts = NetworkUsage.GetActivePortCount(); // Active, ephemeral ports... int activeEphemeralPorts = NetworkUsage.GetActiveEphemeralPortCount(); var dynamicPortRange = NetworkUsage.TupleGetDynamicPortRange(); string clusterManifestXml = null; string osEphemeralPortRange = string.Empty; string fabricAppPortRange = string.Empty; if (this.IsTestRun) { clusterManifestXml = File.ReadAllText(this.TestManifestPath); } else { clusterManifestXml = this.FabricClientInstance.ClusterManager.GetClusterManifestAsync().GetAwaiter().GetResult(); } var appPortRange = NetworkUsage.TupleGetFabricApplicationPortRangeForNodeType(this.FabricServiceContext.NodeContext.NodeType, clusterManifestXml); // Enabled Firewall rules... int firewalls = NetworkUsage.GetActiveFirewallRulesCount(); if (firewalls > -1) { this.osReport += $"EnabledFireWallRules: {firewalls}\r\n"; } if (activePorts > -1) { this.osReport += $"TotalActiveTCPPorts: {activePorts}\r\n"; } if (dynamicPortRange.Item1 > -1) { osEphemeralPortRange = $"{dynamicPortRange.Item1} - {dynamicPortRange.Item2}"; this.osReport += $"WindowsEphemeralTCPPortRange: {osEphemeralPortRange}\r\n"; } if (appPortRange.Item1 > -1) { fabricAppPortRange = $"{appPortRange.Item1} - {appPortRange.Item2}"; this.osReport += $"FabricApplicationTCPPortRange: {fabricAppPortRange}\r\n"; } if (activeEphemeralPorts > -1) { this.osReport += $"ActiveEphemeralTCPPorts: {activeEphemeralPorts}\r\n"; } string osHotFixes = GetWindowsHotFixes(token); if (!string.IsNullOrEmpty(osHotFixes)) { this.osReport += $"\nOS Patches/Hot Fixes:\n\n{osHotFixes}\r\n"; } // ETW... if (this.IsEtwEnabled) { Logger.EtwLogger?.Write( $"FabricObserverDataEvent", new { Level = 0, // Info Node = this.NodeName, Observer = this.ObserverName, OS = osName, OSVersion = osVersion, OSInstallDate = installDate, LastBootUpTime = lastBootTime, TotalMemorySizeGB = this.totalVisibleMemoryGB, LogicalProcessorCount = Environment.ProcessorCount, LogicalDriveCount = driveCount, NumberOfRunningProcesses = int.Parse(numProcs), ActiveFirewallRules = firewalls, ActivePorts = activePorts, ActiveEphemeralPorts = activeEphemeralPorts, WindowsDynamicPortRange = osEphemeralPortRange, FabricAppPortRange = fabricAppPortRange, HotFixes = osHotFixes.Replace("\r\n", ", ").TrimEnd(','), }); } } catch (ManagementException) { } catch (Exception e) { this.HealthReporter.ReportFabricObserverServiceHealth( this.FabricServiceContext.ServiceName.OriginalString, this.ObserverName, HealthState.Error, $"Unhandled exception processing OS information: {e.Message}: \n {e.StackTrace}"); throw; } finally { results?.Dispose(); win32OSInfo?.Dispose(); diskUsage?.Dispose(); sb.Clear(); } }
private void GetComputerInfo(CancellationToken token) { ManagementObjectSearcher win32OSInfo = null; ManagementObjectCollection results = null; var sb = new StringBuilder(); var diskUsage = new DiskUsage(); string osName = string.Empty; string osVersion = string.Empty; int numProcs = 0; string lastBootTime = string.Empty; string installDate = string.Empty; int logicalProcessorCount = Environment.ProcessorCount; int logicalDriveCount = 0; int activePorts = 0; int activeEphemeralPorts = 0; int totalVirtMem = 0; string fabricAppPortRange = string.Empty; string osLang = string.Empty; double freePhysicalMem = 0; double freeVirtualMem = 0; try { win32OSInfo = new ManagementObjectSearcher("SELECT Caption,Version,Status,OSLanguage,NumberOfProcesses,FreePhysicalMemory,FreeVirtualMemory,TotalVirtualMemorySize,TotalVisibleMemorySize,InstallDate,LastBootUpTime FROM Win32_OperatingSystem"); results = win32OSInfo.Get(); foreach (var prop in results) { token.ThrowIfCancellationRequested(); foreach (var p in prop.Properties) { token.ThrowIfCancellationRequested(); string name = p.Name; string value = p.Value.ToString(); if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) { continue; } if (name.ToLower() == "caption") { osName = value; } else if (name.ToLower() == "numberofprocesses") { // Number of running processes _ = int.TryParse(value, out numProcs); } else if (name.ToLower() == "status") { this.osStatus = value; } else if (name.ToLower() == "oslanguage") { osLang = value; } else if (name.ToLower() == "version") { osVersion = value; } else if (name.ToLower().Contains("bootuptime")) { value = ManagementDateTimeConverter.ToDateTime(value).ToUniversalTime().ToString("o"); lastBootTime = value; } else if (name.ToLower().Contains("date")) { value = ManagementDateTimeConverter.ToDateTime(value).ToUniversalTime().ToString("o"); installDate = value; } else if (name.ToLower().Contains("memory")) { // For output. int i = int.Parse(value) / 1024 / 1024; // TotalVisible only needs to be set once. if (name.ToLower().Contains("totalvisible")) { this.totalVisibleMemoryGB = i; } else if (name.ToLower().Contains("totalvirtual")) { totalVirtMem = i; } else if (name.ToLower().Contains("freephysical")) { _ = double.TryParse(value, out freePhysicalMem); } else if (name.ToLower().Contains("freevirtual")) { _ = double.TryParse(value, out freeVirtualMem); } } } } // Active, bound ports. activePorts = NetworkUsage.GetActivePortCount(); // Active, ephemeral ports. activeEphemeralPorts = NetworkUsage.GetActiveEphemeralPortCount(); var dynamicPortRange = NetworkUsage.TupleGetDynamicPortRange(); string clusterManifestXml = null; string osEphemeralPortRange = string.Empty; fabricAppPortRange = string.Empty; if (this.IsTestRun) { clusterManifestXml = File.ReadAllText(this.TestManifestPath); } else { clusterManifestXml = this.FabricClientInstance.ClusterManager.GetClusterManifestAsync(this.AsyncClusterOperationTimeoutSeconds, this.Token).GetAwaiter().GetResult(); } var appPortRange = NetworkUsage.TupleGetFabricApplicationPortRangeForNodeType(this.FabricServiceContext.NodeContext.NodeType, clusterManifestXml); int firewalls = NetworkUsage.GetActiveFirewallRulesCount(); // OS info. sb.AppendLine("OS Information:\r\n"); sb.AppendLine($"Name: {osName}"); sb.AppendLine($"Version: {osVersion}"); sb.AppendLine($"InstallDate: {installDate}"); sb.AppendLine($"LastBootUpTime*: {lastBootTime}"); sb.AppendLine($"OSLanguage: {osLang}"); sb.AppendLine($"OSHealthStatus*: {this.osStatus}"); sb.AppendLine($"NumberOfProcesses*: {numProcs}"); if (dynamicPortRange.Item1 > -1) { osEphemeralPortRange = $"{dynamicPortRange.Item1} - {dynamicPortRange.Item2}"; sb.AppendLine($"WindowsEphemeralTCPPortRange: {osEphemeralPortRange} (Active*: {activeEphemeralPorts})"); } if (appPortRange.Item1 > -1) { fabricAppPortRange = $"{appPortRange.Item1} - {appPortRange.Item2}"; sb.AppendLine($"FabricApplicationTCPPortRange: {fabricAppPortRange}"); } if (firewalls > -1) { sb.AppendLine($"ActiveFirewallRules*: {firewalls}"); } if (activePorts > -1) { sb.AppendLine($"TotalActiveTCPPorts*: {activePorts}"); } // Hardware info. // Proc/Mem sb.AppendLine("\r\nHardware Information:\r\n"); sb.AppendLine($"LogicalProcessorCount: {logicalProcessorCount}"); sb.AppendLine($"TotalVirtualMemorySize: {totalVirtMem} GB"); sb.AppendLine($"TotalVisibleMemorySize: {this.totalVisibleMemoryGB} GB"); sb.AppendLine($"FreePhysicalMemory*: {Math.Round(freePhysicalMem / 1024 / 1024, 2)} GB"); sb.AppendLine($"FreeVirtualMemory*: {Math.Round(freeVirtualMem / 1024 / 1024, 2)} GB"); // Disk var drivesInformation = diskUsage.GetCurrentDiskSpaceTotalAndUsedPercentAllDrives(SizeUnit.Gigabytes); logicalDriveCount = drivesInformation.Count; sb.AppendLine($"LogicalDriveCount: {logicalDriveCount}"); foreach (var tuple in drivesInformation) { string systemDrv = "Data"; if (Environment.SystemDirectory.Substring(0, 1) == tuple.Item1) { systemDrv = "System"; } sb.AppendLine($"Drive {tuple.Item1} ({systemDrv}) Size: {tuple.Item2} GB"); sb.AppendLine($"Drive {tuple.Item1} ({systemDrv}) Consumed*: {tuple.Item3}%"); } string osHotFixes = GetWindowsHotFixes(token); if (!string.IsNullOrEmpty(osHotFixes)) { sb.AppendLine($"\nWindows Patches/Hot Fixes*:\n\n{osHotFixes}"); } // Dynamic info qualifier (*) sb.AppendLine($"\n* Dynamic data."); this.osReport = sb.ToString(); // ETW. if (this.IsEtwEnabled) { Logger.EtwLogger?.Write( $"FabricObserverDataEvent", new { Level = 0, // Info Node = this.NodeName, Observer = this.ObserverName, OS = osName, OSVersion = osVersion, OSInstallDate = installDate, LastBootUpTime = lastBootTime, TotalMemorySizeGB = this.totalVisibleMemoryGB, LogicalProcessorCount = logicalProcessorCount, LogicalDriveCount = logicalDriveCount, NumberOfRunningProcesses = numProcs, ActiveFirewallRules = firewalls, ActivePorts = activePorts, ActiveEphemeralPorts = activeEphemeralPorts, WindowsDynamicPortRange = osEphemeralPortRange, FabricAppPortRange = fabricAppPortRange, HotFixes = GetWindowsHotFixes(token, false).Replace("\r\n", ", ").TrimEnd(','), }); } } catch (ManagementException) { } catch (Exception e) { this.HealthReporter.ReportFabricObserverServiceHealth( this.FabricServiceContext.ServiceName.OriginalString, this.ObserverName, HealthState.Error, $"Unhandled exception processing OS information: {e.Message}: \n {e.StackTrace}"); throw; } finally { results?.Dispose(); win32OSInfo?.Dispose(); diskUsage?.Dispose(); sb.Clear(); } }
/// <inheritdoc/> public override async Task ObserveAsync(CancellationToken token) { this.SetErrorWarningThresholds(); DriveInfo[] allDrives = DriveInfo.GetDrives(); var diskUsage = new DiskUsage(); this.diskInfo = new StringBuilder(); try { int readyCount = 0; foreach (var d in allDrives) { token.ThrowIfCancellationRequested(); if (d.IsReady) { readyCount++; // This section only needs to run if you have the FabricObserverWebApi app installed... // Always log since these are the identifiers of each detected drive... this.diskInfo.AppendFormat("\n\nDrive Name: {0}\n", d.Name); // Logging... this.diskInfo.AppendFormat("Drive Type: {0}\n", d.DriveType); this.diskInfo.AppendFormat(" Volume Label : {0}\n", d.VolumeLabel); this.diskInfo.AppendFormat(" Filesystem : {0}\n", d.DriveFormat); this.diskInfo.AppendFormat(" Total Disk Size: {0} GB\n", d.TotalSize / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" Root Directory : {0}\n", d.RootDirectory); this.diskInfo.AppendFormat(" Free User : {0} GB\n", d.AvailableFreeSpace / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" Free Total: {0} GB\n", d.TotalFreeSpace / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" % Used : {0}%\n", diskUsage.GetCurrentDiskSpaceUsedPercent(d.Name)); // Setup monitoring data structures... string id = d.Name.Substring(0, 1); // Since these live across iterations, do not duplicate them in the containing list... if (!this.diskIOReadsData.Any(data => data.Id == id)) { this.diskIOReadsData.Add(new FabricResourceUsageData <float>("Disk sec/Read (ms)", id)); } if (!this.diskIOWritesData.Any(data => data.Id == id)) { this.diskIOWritesData.Add(new FabricResourceUsageData <float>("Disk sec/Write (ms)", id)); } // Disk space %... if (!this.diskSpacePercentageUsageData.Any(data => data.Id == id)) { this.diskSpacePercentageUsageData.Add(new FabricResourceUsageData <double>("Disk Space Consumption %", id)); } if (!this.diskSpaceUsageData.Any(data => data.Id == id)) { this.diskSpaceUsageData.Add(new FabricResourceUsageData <double>("Disk Space Consumption MB", id)); } if (!this.diskSpaceAvailableData.Any(data => data.Id == id)) { this.diskSpaceAvailableData.Add(new FabricResourceUsageData <double>("Disk Space Available MB", id)); } if (!this.diskSpaceTotalData.Any(data => data.Id == id)) { this.diskSpaceTotalData.Add(new FabricResourceUsageData <double>("Disk Space Total MB", id)); } // Current disk queue length... if (!this.diskAverageQueueLengthData.Any(data => data.Id == id)) { this.diskAverageQueueLengthData.Add(new FabricResourceUsageData <float>("Average Disk Queue Length", id)); } // Generate data over time (_monitorDuration...) for use in ReportAsync health analysis... this.stopWatch?.Start(); while (this.stopWatch?.Elapsed <= this.monitorDuration) { token.ThrowIfCancellationRequested(); this.diskIOReadsData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.PerfCounterGetDiskIOInfo(d.Name.Substring(0, 2), "LogicalDisk", "Avg. Disk sec/Read") * 1000); this.diskIOWritesData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.PerfCounterGetDiskIOInfo(d.Name.Substring(0, 2), "LogicalDisk", "Avg. Disk sec/Write") * 1000); this.diskSpacePercentageUsageData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetCurrentDiskSpaceUsedPercent(id)); this.diskSpaceUsageData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetUsedDiskSpace(id, SizeUnit.Megabytes)); this.diskSpaceAvailableData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetAvailabeDiskSpace(id, SizeUnit.Megabytes)); this.diskSpaceTotalData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetTotalDiskSpace(id, SizeUnit.Megabytes)); this.diskAverageQueueLengthData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetAverageDiskQueueLength(d.Name.Substring(0, 2))); Thread.Sleep(250); } // This section only needs to run if you have the FabricObserverWebApi app installed... this.diskInfo.AppendFormat( "{0}", this.GetWindowsPerfCounterDetailsText( this.diskIOReadsData.FirstOrDefault( x => x.Id == d.Name.Substring(0, 1)).Data, "Avg. Disk sec/Read")); this.diskInfo.AppendFormat( "{0}", this.GetWindowsPerfCounterDetailsText( this.diskIOWritesData.FirstOrDefault( x => x.Id == d.Name.Substring(0, 1)).Data, "Avg. Disk sec/Write")); this.diskInfo.AppendFormat( "{0}", this.GetWindowsPerfCounterDetailsText( this.diskAverageQueueLengthData.FirstOrDefault( x => x.Id == d.Name.Substring(0, 1)).Data, "Avg. Disk Queue Length")); this.stopWatch.Stop(); this.stopWatch.Reset(); } } } finally { diskUsage.Dispose(); diskUsage = null; } await this.ReportAsync(token).ConfigureAwait(true); this.LastRunDateTime = DateTime.Now; }
private async Task GetComputerInfoAsync(CancellationToken token) { ManagementObjectSearcher win32OsInfo = null; ManagementObjectCollection results = null; var sb = new StringBuilder(); var diskUsage = new DiskUsage(); string osName = string.Empty; string osVersion = string.Empty; int numProcs = 0; string lastBootTime = string.Empty; string installDate = string.Empty; int logicalProcessorCount = Environment.ProcessorCount; int totalVirtualMem = 0; string osLang = string.Empty; double freePhysicalMem = 0; double freeVirtualMem = 0; try { win32OsInfo = new ManagementObjectSearcher("SELECT Caption,Version,Status,OSLanguage,NumberOfProcesses,FreePhysicalMemory,FreeVirtualMemory,TotalVirtualMemorySize,TotalVisibleMemorySize,InstallDate,LastBootUpTime FROM Win32_OperatingSystem"); results = win32OsInfo.Get(); foreach (var prop in results) { token.ThrowIfCancellationRequested(); foreach (var p in prop.Properties) { token.ThrowIfCancellationRequested(); string name = p.Name; string value = p.Value.ToString(); if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) { continue; } switch (name.ToLower()) { case "caption": osName = value; break; case "numberofprocesses": _ = int.TryParse(value, out numProcs); break; case "status": this.osStatus = value; break; case "oslanguage": osLang = value; break; case "version": osVersion = value; break; default: { if (name.ToLower().Contains("bootuptime")) { value = ManagementDateTimeConverter.ToDateTime(value).ToUniversalTime().ToString("o"); lastBootTime = value; } else if (name.ToLower().Contains("date")) { value = ManagementDateTimeConverter.ToDateTime(value).ToUniversalTime().ToString("o"); installDate = value; } else if (name.ToLower().Contains("memory")) { // For output. int i = int.Parse(value) / 1024 / 1024; // TotalVisible only needs to be set once. if (name.ToLower().Contains("totalvisible")) { this.totalVisibleMemoryGb = i; } else if (name.ToLower().Contains("totalvirtual")) { totalVirtualMem = i; } else if (name.ToLower().Contains("freephysical")) { _ = double.TryParse(value, out freePhysicalMem); } else if (name.ToLower().Contains("freevirtual")) { _ = double.TryParse(value, out freeVirtualMem); } } break; } } } } // Active, bound ports. var activePorts = NetworkUsage.GetActivePortCount(); // Active, ephemeral ports. var activeEphemeralPorts = NetworkUsage.GetActiveEphemeralPortCount(); var(lowPortOs, highPortOs) = NetworkUsage.TupleGetDynamicPortRange(); string osEphemeralPortRange = string.Empty; var fabricAppPortRange = string.Empty; var clusterManifestXml = this.IsTestRun ? File.ReadAllText( this.TestManifestPath) : await this.FabricClientInstance.ClusterManager.GetClusterManifestAsync( this.AsyncClusterOperationTimeoutSeconds, this.Token).ConfigureAwait(false); var(lowPortApp, highPortApp) = NetworkUsage.TupleGetFabricApplicationPortRangeForNodeType( this.FabricServiceContext.NodeContext.NodeType, clusterManifestXml); int firewalls = NetworkUsage.GetActiveFirewallRulesCount(); // WU AutoUpdate string auMessage = "WindowsUpdateAutoDownloadEnabled: "; if (this.auStateUnknown) { auMessage += "Unknown"; } else { auMessage += this.isWindowsUpdateAutoDownloadEnabled; } // OS info. _ = sb.AppendLine("OS Information:\r\n"); _ = sb.AppendLine($"Name: {osName}"); _ = sb.AppendLine($"Version: {osVersion}"); _ = sb.AppendLine($"InstallDate: {installDate}"); _ = sb.AppendLine($"LastBootUpTime*: {lastBootTime}"); _ = sb.AppendLine(auMessage); _ = sb.AppendLine($"OSLanguage: {osLang}"); _ = sb.AppendLine($"OSHealthStatus*: {this.osStatus}"); _ = sb.AppendLine($"NumberOfProcesses*: {numProcs}"); if (lowPortOs > -1) { osEphemeralPortRange = $"{lowPortOs} - {highPortOs}"; _ = sb.AppendLine($"WindowsEphemeralTCPPortRange: {osEphemeralPortRange} (Active*: {activeEphemeralPorts})"); } if (lowPortApp > -1) { fabricAppPortRange = $"{lowPortApp} - {highPortApp}"; _ = sb.AppendLine($"FabricApplicationTCPPortRange: {fabricAppPortRange}"); } if (firewalls > -1) { _ = sb.AppendLine($"ActiveFirewallRules*: {firewalls}"); } if (activePorts > -1) { _ = sb.AppendLine($"TotalActiveTCPPorts*: {activePorts}"); } // Hardware info. // Proc/Mem _ = sb.AppendLine($"{Environment.NewLine}Hardware Information:{Environment.NewLine}"); _ = sb.AppendLine($"LogicalProcessorCount: {logicalProcessorCount}"); _ = sb.AppendLine($"TotalVirtualMemorySize: {totalVirtualMem} GB"); _ = sb.AppendLine($"TotalVisibleMemorySize: {this.totalVisibleMemoryGb} GB"); _ = sb.AppendLine($"FreePhysicalMemory*: {Math.Round(freePhysicalMem / 1024 / 1024, 2)} GB"); _ = sb.AppendLine($"FreeVirtualMemory*: {Math.Round(freeVirtualMem / 1024 / 1024, 2)} GB"); // Disk var drivesInformationTuple = diskUsage.GetCurrentDiskSpaceTotalAndUsedPercentAllDrives(SizeUnit.Gigabytes); var logicalDriveCount = drivesInformationTuple.Count; string driveInfo = string.Empty; _ = sb.AppendLine($"LogicalDriveCount: {logicalDriveCount}"); foreach (var(driveName, diskSize, percentConsumed) in drivesInformationTuple) { string systemDrv = "Data"; if (Environment.SystemDirectory.Substring(0, 1) == driveName) { systemDrv = "System"; } string drvSize = $"Drive {driveName} ({systemDrv}) Size: {diskSize} GB"; string drvConsumed = $"Drive {driveName} ({systemDrv}) Consumed*: {percentConsumed}%"; _ = sb.AppendLine(drvSize); _ = sb.AppendLine(drvConsumed); driveInfo += $"{drvSize}{Environment.NewLine}{drvConsumed}{Environment.NewLine}"; } string osHotFixes = GetWindowsHotFixes(token); if (!string.IsNullOrEmpty(osHotFixes)) { _ = sb.AppendLine($"\nWindows Patches/Hot Fixes*:\n\n{osHotFixes}"); } // Dynamic info qualifier (*) _ = sb.AppendLine($"\n* Dynamic data."); this.osReport = sb.ToString(); // ETW. if (this.IsEtwEnabled) { Logger.EtwLogger?.Write( ObserverConstants.FabricObserverETWEventName, new { HealthState = "Ok", Node = this.NodeName, Observer = this.ObserverName, OS = osName, OSVersion = osVersion, OSInstallDate = installDate, AutoUpdateEnabled = this.auStateUnknown ? "Unknown" : this.isWindowsUpdateAutoDownloadEnabled.ToString(), LastBootUpTime = lastBootTime, WindowsAutoUpdateEnabled = this.isWindowsUpdateAutoDownloadEnabled, TotalMemorySizeGB = this.totalVisibleMemoryGb, AvailablePhysicalMemoryGB = Math.Round(freePhysicalMem / 1024 / 1024, 2), AvailableVirtualMemoryGB = Math.Round(freeVirtualMem / 1024 / 1024, 2), LogicalProcessorCount = logicalProcessorCount, LogicalDriveCount = logicalDriveCount, DriveInfo = driveInfo, NumberOfRunningProcesses = numProcs, ActiveFirewallRules = firewalls, ActivePorts = activePorts, ActiveEphemeralPorts = activeEphemeralPorts, WindowsDynamicPortRange = osEphemeralPortRange, FabricAppPortRange = fabricAppPortRange, HotFixes = GetWindowsHotFixes(token, false).Replace("\r\n", ", ").TrimEnd(','), }); } // Telemetry if (this.IsTelemetryProviderEnabled && this.IsObserverTelemetryEnabled) { this.TelemetryClient?.ReportMetricAsync( new MachineTelemetryData { HealthState = "Ok", Node = this.NodeName, Observer = this.ObserverName, OS = osName, OSVersion = osVersion, OSInstallDate = installDate, LastBootUpTime = lastBootTime, WindowsUpdateAutoDownloadEnabled = this.isWindowsUpdateAutoDownloadEnabled, TotalMemorySizeGB = this.totalVisibleMemoryGb, AvailablePhysicalMemoryGB = Math.Round(freePhysicalMem / 1024 / 1024, 2), AvailableVirtualMemoryGB = Math.Round(freeVirtualMem / 1024 / 1024, 2), LogicalProcessorCount = logicalProcessorCount, LogicalDriveCount = logicalDriveCount, DriveInfo = driveInfo, NumberOfRunningProcesses = numProcs, ActiveFirewallRules = firewalls, ActivePorts = activePorts, ActiveEphemeralPorts = activeEphemeralPorts, WindowsDynamicPortRange = osEphemeralPortRange, FabricAppPortRange = fabricAppPortRange, HotFixes = GetWindowsHotFixes(token, false).Replace("\r\n", ", ").TrimEnd(','), }, this.Token); } } catch (ManagementException) { } catch (Exception e) { this.HealthReporter.ReportFabricObserverServiceHealth( this.FabricServiceContext.ServiceName.OriginalString, this.ObserverName, HealthState.Error, $"Unhandled exception processing OS information:{Environment.NewLine}{e}"); throw; } finally { results?.Dispose(); win32OsInfo?.Dispose(); diskUsage?.Dispose(); _ = sb.Clear(); } }