Beispiel #1
0
        /// <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;
            }
        }
Beispiel #2
0
        /// <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;
        }
Beispiel #6
0
        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();
            }
        }