private async Task GetSystemCpuMemoryValuesAsync(CancellationToken token)
        {
            await Task.Run(
                () =>
            {
                token.ThrowIfCancellationRequested();

                try
                {
                    // Ports.
                    int activePortCountTotal    = NetworkUsage.GetActivePortCount();
                    int ephemeralPortCountTotal = NetworkUsage.GetActiveEphemeralPortCount();
                    this.activePortsData.Data.Add(activePortCountTotal);
                    this.ephemeralPortsData.Data.Add(ephemeralPortCountTotal);

                    // Firewall rules.
                    int firewalls = NetworkUsage.GetActiveFirewallRulesCount();
                    this.firewallData.Data.Add(firewalls);

                    // CPU and Memory.
                    for (int i = 0; i < 30; i++)
                    {
                        token.ThrowIfCancellationRequested();

                        if (this.CpuWarningUsageThresholdPct > 0 &&
                            this.CpuWarningUsageThresholdPct <= 100)
                        {
                            this.allCpuDataPrivTime.Data.Add(this.perfCounters.PerfCounterGetProcessorInfo());
                        }

                        if (this.MemWarningUsageThresholdMb > 0)
                        {
                            this.allMemDataCommittedBytes.Data.Add(this.perfCounters.PerfCounterGetMemoryInfoMb());
                        }

                        if (this.MemoryWarningLimitPercent > 0)
                        {
                            this.allMemDataPercentUsed.Data.Add(
                                ObserverManager.TupleGetTotalPhysicalMemorySizeAndPercentInUse().PercentInUse);
                        }

                        Thread.Sleep(250);
                    }
                }
                catch (Exception e)
                {
                    if (!(e is OperationCanceledException))
                    {
                        this.HealthReporter.ReportFabricObserverServiceHealth(
                            this.FabricServiceContext.ServiceName.OriginalString,
                            this.ObserverName,
                            HealthState.Warning,
                            $"Unhandled exception in GetSystemCpuMemoryValuesAsync: {e.Message}: \n {e.StackTrace}");
                    }

                    throw;
                }
            }, token).ConfigureAwait(true);
        }
        private string PrintNetworkUsage(NetworkUsage networkUsage, DateTimeOffset startTime)
        {
            string result = "Usage from " + startTime.ToString() + " to " + (startTime + networkUsage.ConnectionDuration).ToString() +
                            "\n\tBytes sent: " + networkUsage.BytesSent +
                            "\n\tBytes received: " + networkUsage.BytesReceived + "\n";

            return(result);
        }
        private NetworkInterfaceUsageInfo CreateInfo(NetworkUsage usage)
        {
            var result = usage is TeamingNetworkUsage teamingNetworkUsage
                ? new TeamingInterfaceUsageInfo {
                ChildInterfaces = teamingNetworkUsage.ChildInterfaces
            }
                : new NetworkInterfaceUsageInfo();

            result.InterfaceName = usage.InterfaceName;

            return(result);
        }
        public object GetResource()
        {
            var currentNetworkUsage = GetTotalUsage();

            var usageOfPastMinute = new NetworkUsage(
                currentNetworkUsage.DownloadInBytes - _lastNetworkUsage.DownloadInBytes,
                currentNetworkUsage.UploadInBytes - _lastNetworkUsage.UploadInBytes
                );

            this._lastNetworkUsage = currentNetworkUsage;
            return(usageOfPastMinute);
        }
        private void FillInfo(NetworkInterfaceUsageInfo toFill, NetworkUsage previousUsage, NetworkUsage usage, double deltaSeconds)
        {
            var deltaReceivedBytes = usage.ReceivedBytes - previousUsage.ReceivedBytes;
            var deltaSentBytes     = usage.SentBytes - previousUsage.SentBytes;

            if (deltaSeconds > 0d)
            {
                toFill.ReceivedBytesPerSecond = (long)(deltaReceivedBytes / deltaSeconds);
                toFill.SentBytesPerSecond     = (long)(deltaSentBytes / deltaSeconds);
            }

            toFill.BandwidthBytesPerSecond = usage.NetworkMaxMBitsPerSecond * 1000L * 1000L / 8L;
        }
        private async Task MonitorAppAsync(ApplicationInfo application)
        {
            var repOrInstList = await this.GetDeployedApplicationReplicaOrInstanceListAsync(new Uri(application.Target)).ConfigureAwait(true);

            if (repOrInstList.Count == 0)
            {
                return;
            }

            Process currentProcess = null;

            foreach (var repOrInst in repOrInstList)
            {
                this.Token.ThrowIfCancellationRequested();

                int processid = (int)repOrInst.ReplicaHostProcessId;
                var cpuUsage  = new CpuUsage();

                try
                {
                    // App level...
                    currentProcess = Process.GetProcessById(processid);

                    this.Token.ThrowIfCancellationRequested();

                    if (currentProcess == null)
                    {
                        continue;
                    }

                    var procName = currentProcess.ProcessName;

                    // Add new resource data structures for each app service process...
                    var id = $"{application.Target.Replace("fabric:/", string.Empty)}:{procName}";

                    if (!this.allAppCpuData.Any(list => list.Id == id))
                    {
                        this.allAppCpuData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalCpuTime, id));
                        this.allAppMemDataMB.Add(new FabricResourceUsageData <long>(ErrorWarningProperty.TotalMemoryConsumptionMB, id));
                        this.allAppMemDataPercent.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.TotalMemoryConsumptionPct, id));
                        this.allAppTotalActivePortsData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalActivePorts, id));
                        this.allAppEphemeralPortsData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalEphemeralPorts, id));
                    }

                    // CPU (all cores)...
                    int i = Environment.ProcessorCount + 10;

                    while (!currentProcess.HasExited && i > 0)
                    {
                        this.Token.ThrowIfCancellationRequested();

                        int cpu = cpuUsage.GetCpuUsageProcess(currentProcess);

                        if (cpu >= 0)
                        {
                            this.allAppCpuData.FirstOrDefault(x => x.Id == id).Data.Add(cpu);
                        }

                        // Memory (private working set (process))...
                        var mem = this.perfCounters.PerfCounterGetProcessPrivateWorkingSetMB(currentProcess.ProcessName);
                        this.allAppMemDataMB.FirstOrDefault(x => x.Id == id).Data.Add((long)mem);

                        // Memory (percent in use (total))...
                        var  memInfo  = ObserverManager.TupleGetTotalPhysicalMemorySizeAndPercentInUse();
                        long totalMem = memInfo.Item1;

                        if (totalMem > -1)
                        {
                            double usedPct = Math.Round(((double)(mem * 100)) / (totalMem * 1024), 2);
                            this.allAppMemDataPercent.FirstOrDefault(x => x.Id == id).Data.Add(usedPct);
                        }

                        --i;

                        Thread.Sleep(250);
                    }

                    // Total and Ephemeral ports....
                    this.allAppTotalActivePortsData.FirstOrDefault(x => x.Id == id)
                    .Data.Add(NetworkUsage.GetActivePortCount(currentProcess.Id));

                    this.allAppEphemeralPortsData.FirstOrDefault(x => x.Id == id)
                    .Data.Add(NetworkUsage.GetActiveEphemeralPortCount(currentProcess.Id));
                }
                catch (Exception e)
                {
                    if (e is Win32Exception)
                    {
                        this.WriteToLogWithLevel(
                            this.ObserverName,
                            $"MonitorAsync failed to find current service process for {application.Target}",
                            LogLevel.Information);
                    }
                    else
                    {
                        if (!(e is OperationCanceledException))
                        {
                            this.WriteToLogWithLevel(
                                this.ObserverName,
                                $"Unhandled exception in MonitorAsync: \n {e.ToString()}",
                                LogLevel.Warning);
                        }

                        throw;
                    }
                }
                finally
                {
                    currentProcess?.Dispose();
                    currentProcess = null;
                }
            }
        }
Пример #7
0
        private void GetProcessInfo(string procName)
        {
            var processes = Process.GetProcessesByName(procName);

            if (processes?.Length == 0)
            {
                return;
            }

            foreach (var process in processes)
            {
                try
                {
                    this.Token.ThrowIfCancellationRequested();

                    // ports in use by Fabric services...
                    this.TotalActivePortCount          += NetworkUsage.GetActivePortCount(process.Id);
                    this.TotalActiveEphemeralPortCount += NetworkUsage.GetActiveEphemeralPortCount(process.Id);

                    int procCount = Environment.ProcessorCount;

                    while (!process.HasExited && procCount > 0)
                    {
                        this.Token.ThrowIfCancellationRequested();

                        try
                        {
                            int cpu = (int)this.perfCounters.PerfCounterGetProcessorInfo("% Processor Time", "Process", process.ProcessName);

                            this.allCpuData.FirstOrDefault(x => x.Id == procName).Data.Add(cpu);

                            // Disk IO (per-process disk reads/writes per sec)
                            this.allAppDiskReadsData.FirstOrDefault(x => x.Id == procName)
                            .Data.Add(this.diskUsage.PerfCounterGetDiskIOInfo(
                                          process.ProcessName,
                                          "Process",
                                          "IO Read Operations/sec"));

                            this.allAppDiskWritesData.FirstOrDefault(x => x.Id == procName)
                            .Data.Add(this.diskUsage.PerfCounterGetDiskIOInfo(
                                          process.ProcessName,
                                          "Process",
                                          "IO Write Operations/sec"));

                            // Memory - Private WS for proc...
                            var workingset = this.perfCounters.PerfCounterGetProcessPrivateWorkingSetMB(process.ProcessName);
                            this.allMemData.FirstOrDefault(x => x.Id == procName).Data.Add((long)workingset);

                            --procCount;
                            Thread.Sleep(250);
                        }
                        catch (Exception e)
                        {
                            this.WriteToLogWithLevel(
                                this.ObserverName,
                                $"Can't observe {process} details due to {e.Message} - {e.StackTrace}",
                                LogLevel.Warning);
                            throw;
                        }
                    }
                }
                catch (Win32Exception)
                {
                    // This will always be the case if FabricObserver.exe is not running as Admin or LocalSystem...
                    // It's OK. Just means that the elevated process (like FabricHost.exe) won't be observed.
                    this.WriteToLogWithLevel(
                        this.ObserverName,
                        $"Can't observe {process} due to it's privilege level - " + "FabricObserver must be running as System or Admin for this specific task.",
                        LogLevel.Information);
                    break;
                }
                finally
                {
                    process?.Dispose();
                }
            }
        }
Пример #8
0
        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();
            }
        }
Пример #9
0
        private Task GetSystemCpuMemoryValuesAsync(CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            try
            {
                // Ports.
                int activePortCountTotal    = NetworkUsage.GetActivePortCount();
                int ephemeralPortCountTotal = NetworkUsage.GetActiveEphemeralPortCount();
                this.activePortsData.Data.Add(activePortCountTotal);
                this.ephemeralPortsData.Data.Add(ephemeralPortCountTotal);

                // Firewall rules.
                int firewalls = NetworkUsage.GetActiveFirewallRulesCount();
                this.firewallData.Data.Add(firewalls);

                // CPU and Memory.
                // Note: Please make sure you understand the normal state of your nodes
                // with respect to the machine resource use and/or abuse by your service(s).
                // For example, if it is normal for your services to consume 90% of available CPU and memory
                // as part of the work they perform under normal traffic flow, then it doesn't make sense to warn or
                // error on these conditions.
                // TODO: Look into making this a long running background task with signaling.
                TimeSpan duration = TimeSpan.FromSeconds(30);

                if (this.MonitorDuration > TimeSpan.MinValue)
                {
                    duration = this.MonitorDuration;
                }

                // Warn up the counters.
                _ = this.perfCounters.PerfCounterGetProcessorInfo();
                _ = this.perfCounters.PerfCounterGetMemoryInfoMb();

                while (this.stopwatch.Elapsed <= duration)
                {
                    token.ThrowIfCancellationRequested();

                    if (this.CpuWarningUsageThresholdPct > 0 &&
                        this.CpuWarningUsageThresholdPct <= 100)
                    {
                        this.AllCpuTimeData.Data.Add(this.perfCounters.PerfCounterGetProcessorInfo());
                    }

                    if (this.MemWarningUsageThresholdMb > 0)
                    {
                        this.allMemDataCommittedBytes.Data.Add(this.perfCounters.PerfCounterGetMemoryInfoMb());
                    }

                    if (this.MemoryWarningLimitPercent > 0)
                    {
                        this.allMemDataPercentUsed.Data.Add(
                            ObserverManager.TupleGetTotalPhysicalMemorySizeAndPercentInUse().PercentInUse);
                    }

                    Thread.Sleep(250);
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception e)
            {
                this.HealthReporter.ReportFabricObserverServiceHealth(
                    this.FabricServiceContext.ServiceName.OriginalString,
                    this.ObserverName,
                    HealthState.Warning,
                    $"Unhandled exception in GetSystemCpuMemoryValuesAsync:{Environment.NewLine}{e}");

                throw;
            }

            return(Task.CompletedTask);
        }
        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();
            }
        }
Пример #11
0
        private async Task MonitorAppAsync(ApplicationInfo application)
        {
            List <ReplicaOrInstanceMonitoringInfo> repOrInstList;

            if (!string.IsNullOrEmpty(application.TargetType))
            {
                repOrInstList = await GetDeployedApplicationReplicaOrInstanceListAsync(null, application.TargetType).ConfigureAwait(true);
            }
            else
            {
                repOrInstList = await GetDeployedApplicationReplicaOrInstanceListAsync(new Uri(application.Target)).ConfigureAwait(true);
            }

            if (repOrInstList.Count == 0)
            {
                ObserverLogger.LogInfo("No target or targetType specified.");
                return;
            }

            Process currentProcess = null;

            foreach (var repOrInst in repOrInstList)
            {
                Token.ThrowIfCancellationRequested();

                int processid = (int)repOrInst.HostProcessId;
                var cpuUsage  = new CpuUsage();

                try
                {
                    // App level.
                    currentProcess = Process.GetProcessById(processid);

                    Token.ThrowIfCancellationRequested();

                    var    procName      = currentProcess.ProcessName;
                    string appNameOrType = GetAppNameOrType(repOrInst);

                    var id = $"{appNameOrType}:{procName}";

                    // Add new resource data structures for each app service process.
                    if (!allAppCpuData.Any(list => list.Id == id))
                    {
                        allAppCpuData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalCpuTime, id));
                        allAppMemDataMB.Add(new FabricResourceUsageData <long>(ErrorWarningProperty.TotalMemoryConsumptionMb, id));
                        allAppMemDataPercent.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.TotalMemoryConsumptionPct, id));
                        allAppTotalActivePortsData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalActivePorts, id));
                        allAppEphemeralPortsData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalEphemeralPorts, id));
                    }

                    // CPU (all cores).
                    int i = Environment.ProcessorCount + 10;

                    while (!currentProcess.HasExited && i > 0)
                    {
                        Token.ThrowIfCancellationRequested();

                        int cpu = cpuUsage.GetCpuUsageProcess(currentProcess);

                        if (cpu >= 0)
                        {
                            allAppCpuData.FirstOrDefault(x => x.Id == id).Data.Add(cpu);
                        }

                        // Memory (private working set (process)).
                        var processMem = perfCounters.PerfCounterGetProcessPrivateWorkingSetMb(currentProcess.ProcessName);
                        allAppMemDataMB.FirstOrDefault(x => x.Id == id).Data.Add((long)processMem);

                        // Memory (percent in use (total)).
                        var  memInfo  = ObserverManager.TupleGetTotalPhysicalMemorySizeAndPercentInUse();
                        long totalMem = memInfo.TotalMemory;

                        if (totalMem > -1)
                        {
                            double usedPct = Math.Round(((double)(processMem * 100)) / (totalMem * 1024), 2);
                            allAppMemDataPercent.FirstOrDefault(x => x.Id == id).Data.Add(usedPct);
                        }

                        --i;

                        Thread.Sleep(250);
                    }

                    // Total and Ephemeral ports..
                    allAppTotalActivePortsData.FirstOrDefault(x => x.Id == id)
                    .Data.Add(NetworkUsage.GetActivePortCount(currentProcess.Id));

                    allAppEphemeralPortsData.FirstOrDefault(x => x.Id == id)
                    .Data.Add(NetworkUsage.GetActiveEphemeralPortCount(currentProcess.Id));
                }
                catch (Exception e)
                {
                    if (e is Win32Exception || e is ArgumentException || e is InvalidOperationException)
                    {
                        WriteToLogWithLevel(
                            ObserverName,
                            $"MonitorAsync failed to find current service process for {application.Target}/n{e}",
                            LogLevel.Information);
                    }
                    else
                    {
                        if (!(e is OperationCanceledException))
                        {
                            WriteToLogWithLevel(
                                ObserverName,
                                $"Unhandled exception in MonitorAsync: \n {e}",
                                LogLevel.Warning);
                        }

                        throw;
                    }
                }
                finally
                {
                    currentProcess?.Dispose();
                    currentProcess = null;
                }
            }
        }
Пример #12
0
        private async Task MonitorAppAsync(ApplicationInfo application)
        {
            List <ReplicaOrInstanceMonitoringInfo> repOrInstList;

            if (this.IsTestRun)
            {
                repOrInstList = this.ReplicaOrInstanceList;
            }
            else
            {
                if (!string.IsNullOrEmpty(application.TargetAppType))
                {
                    repOrInstList = await this
                                    .GetDeployedApplicationReplicaOrInstanceListAsync(null, application.TargetAppType)
                                    .ConfigureAwait(true);
                }
                else
                {
                    repOrInstList = await this
                                    .GetDeployedApplicationReplicaOrInstanceListAsync(new Uri(application.TargetApp))
                                    .ConfigureAwait(true);
                }

                if (repOrInstList.Count == 0)
                {
                    this.ObserverLogger.LogInfo("No targetApp or targetAppType specified.");
                    return;
                }
            }

            Process currentProcess = null;

            foreach (var repOrInst in repOrInstList)
            {
                this.Token.ThrowIfCancellationRequested();

                var timer     = new Stopwatch();
                int processId = (int)repOrInst.HostProcessId;
                var cpuUsage  = new CpuUsage();

                try
                {
                    // App level.
                    currentProcess = Process.GetProcessById(processId);

                    this.Token.ThrowIfCancellationRequested();

                    var    procName      = currentProcess.ProcessName;
                    string appNameOrType = GetAppNameOrType(repOrInst);

                    var id = $"{appNameOrType}:{procName}";

                    // Add new resource data structures for each app service process.
                    if (this.allAppCpuData.All(list => list.Id != id))
                    {
                        this.allAppCpuData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalCpuTime, id, this.DataCapacity, this.UseCircularBuffer));
                        this.allAppMemDataMb.Add(new FabricResourceUsageData <float>(ErrorWarningProperty.TotalMemoryConsumptionMb, id, this.DataCapacity, this.UseCircularBuffer));
                        this.allAppMemDataPercent.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.TotalMemoryConsumptionPct, id, this.DataCapacity, this.UseCircularBuffer));
                        this.allAppTotalActivePortsData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalActivePorts, id, 1));
                        this.allAppEphemeralPortsData.Add(new FabricResourceUsageData <int>(ErrorWarningProperty.TotalEphemeralPorts, id, 1));
                    }

                    TimeSpan duration = TimeSpan.FromSeconds(15);

                    if (this.MonitorDuration > TimeSpan.MinValue)
                    {
                        duration = this.MonitorDuration;
                    }

                    // Warm up the counters.
                    _ = cpuUsage.GetCpuUsageProcess(currentProcess);
                    _ = this.perfCounters.PerfCounterGetProcessPrivateWorkingSetMb(currentProcess.ProcessName);

                    timer.Start();

                    while (!currentProcess.HasExited && timer.Elapsed <= duration)
                    {
                        this.Token.ThrowIfCancellationRequested();

                        // CPU (all cores).
                        int cpu = cpuUsage.GetCpuUsageProcess(currentProcess);

                        if (cpu >= 0)
                        {
                            this.allAppCpuData.FirstOrDefault(x => x.Id == id).Data.Add(cpu);
                        }

                        // Memory (private working set (process)).
                        var processMem = this.perfCounters.PerfCounterGetProcessPrivateWorkingSetMb(currentProcess.ProcessName);
                        this.allAppMemDataMb.FirstOrDefault(x => x.Id == id).Data.Add(processMem);

                        // Memory (percent in use (total)).
                        var  memInfo  = ObserverManager.TupleGetTotalPhysicalMemorySizeAndPercentInUse();
                        long totalMem = memInfo.TotalMemory;

                        if (totalMem > -1)
                        {
                            double usedPct = Math.Round(((double)(processMem * 100)) / (totalMem * 1024), 2);
                            this.allAppMemDataPercent.FirstOrDefault(x => x.Id == id).Data.Add(Math.Round(usedPct, 1));
                        }

                        Thread.Sleep(250);
                    }

                    timer.Stop();
                    timer.Reset();

                    // Total and Ephemeral ports..
                    this.allAppTotalActivePortsData.FirstOrDefault(x => x.Id == id)
                    .Data.Add(NetworkUsage.GetActivePortCount(currentProcess.Id));

                    this.allAppEphemeralPortsData.FirstOrDefault(x => x.Id == id)
                    .Data.Add(NetworkUsage.GetActiveEphemeralPortCount(currentProcess.Id));
                }
                catch (Exception e)
                {
                    if (e is Win32Exception || e is ArgumentException || e is InvalidOperationException)
                    {
                        this.WriteToLogWithLevel(
                            this.ObserverName,
                            $"MonitorAsync failed to find current service process for {application.TargetApp}/n{e}",
                            LogLevel.Information);
                    }
                    else
                    {
                        if (!(e is OperationCanceledException))
                        {
                            this.WriteToLogWithLevel(
                                this.ObserverName,
                                $"Unhandled exception in MonitorAsync: \n {e}",
                                LogLevel.Warning);
                        }

                        throw;
                    }
                }
                finally
                {
                    currentProcess?.Dispose();
                    currentProcess = null;
                }
            }
        }
Пример #13
0
        private async Task GetSystemCpuMemoryValuesAsync(CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            CpuUtilizationProvider cpuUtilizationProvider = null;

            try
            {
                // Ports.
                int activePortCountTotal    = OperatingSystemInfoProvider.Instance.GetActivePortCount();
                int ephemeralPortCountTotal = OperatingSystemInfoProvider.Instance.GetActiveEphemeralPortCount();
                this.activePortsData.Data.Add(activePortCountTotal);
                this.ephemeralPortsData.Data.Add(ephemeralPortCountTotal);

                // Firewall rules.
                int firewalls = NetworkUsage.GetActiveFirewallRulesCount();
                this.firewallData.Data.Add(firewalls);

                // CPU and Memory.
                // Note: Please make sure you understand the normal state of your nodes
                // with respect to the machine resource use and/or abuse by your service(s).
                // For example, if it is normal for your services to consume 90% of available CPU and memory
                // as part of the work they perform under normal traffic flow, then it doesn't make sense to warn or
                // error on these conditions.
                // TODO: Look into making this a long running background task with signaling.
                TimeSpan duration = TimeSpan.FromSeconds(10);

                if (MonitorDuration > TimeSpan.MinValue)
                {
                    duration = MonitorDuration;
                }

                cpuUtilizationProvider = CpuUtilizationProvider.Create();

                // Warm up the counters.
                _ = await cpuUtilizationProvider.NextValueAsync();

                while (this.stopwatch.Elapsed <= duration)
                {
                    token.ThrowIfCancellationRequested();

                    if (CpuWarningUsageThresholdPct > 0 &&
                        CpuWarningUsageThresholdPct <= 100)
                    {
                        AllCpuTimeData.Data.Add(await cpuUtilizationProvider.NextValueAsync());
                    }

                    if (MemWarningUsageThresholdMb > 0)
                    {
                        float committedMegaBytes = MemoryUsageProvider.Instance.GetCommittedBytes() / 1048576.0f;
                        this.allMemDataCommittedBytes.Data.Add(committedMegaBytes);
                    }

                    if (MemoryWarningLimitPercent > 0)
                    {
                        this.allMemDataPercentUsed.Data.Add(
                            OperatingSystemInfoProvider.Instance.TupleGetTotalPhysicalMemorySizeAndPercentInUse().PercentInUse);
                    }

                    await Task.Delay(250).ConfigureAwait(false);
                }
            }
            catch (AggregateException e) when(e.InnerException is OperationCanceledException || e.InnerException is TaskCanceledException || e.InnerException is TimeoutException)
            {
                return;
            }
            catch (Exception e)
            {
                HealthReporter.ReportFabricObserverServiceHealth(
                    FabricServiceContext.ServiceName.OriginalString,
                    ObserverName,
                    HealthState.Warning,
                    $"Unhandled exception in GetSystemCpuMemoryValuesAsync:{Environment.NewLine}{e}");

                throw;
            }
            finally
            {
                cpuUtilizationProvider?.Dispose();
            }
        }
        private void GetProcessInfo(string procName)
        {
            var processes = Process.GetProcessesByName(procName);

            if (processes.Length == 0)
            {
                return;
            }

            Stopwatch timer = new Stopwatch();

            foreach (var process in processes)
            {
                try
                {
                    this.Token.ThrowIfCancellationRequested();

                    // ports in use by Fabric services.
                    this.TotalActivePortCount          += NetworkUsage.GetActivePortCount(process.Id);
                    this.TotalActiveEphemeralPortCount += NetworkUsage.GetActiveEphemeralPortCount(process.Id);

                    TimeSpan duration = TimeSpan.FromSeconds(15);

                    if (this.MonitorDuration > TimeSpan.MinValue)
                    {
                        duration = this.MonitorDuration;
                    }

                    // Warm up the counters.
                    _ = this.perfCounters.PerfCounterGetProcessorInfo("% Processor Time", "Process", process.ProcessName);
                    _ = this.perfCounters.PerfCounterGetProcessPrivateWorkingSetMb(process.ProcessName);

                    timer.Start();

                    while (!process.HasExited && timer.Elapsed <= duration)
                    {
                        this.Token.ThrowIfCancellationRequested();

                        try
                        {
                            // CPU Time for service process.
                            int cpu = (int)this.perfCounters.PerfCounterGetProcessorInfo("% Processor Time", "Process", process.ProcessName);
                            this.allCpuData.FirstOrDefault(x => x.Id == procName)?.Data.Add(cpu);

                            // Private Working Set for service process.
                            float mem = this.perfCounters.PerfCounterGetProcessPrivateWorkingSetMb(process.ProcessName);
                            this.allMemData.FirstOrDefault(x => x.Id == procName)?.Data.Add(mem);

                            Thread.Sleep(250);
                        }
                        catch (Exception e)
                        {
                            this.WriteToLogWithLevel(
                                this.ObserverName,
                                $"Can't observe {process} details:{Environment.NewLine}{e}",
                                LogLevel.Warning);

                            throw;
                        }
                    }
                }
                catch (Win32Exception)
                {
                    // This will always be the case if FabricObserver.exe is not running as Admin or LocalSystem.
                    // It's OK. Just means that the elevated process (like FabricHost.exe) won't be observed.
                    this.WriteToLogWithLevel(
                        this.ObserverName,
                        $"Can't observe {process.ProcessName} due to it's privilege level. FabricObserver must be running as System or Admin for this specific task.",
                        LogLevel.Information);

                    break;
                }
                finally
                {
                    process?.Dispose();
                }

                timer.Stop();
                timer.Reset();
            }
        }
 public NetworkUsageResource()
 {
     _lastNetworkUsage = GetTotalUsage();
 }
        private async Task GetComputerInfoAsync(CancellationToken token)
        {
            var sb = new StringBuilder();
            int logicalProcessorCount = Environment.ProcessorCount;

            try
            {
                OSInfo osInfo = await OperatingSystemInfoProvider.Instance.GetOSInfoAsync(token);

                this.osStatus = osInfo.Status;

                // Active, bound ports.
                int activePorts = OperatingSystemInfoProvider.Instance.GetActivePortCount();

                // Active, ephemeral ports.
                int activeEphemeralPorts = OperatingSystemInfoProvider.Instance.GetActiveEphemeralPortCount();
                (int lowPortOS, int highPortOS) = OperatingSystemInfoProvider.Instance.TupleGetDynamicPortRange();
                string osEphemeralPortRange = string.Empty;
                string fabricAppPortRange   = string.Empty;

                string clusterManifestXml = IsTestRun ? File.ReadAllText(
                    TestManifestPath) : await FabricClientInstance.ClusterManager.GetClusterManifestAsync(
                    AsyncClusterOperationTimeoutSeconds, Token).ConfigureAwait(false);

                (int lowPortApp, int highPortApp) =
                    NetworkUsage.TupleGetFabricApplicationPortRangeForNodeType(
                        FabricServiceContext.NodeContext.NodeType,
                        clusterManifestXml);

                int firewalls = NetworkUsage.GetActiveFirewallRulesCount();

                // OS info.
                _ = sb.AppendLine("OS Information:\r\n");
                _ = sb.AppendLine($"Name: {osInfo.Name}");
                _ = sb.AppendLine($"Version: {osInfo.Version}");

                if (string.IsNullOrEmpty(osInfo.InstallDate))
                {
                    _ = sb.AppendLine($"InstallDate: {osInfo.InstallDate}");
                }

                _ = sb.AppendLine($"LastBootUpTime*: {osInfo.LastBootUpTime}");

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    // WU AutoUpdate - Download enabled.
                    // If the config setting EnableWindowsAutoUpdateCheck is set to false, then don't add this info to sb.
                    if (this.isWUADSettingEnabled)
                    {
                        string auMessage = "WindowsUpdateAutoDownloadEnabled: ";

                        if (this.auStateUnknown)
                        {
                            auMessage += "Unknown";
                        }
                        else
                        {
                            auMessage += this.isWindowsUpdateAutoDownloadEnabled;
                        }
                        _ = sb.AppendLine(auMessage);
                    }

                    // Not supported for Linux.
                    _ = sb.AppendLine($"OSLanguage: {osInfo.Language}");
                    _ = sb.AppendLine($"OSHealthStatus*: {osInfo.Status}");
                }

                _ = sb.AppendLine($"NumberOfProcesses*: {osInfo.NumberOfProcesses}");

                if (lowPortOS > -1)
                {
                    osEphemeralPortRange = $"{lowPortOS} - {highPortOS}";
                    _ = sb.AppendLine($"OSEphemeralTCPPortRange: {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}");

                if (osInfo.TotalVirtualMemorySizeKB > 0)
                {
                    _ = sb.AppendLine($"TotalVirtualMemorySize: {osInfo.TotalVirtualMemorySizeKB / 1048576} GB");
                }

                if (osInfo.TotalVisibleMemorySizeKB > 0)
                {
                    _ = sb.AppendLine($"TotalVisibleMemorySize: {osInfo.TotalVisibleMemorySizeKB / 1048576} GB");
                }

                _ = sb.AppendLine($"FreePhysicalMemory*: {Math.Round(osInfo.AvailableMemoryKB / 1048576.0, 2)} GB");
                _ = sb.AppendLine($"FreeVirtualMemory*: {Math.Round(osInfo.FreeVirtualMemoryKB / 1048576.0, 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 drvSize;

                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        string systemDrv = "Data";

                        if (string.Equals(Environment.SystemDirectory.Substring(0, 1), driveName.Substring(0, 1), StringComparison.OrdinalIgnoreCase))
                        {
                            systemDrv = "System";
                        }

                        drvSize = $"Drive {driveName} ({systemDrv}) Size: {diskSize} GB, Consumed*: {percentConsumed}%";
                    }
                    else
                    {
                        drvSize = $"Mount point: {driveName}, Size: {diskSize} GB, Consumed*: {percentConsumed}%";
                    }

                    _ = sb.AppendLine(drvSize);

                    driveInfo += $"{drvSize}{Environment.NewLine}";
                }

                string osHotFixes = string.Empty;

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    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();

                string hotFixes = string.Empty;

                // ETW.
                if (IsEtwEnabled)
                {
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        hotFixes = GetWindowsHotFixes(token, generateUrl: false).Replace("\r\n", ", ").TrimEnd(',');
                    }

                    Logger.EtwLogger?.Write(
                        ObserverConstants.FabricObserverETWEventName,
                        new
                    {
                        HealthState       = "Ok",
                        Node              = NodeName,
                        Observer          = ObserverName,
                        OS                = osInfo.Name,
                        OSVersion         = osInfo.Version,
                        OSInstallDate     = osInfo.InstallDate,
                        AutoUpdateEnabled = this.auStateUnknown ? "Unknown" : this.isWindowsUpdateAutoDownloadEnabled.ToString(),
                        osInfo.LastBootUpTime,
                        WindowsAutoUpdateEnabled  = this.isWindowsUpdateAutoDownloadEnabled,
                        TotalMemorySizeGB         = (int)(osInfo.TotalVisibleMemorySizeKB / 1048576),
                        AvailablePhysicalMemoryGB = Math.Round(osInfo.FreePhysicalMemoryKB / 1048576.0, 2),
                        AvailableVirtualMemoryGB  = Math.Round(osInfo.FreeVirtualMemoryKB / 1048576.0, 2),
                        LogicalProcessorCount     = logicalProcessorCount,
                        LogicalDriveCount         = logicalDriveCount,
                        DriveInfo = driveInfo,
                        NumberOfRunningProcesses = osInfo.NumberOfProcesses,
                        ActiveFirewallRules      = firewalls,
                        ActivePorts             = activePorts,
                        ActiveEphemeralPorts    = activeEphemeralPorts,
                        WindowsDynamicPortRange = osEphemeralPortRange,
                        FabricAppPortRange      = fabricAppPortRange,
                        HotFixes = hotFixes,
                    });
                }

                // Telemetry
                if (IsTelemetryProviderEnabled && IsObserverTelemetryEnabled)
                {
                    if (string.IsNullOrEmpty(hotFixes) && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        hotFixes = GetWindowsHotFixes(token, generateUrl: false).Replace("\r\n", ", ").TrimEnd(',');
                    }

                    TelemetryClient?.ReportMetricAsync(
                        new MachineTelemetryData
                    {
                        HealthState    = "Ok",
                        Node           = NodeName,
                        Observer       = ObserverName,
                        OS             = osInfo.Name,
                        OSVersion      = osInfo.Version,
                        OSInstallDate  = osInfo.InstallDate,
                        LastBootUpTime = osInfo.LastBootUpTime,
                        WindowsUpdateAutoDownloadEnabled = this.isWindowsUpdateAutoDownloadEnabled,
                        TotalMemorySizeGB         = (int)osInfo.TotalVisibleMemorySizeKB / 1048576,
                        AvailablePhysicalMemoryGB = Math.Round(osInfo.FreePhysicalMemoryKB / 1048576.0, 2),
                        AvailableVirtualMemoryGB  = Math.Round(osInfo.FreeVirtualMemoryKB / 1048576.0, 2),
                        LogicalProcessorCount     = logicalProcessorCount,
                        LogicalDriveCount         = logicalDriveCount,
                        DriveInfo = driveInfo,
                        NumberOfRunningProcesses = osInfo.NumberOfProcesses,
                        ActiveFirewallRules      = firewalls,
                        ActivePorts             = activePorts,
                        ActiveEphemeralPorts    = activeEphemeralPorts,
                        WindowsDynamicPortRange = osEphemeralPortRange,
                        FabricAppPortRange      = fabricAppPortRange,
                        HotFixes = hotFixes,
                    }, Token);
                }
            }
            catch (Exception e) when(e is FabricException || e is OperationCanceledException || e is TaskCanceledException || e is InvalidComObjectException)
            {
                HealthReporter.ReportFabricObserverServiceHealth(
                    FabricServiceContext.ServiceName.OriginalString,
                    ObserverName,
                    HealthState.Warning,
                    $"Handled Exception processing OS information:{Environment.NewLine}{e}");
            }
            catch (Exception e)
            {
                HealthReporter.ReportFabricObserverServiceHealth(
                    FabricServiceContext.ServiceName.OriginalString,
                    ObserverName,
                    HealthState.Error,
                    $"Unhandled Exception processing OS information:{Environment.NewLine}{e}");

                throw;
            }
        }
        private async Task <string> GetDeployedAppsInfoAsync(CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            ApplicationList appList = null;
            var             sb      = new StringBuilder();
            string          clusterManifestXml;

            if (this.IsTestRun)
            {
                clusterManifestXml = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "clusterManifest.xml"));
            }
            else
            {
                appList = await this.FabricClientInstance.QueryManager.GetApplicationListAsync().ConfigureAwait(true);

                clusterManifestXml = await this.FabricClientInstance.ClusterManager.GetClusterManifestAsync().ConfigureAwait(true);
            }

            token.ThrowIfCancellationRequested();

            XmlReader    xreader = null;
            StringReader sreader = null;
            string       ret     = null;

            try
            {
                // Safe XML pattern - *Do not use LoadXml*...
                var xdoc = new XmlDocument {
                    XmlResolver = null
                };
                sreader = new StringReader(clusterManifestXml);
                xreader = XmlReader.Create(sreader, new XmlReaderSettings()
                {
                    XmlResolver = null
                });
                xdoc.Load(xreader);

                // Cluster Information...
                var nsmgr = new XmlNamespaceManager(xdoc.NameTable);
                nsmgr.AddNamespace("sf", "http://schemas.microsoft.com/2011/01/fabric");

                // Failover Manager...
                var fMparameterNodes = xdoc.SelectNodes("//sf:Section[@Name='FailoverManager']//sf:Parameter", nsmgr);
                sb.AppendLine("\nCluster Information:\n");

                foreach (XmlNode node in fMparameterNodes)
                {
                    token.ThrowIfCancellationRequested();

                    sb.AppendLine(node.Attributes.Item(0).Value + ": " + node.Attributes.Item(1).Value);
                }

                token.ThrowIfCancellationRequested();

                // Node Information...
                sb.AppendLine($"\nNode Info:\n");
                sb.AppendLine($"Node Name: {this.NodeName}");
                sb.AppendLine($"Node Id: {this.FabricServiceContext.NodeContext.NodeId}");
                sb.AppendLine($"Node Instance Id: {this.FabricServiceContext.NodeContext.NodeInstanceId}");
                sb.AppendLine($"Node Type: {this.FabricServiceContext.NodeContext.NodeType}");
                Tuple <int, int> portRange = NetworkUsage.TupleGetFabricApplicationPortRangeForNodeType(this.FabricServiceContext.NodeContext.NodeType, clusterManifestXml);

                if (portRange.Item1 > -1)
                {
                    sb.AppendLine($"Application Port Range: {portRange.Item1} - {portRange.Item2}");
                }

                var infraNode = xdoc.SelectSingleNode("//sf:Node", nsmgr);

                if (infraNode != null)
                {
                    sb.AppendLine("Is Seed Node: " + infraNode.Attributes["IsSeedNode"]?.Value);
                    sb.AppendLine("Fault Domain: " + infraNode.Attributes["FaultDomain"]?.Value);
                    sb.AppendLine("Upgrade Domain: " + infraNode.Attributes["UpgradeDomain"]?.Value);
                }

                token.ThrowIfCancellationRequested();

                if (!string.IsNullOrEmpty(this.sFNodeLastBootTime))
                {
                    sb.AppendLine("Last Rebooted: " + this.sFNodeLastBootTime);
                }

                // Stop here for unit testing...
                if (this.IsTestRun)
                {
                    ret = sb.ToString();
                    sb.Clear();

                    return(ret);
                }

                // Application Info...
                // TODO: Emit ETW event for App and Service info...
                if (appList != null)
                {
                    sb.AppendLine("\nDeployed Apps:\n");

                    foreach (var app in appList)
                    {
                        token.ThrowIfCancellationRequested();

                        var appName     = app.ApplicationName.OriginalString;
                        var appType     = app.ApplicationTypeName;
                        var appVersion  = app.ApplicationTypeVersion;
                        var healthState = app.HealthState.ToString();
                        var status      = app.ApplicationStatus.ToString();

                        sb.AppendLine("Application Name: " + appName);
                        sb.AppendLine("Type: " + appType);
                        sb.AppendLine("Version: " + appVersion);
                        sb.AppendLine("Health state: " + healthState);
                        sb.AppendLine("Status: " + status);

                        // App's Service(s)...
                        sb.AppendLine("\n\tServices:");
                        var serviceList = await this.FabricClientInstance.QueryManager.GetServiceListAsync(app.ApplicationName).ConfigureAwait(true);

                        var replicaList = await this.FabricClientInstance.QueryManager.GetDeployedReplicaListAsync(this.NodeName, app.ApplicationName).ConfigureAwait(true);

                        foreach (var service in serviceList)
                        {
                            var kind = service.ServiceKind.ToString();
                            var type = service.ServiceTypeName;
                            var serviceManifestversion = service.ServiceManifestVersion;
                            var serviceName            = service.ServiceName;
                            var serviceDescription     = await this.FabricClientInstance.ServiceManager.GetServiceDescriptionAsync(serviceName).ConfigureAwait(true);

                            var processModel = serviceDescription.ServicePackageActivationMode.ToString();

                            foreach (var rep in replicaList)
                            {
                                if (service.ServiceName != rep.ServiceName)
                                {
                                    continue;
                                }

                                // Get established port count per service...
                                int procId = (int)rep.HostProcessId;
                                int ports = -1, ephemeralPorts = -1;

                                if (procId > -1)
                                {
                                    ports          = NetworkUsage.GetActivePortCount(procId);
                                    ephemeralPorts = NetworkUsage.GetActiveEphemeralPortCount(procId);
                                }

                                sb.AppendLine("\tService Name: " + serviceName.OriginalString);
                                sb.AppendLine("\tTypeName: " + type);
                                sb.AppendLine("\tKind: " + kind);
                                sb.AppendLine("\tProcessModel: " + processModel);
                                sb.AppendLine("\tServiceManifest Version: " + serviceManifestversion);

                                if (ports > -1)
                                {
                                    sb.AppendLine("\tActive Ports: " + ports);
                                }

                                if (ephemeralPorts > -1)
                                {
                                    sb.AppendLine("\tActive Ephemeral Ports: " + ephemeralPorts);
                                }

                                sb.AppendLine();

                                // ETW...
                                if (this.IsEtwEnabled)
                                {
                                    Logger.EtwLogger?.Write(
                                        $"FabricObserverDataEvent",
                                        new
                                    {
                                        Level                  = 0, // Info
                                        Node                   = this.NodeName,
                                        Observer               = this.ObserverName,
                                        AppName                = appName,
                                        AppType                = appType,
                                        AppVersion             = appVersion,
                                        AppHealthState         = healthState,
                                        AppStatus              = status,
                                        ServiceName            = serviceName.OriginalString,
                                        ServiceTypeName        = type,
                                        Kind                   = kind,
                                        ProcessModel           = processModel,
                                        ServiceManifestVersion = serviceManifestversion,
                                        ActivePorts            = ports,
                                        EphemeralPorts         = ephemeralPorts,
                                    });
                                }

                                break;
                            }
                        }
                    }
                }

                ret = sb.ToString();
                sb.Clear();
            }
            finally
            {
                sreader.Dispose();
                xreader.Dispose();
            }

            return(ret);
        }
Пример #18
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();
            }
        }