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; } SetErrorWarningThresholds(); DriveInfo[] allDrives = DriveInfo.GetDrives(); if (ObserverManager.ObserverWebAppDeployed) { this.diskInfo = new StringBuilder(); } foreach (var d in allDrives) { token.ThrowIfCancellationRequested(); if (!DiskUsage.ShouldCheckDrive(d)) { continue; } // 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; // Since these live across iterations, do not duplicate them in the containing list. // Disk space %. if (this.DiskSpaceUsagePercentageData.All(data => data.Id != id) && (this.DiskSpacePercentErrorThreshold > 0 || this.DiskSpacePercentWarningThreshold > 0)) { this.DiskSpaceUsagePercentageData.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.DiskSpaceUsagePercentage, id, DataCapacity)); } // Current disk queue length. if (this.DiskAverageQueueLengthData.All(data => data.Id != id) && (this.AverageQueueLengthErrorThreshold > 0 || this.AverageQueueLengthWarningThreshold > 0)) { this.DiskAverageQueueLengthData.Add(new FabricResourceUsageData <float>(ErrorWarningProperty.DiskAverageQueueLength, id, DataCapacity)); } // This data is just used for Telemetry today. if (this.DiskSpaceAvailableMbData.All(data => data.Id != id)) { this.DiskSpaceAvailableMbData.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.DiskSpaceAvailableMb, id, DataCapacity)); } // This data is just used for Telemetry today. if (this.DiskSpaceTotalMbData.All(data => data.Id != id)) { this.DiskSpaceTotalMbData.Add(new FabricResourceUsageData <double>(ErrorWarningProperty.DiskSpaceTotalMb, id, DataCapacity)); } // It is important to check if code is running on Windows, since d.Name.Substring(0, 2) will fail on Linux for / (root) mount point. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (this.AverageQueueLengthErrorThreshold > 0 || this.AverageQueueLengthWarningThreshold > 0) { // Warm up counter. _ = DiskUsage.GetAverageDiskQueueLength(d.Name.Substring(0, 2)); this.DiskAverageQueueLengthData.Single(x => x.Id == id).Data.Add(DiskUsage.GetAverageDiskQueueLength(d.Name.Substring(0, 2))); } } if (this.DiskSpacePercentErrorThreshold > 0 || this.DiskSpacePercentWarningThreshold > 0) { this.DiskSpaceUsagePercentageData.Single(x => x.Id == id).Data.Add(DiskUsage.GetCurrentDiskSpaceUsedPercent(id)); } this.DiskSpaceAvailableMbData.Single(x => x.Id == id).Data.Add(DiskUsage.GetAvailableDiskSpace(id, SizeUnit.Megabytes)); this.DiskSpaceTotalMbData.Single(x => x.Id == id).Data.Add(DiskUsage.GetTotalDiskSpace(id, SizeUnit.Megabytes)); // This section only needs to run if you have the FabricObserverWebApi app installed. if (ObserverManager.ObserverWebAppDeployed && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { _ = this.diskInfo.AppendFormat( "{0}", GetWindowsPerfCounterDetailsText( this.DiskAverageQueueLengthData.FirstOrDefault( x => x.Id == d.Name.Substring(0, 1)) ?.Data, "Avg. Disk Queue Length")); } RunDuration = this.stopWatch.Elapsed; } await ReportAsync(token).ConfigureAwait(true); LastRunDateTime = DateTime.Now; }