/// <inheritdoc/> public override async Task ObserveAsync(CancellationToken token) { this.SetErrorWarningThresholds(); DriveInfo[] allDrives = DriveInfo.GetDrives(); var diskUsage = new DiskUsage(); this.diskInfo = new StringBuilder(); try { int readyCount = 0; foreach (var d in allDrives) { token.ThrowIfCancellationRequested(); if (d.IsReady) { readyCount++; // This section only needs to run if you have the FabricObserverWebApi app installed... // Always log since these are the identifiers of each detected drive... this.diskInfo.AppendFormat("\n\nDrive Name: {0}\n", d.Name); // Logging... this.diskInfo.AppendFormat("Drive Type: {0}\n", d.DriveType); this.diskInfo.AppendFormat(" Volume Label : {0}\n", d.VolumeLabel); this.diskInfo.AppendFormat(" Filesystem : {0}\n", d.DriveFormat); this.diskInfo.AppendFormat(" Total Disk Size: {0} GB\n", d.TotalSize / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" Root Directory : {0}\n", d.RootDirectory); this.diskInfo.AppendFormat(" Free User : {0} GB\n", d.AvailableFreeSpace / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" Free Total: {0} GB\n", d.TotalFreeSpace / 1024 / 1024 / 1024); this.diskInfo.AppendFormat(" % Used : {0}%\n", diskUsage.GetCurrentDiskSpaceUsedPercent(d.Name)); // Setup monitoring data structures... string id = d.Name.Substring(0, 1); // Since these live across iterations, do not duplicate them in the containing list... if (!this.diskIOReadsData.Any(data => data.Id == id)) { this.diskIOReadsData.Add(new FabricResourceUsageData <float>("Disk sec/Read (ms)", id)); } if (!this.diskIOWritesData.Any(data => data.Id == id)) { this.diskIOWritesData.Add(new FabricResourceUsageData <float>("Disk sec/Write (ms)", id)); } // Disk space %... if (!this.diskSpacePercentageUsageData.Any(data => data.Id == id)) { this.diskSpacePercentageUsageData.Add(new FabricResourceUsageData <double>("Disk Space Consumption %", id)); } if (!this.diskSpaceUsageData.Any(data => data.Id == id)) { this.diskSpaceUsageData.Add(new FabricResourceUsageData <double>("Disk Space Consumption MB", id)); } if (!this.diskSpaceAvailableData.Any(data => data.Id == id)) { this.diskSpaceAvailableData.Add(new FabricResourceUsageData <double>("Disk Space Available MB", id)); } if (!this.diskSpaceTotalData.Any(data => data.Id == id)) { this.diskSpaceTotalData.Add(new FabricResourceUsageData <double>("Disk Space Total MB", id)); } // Current disk queue length... if (!this.diskAverageQueueLengthData.Any(data => data.Id == id)) { this.diskAverageQueueLengthData.Add(new FabricResourceUsageData <float>("Average Disk Queue Length", id)); } // Generate data over time (_monitorDuration...) for use in ReportAsync health analysis... this.stopWatch?.Start(); while (this.stopWatch?.Elapsed <= this.monitorDuration) { token.ThrowIfCancellationRequested(); this.diskIOReadsData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.PerfCounterGetDiskIOInfo(d.Name.Substring(0, 2), "LogicalDisk", "Avg. Disk sec/Read") * 1000); this.diskIOWritesData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.PerfCounterGetDiskIOInfo(d.Name.Substring(0, 2), "LogicalDisk", "Avg. Disk sec/Write") * 1000); this.diskSpacePercentageUsageData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetCurrentDiskSpaceUsedPercent(id)); this.diskSpaceUsageData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetUsedDiskSpace(id, SizeUnit.Megabytes)); this.diskSpaceAvailableData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetAvailabeDiskSpace(id, SizeUnit.Megabytes)); this.diskSpaceTotalData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetTotalDiskSpace(id, SizeUnit.Megabytes)); this.diskAverageQueueLengthData.FirstOrDefault( x => x.Id == id) .Data.Add(diskUsage.GetAverageDiskQueueLength(d.Name.Substring(0, 2))); Thread.Sleep(250); } // This section only needs to run if you have the FabricObserverWebApi app installed... this.diskInfo.AppendFormat( "{0}", this.GetWindowsPerfCounterDetailsText( this.diskIOReadsData.FirstOrDefault( x => x.Id == d.Name.Substring(0, 1)).Data, "Avg. Disk sec/Read")); this.diskInfo.AppendFormat( "{0}", this.GetWindowsPerfCounterDetailsText( this.diskIOWritesData.FirstOrDefault( x => x.Id == d.Name.Substring(0, 1)).Data, "Avg. Disk sec/Write")); this.diskInfo.AppendFormat( "{0}", this.GetWindowsPerfCounterDetailsText( this.diskAverageQueueLengthData.FirstOrDefault( x => x.Id == d.Name.Substring(0, 1)).Data, "Avg. Disk Queue Length")); this.stopWatch.Stop(); this.stopWatch.Reset(); } } } finally { diskUsage.Dispose(); diskUsage = null; } await this.ReportAsync(token).ConfigureAwait(true); this.LastRunDateTime = DateTime.Now; }