- 
                Notifications
    You must be signed in to change notification settings 
- Fork 841
Add Windows disk I/O metrics to ResourceMonitoring #6181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    
      
        
          +926
        
        
          −3
        
        
          
        
      
    
  
  
     Merged
                    Changes from all commits
      Commits
    
    
            Show all changes
          
          
            31 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      555b98e
              
                create an empty file for WindowsDiskMetrics
              
              
                makazeu 2e8a9be
              
                Implement Windows Disk I/O bytes metric
              
              
                makazeu fe0c09b
              
                update
              
              
                makazeu 664053a
              
                Add SupportedOSPlatform attribute for Windows in disk metrics classes
              
              
                makazeu 3180f66
              
                update
              
              
                makazeu ccb3d27
              
                Fix property name for disk I/O metrics enabling in Windows
              
              
                makazeu 24e60bd
              
                update
              
              
                makazeu f6957fe
              
                Improve error handling in disk performance counter initialization
              
              
                makazeu 07ceca6
              
                Rename disk performance counter classes
              
              
                makazeu 9e12912
              
                Implement Disk Operations metric
              
              
                makazeu 37c9e8a
              
                Style updates
              
              
                makazeu 8bba5a4
              
                Add PlatformAttributes in LegacySupport
              
              
                makazeu 878e61b
              
                Add a simple unit test
              
              
                makazeu e9985af
              
                Add interfaces for PerformanceCounter
              
              
                makazeu 6d96e50
              
                update ut
              
              
                makazeu 6095dd0
              
                Merge branch 'main' into windows-disk-metrics
              
              
                makazeu 718bc13
              
                Use TimeProvider
              
              
                makazeu db2949a
              
                Add TimeProvider as a singleton in ResourceMonitoringServiceCollectio…
              
              
                makazeu 12edc8a
              
                Add unit tests for PerformanceCounterFactory and PerformanceCounterWr…
              
              
                makazeu 23a0f3d
              
                update
              
              
                makazeu 6c108da
              
                Add Unit Tests
              
              
                makazeu 080ae7d
              
                Refine
              
              
                makazeu a3efed7
              
                Refine
              
              
                makazeu 7053f3f
              
                Refine
              
              
                makazeu 93ea836
              
                Add WindowsDiskMetricsTests
              
              
                makazeu 54836ec
              
                Refine
              
              
                makazeu a1b620e
              
                Merge branch 'main' into windows-disk-metrics
              
              
                makazeu a1de91a
              
                clean
              
              
                makazeu a0395c0
              
                Refine
              
              
                makazeu c0fbc4d
              
                Merge branch 'main' into windows-disk-metrics
              
              
                makazeu d9d9194
              
                Merge branch 'dotnet:main' into windows-disk-metrics
              
              
                makazeu File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
        
          
          
            171 changes: 171 additions & 0 deletions
          
          171 
        
  src/LegacySupport/PlatformAttributes/PlatformAttributes.cs
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|  | ||
| #pragma warning disable S1694 | ||
| #pragma warning disable S3996 | ||
| #pragma warning disable SA1128 | ||
| #pragma warning disable SA1402 | ||
| #pragma warning disable SA1513 | ||
| #pragma warning disable SA1649 | ||
|  | ||
| namespace System.Runtime.Versioning | ||
| { | ||
| /// <summary> | ||
| /// Base type for all platform-specific API attributes. | ||
| /// </summary> | ||
| #pragma warning disable CS3015 // Type has no accessible constructors which use only CLS-compliant types | ||
| internal abstract class OSPlatformAttribute : Attribute | ||
| #pragma warning restore CS3015 | ||
| { | ||
| private protected OSPlatformAttribute(string platformName) | ||
| { | ||
| PlatformName = platformName; | ||
| } | ||
| public string PlatformName { get; } | ||
| } | ||
|  | ||
| /// <summary> | ||
| /// Records the platform that the project targeted. | ||
| /// </summary> | ||
| [AttributeUsage(AttributeTargets.Assembly, | ||
| AllowMultiple = false, Inherited = false)] | ||
| internal sealed class TargetPlatformAttribute : OSPlatformAttribute | ||
| { | ||
| public TargetPlatformAttribute(string platformName) : base(platformName) | ||
| { | ||
| } | ||
| } | ||
|  | ||
| /// <summary> | ||
| /// Records the operating system (and minimum version) that supports an API. Multiple attributes can be | ||
| /// applied to indicate support on multiple operating systems. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Callers can apply a <see cref="SupportedOSPlatformAttribute " /> | ||
| /// or use guards to prevent calls to APIs on unsupported operating systems. | ||
| /// | ||
| /// A given platform should only be specified once. | ||
| /// </remarks> | ||
| [AttributeUsage(AttributeTargets.Assembly | | ||
| AttributeTargets.Class | | ||
| AttributeTargets.Constructor | | ||
| AttributeTargets.Enum | | ||
| AttributeTargets.Event | | ||
| AttributeTargets.Field | | ||
| AttributeTargets.Interface | | ||
| AttributeTargets.Method | | ||
| AttributeTargets.Module | | ||
| AttributeTargets.Property | | ||
| AttributeTargets.Struct, | ||
| AllowMultiple = true, Inherited = false)] | ||
| internal sealed class SupportedOSPlatformAttribute : OSPlatformAttribute | ||
| { | ||
| public SupportedOSPlatformAttribute(string platformName) : base(platformName) | ||
| { | ||
| } | ||
| } | ||
|  | ||
| /// <summary> | ||
| /// Marks APIs that were removed in a given operating system version. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Primarily used by OS bindings to indicate APIs that are only available in | ||
| /// earlier versions. | ||
| /// </remarks> | ||
| [AttributeUsage(AttributeTargets.Assembly | | ||
| AttributeTargets.Class | | ||
| AttributeTargets.Constructor | | ||
| AttributeTargets.Enum | | ||
| AttributeTargets.Event | | ||
| AttributeTargets.Field | | ||
| AttributeTargets.Interface | | ||
| AttributeTargets.Method | | ||
| AttributeTargets.Module | | ||
| AttributeTargets.Property | | ||
| AttributeTargets.Struct, | ||
| AllowMultiple = true, Inherited = false)] | ||
| internal sealed class UnsupportedOSPlatformAttribute : OSPlatformAttribute | ||
| { | ||
| public UnsupportedOSPlatformAttribute(string platformName) : base(platformName) | ||
| { | ||
| } | ||
| public UnsupportedOSPlatformAttribute(string platformName, string? message) : base(platformName) | ||
| { | ||
| Message = message; | ||
| } | ||
| public string? Message { get; } | ||
| } | ||
|  | ||
| /// <summary> | ||
| /// Marks APIs that were obsoleted in a given operating system version. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Primarily used by OS bindings to indicate APIs that should not be used anymore. | ||
| /// </remarks> | ||
| [AttributeUsage(AttributeTargets.Assembly | | ||
| AttributeTargets.Class | | ||
| AttributeTargets.Constructor | | ||
| AttributeTargets.Enum | | ||
| AttributeTargets.Event | | ||
| AttributeTargets.Field | | ||
| AttributeTargets.Interface | | ||
| AttributeTargets.Method | | ||
| AttributeTargets.Module | | ||
| AttributeTargets.Property | | ||
| AttributeTargets.Struct, | ||
| AllowMultiple = true, Inherited = false)] | ||
| internal sealed class ObsoletedOSPlatformAttribute : OSPlatformAttribute | ||
| { | ||
| public ObsoletedOSPlatformAttribute(string platformName) : base(platformName) | ||
| { | ||
| } | ||
| public ObsoletedOSPlatformAttribute(string platformName, string? message) : base(platformName) | ||
| { | ||
| Message = message; | ||
| } | ||
| public string? Message { get; } | ||
| public string? Url { get; set; } | ||
| } | ||
|  | ||
| /// <summary> | ||
| /// Annotates a custom guard field, property or method with a supported platform name and optional version. | ||
| /// Multiple attributes can be applied to indicate guard for multiple supported platforms. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Callers can apply a <see cref="SupportedOSPlatformGuardAttribute " /> to a field, property or method | ||
| /// and use that field, property or method in a conditional or assert statements in order to safely call platform specific APIs. | ||
| /// | ||
| /// The type of the field or property should be boolean, the method return type should be boolean in order to be used as platform guard. | ||
| /// </remarks> | ||
| [AttributeUsage(AttributeTargets.Field | | ||
| AttributeTargets.Method | | ||
| AttributeTargets.Property, | ||
| AllowMultiple = true, Inherited = false)] | ||
| internal sealed class SupportedOSPlatformGuardAttribute : OSPlatformAttribute | ||
| { | ||
| public SupportedOSPlatformGuardAttribute(string platformName) : base(platformName) | ||
| { | ||
| } | ||
| } | ||
|  | ||
| /// <summary> | ||
| /// Annotates the custom guard field, property or method with an unsupported platform name and optional version. | ||
| /// Multiple attributes can be applied to indicate guard for multiple unsupported platforms. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Callers can apply a <see cref="UnsupportedOSPlatformGuardAttribute " /> to a field, property or method | ||
| /// and use that field, property or method in a conditional or assert statements as a guard to safely call APIs unsupported on those platforms. | ||
| /// | ||
| /// The type of the field or property should be boolean, the method return type should be boolean in order to be used as platform guard. | ||
| /// </remarks> | ||
| [AttributeUsage(AttributeTargets.Field | | ||
| AttributeTargets.Method | | ||
| AttributeTargets.Property, | ||
| AllowMultiple = true, Inherited = false)] | ||
| internal sealed class UnsupportedOSPlatformGuardAttribute : OSPlatformAttribute | ||
| { | ||
| public UnsupportedOSPlatformGuardAttribute(string platformName) : base(platformName) | ||
| { | ||
| } | ||
| } | ||
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| Enables use of C# OSPlatform attributes on older frameworks. | ||
|  | ||
| To use this source in your project, add the following to your `.csproj` file: | ||
|  | ||
| ```xml | ||
| <PropertyGroup> | ||
| <InjectPlatformAttributesOnLegacy>true</InjectPlatformAttributesOnLegacy> | ||
| </PropertyGroup> | ||
| ``` | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
        
          
  
    
      
          
            83 changes: 83 additions & 0 deletions
          
          83 
        
  ...ft.Extensions.Diagnostics.ResourceMonitoring/Windows/Disk/WindowsDiskIoRatePerfCounter.cs
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|  | ||
| using System; | ||
| using System.Collections.Concurrent; | ||
| using System.Collections.Generic; | ||
| using System.Runtime.Versioning; | ||
|  | ||
| namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows.Disk; | ||
|  | ||
| [SupportedOSPlatform("windows")] | ||
| internal sealed class WindowsDiskIoRatePerfCounter | ||
| { | ||
| private readonly List<IPerformanceCounter> _counters = []; | ||
| private readonly IPerformanceCounterFactory _performanceCounterFactory; | ||
| private readonly TimeProvider _timeProvider; | ||
| private readonly string _categoryName; | ||
| private readonly string _counterName; | ||
| private readonly string[] _instanceNames; | ||
| private long _lastTimestamp; | ||
|  | ||
| internal WindowsDiskIoRatePerfCounter( | ||
| IPerformanceCounterFactory performanceCounterFactory, | ||
| TimeProvider timeProvider, | ||
| string categoryName, | ||
| string counterName, | ||
| string[] instanceNames) | ||
| { | ||
| _performanceCounterFactory = performanceCounterFactory; | ||
| _timeProvider = timeProvider; | ||
| _categoryName = categoryName; | ||
| _counterName = counterName; | ||
| _instanceNames = instanceNames; | ||
| } | ||
|  | ||
| /// <summary> | ||
| /// Gets the disk I/O measurements. | ||
| /// Key: Disk name, Value: Total count. | ||
| /// </summary> | ||
| internal IDictionary<string, long> TotalCountDict { get; } = new ConcurrentDictionary<string, long>(); | ||
|  | ||
| internal void InitializeDiskCounters() | ||
| { | ||
| foreach (string instanceName in _instanceNames) | ||
| { | ||
| // Skip the total instance | ||
| if (instanceName.Equals("_Total", StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| continue; | ||
| } | ||
|  | ||
| // Create counters for each disk | ||
| _counters.Add(_performanceCounterFactory.Create(_categoryName, _counterName, instanceName)); | ||
| TotalCountDict.Add(instanceName, 0); | ||
| } | ||
|  | ||
| // Initialize the counters to get the first value | ||
| foreach (IPerformanceCounter counter in _counters) | ||
| { | ||
| _ = counter.NextValue(); | ||
| } | ||
|  | ||
| _lastTimestamp = _timeProvider.GetUtcNow().ToUnixTimeMilliseconds(); | ||
| } | ||
|  | ||
| internal void UpdateDiskCounters() | ||
| { | ||
| long currentTimestamp = _timeProvider.GetUtcNow().ToUnixTimeMilliseconds(); | ||
| double elapsedSeconds = (currentTimestamp - _lastTimestamp) / 1000.0; // Convert to seconds | ||
|  | ||
| // For the kind of "rate" perf counters, this algorithm calculates the total value over a time interval | ||
| // by multiplying the per-second rate (e.g., Disk Bytes/sec) by the time interval between two samples. | ||
| // This effectively reverses the per-second rate calculation to a total amount (e.g., total bytes transferred) during that period. | ||
| foreach (IPerformanceCounter counter in _counters) | ||
| { | ||
| // total value = per-second rate * elapsed seconds | ||
| double value = counter.NextValue() * elapsedSeconds; | ||
| TotalCountDict[counter.InstanceName] += (long)value; | ||
| } | ||
|  | ||
| _lastTimestamp = currentTimestamp; | ||
| } | ||
| } | 
      
      Oops, something went wrong.
        
    
  
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.