77// Variant of https://github.com/dotnet/core/tree/main/samples/dotnet-runtimeinfo
88// Ascii text: https://ascii.co.uk/text (Univers font)
99
10- string nl = Environment . NewLine ;
11-
12- WriteLine (
13- $ " 42{ nl } " +
14- $ " 42 ,d ,d{ nl } " +
15- $ " 42 42 42{ nl } " +
16- $ " ,adPPYb,42 ,adPPYba, MM42MMM 8b,dPPYba, ,adPPYba, MM42MMM{ nl } " +
17- $ "a8\" `Y42 a8\" \" 8a 42 42P\' `\" 8a a8P_____42 42{ nl } " +
18- $ "8b 42 8b d8 42 42 42 8PP\" \" \" \" \" \" \" 42{ nl } " +
19- $ "\" 8a, ,d42 \" 8a, ,a8\" 42, 42 42 \" 8b, ,aa 42,{ nl } " +
20- $ " `\" 8bbdP\" Y8 `\" YbbdP\" \' \" Y428 42 42 `\" Ybbd8\" \' \" Y428{ nl } ") ;
10+ WriteLine ( """
11+ 42
12+ 42 ,d ,d
13+ 42 42 42
14+ ,adPPYb,42 ,adPPYba, MM42MMM 8b,dPPYba, ,adPPYba, MM42MMM
15+ a8" `Y42 a8" "8a 42 42P' `"8a a8P_____42 42
16+ 8b 42 8b d8 42 42 42 8PP!!!!!!! 42
17+ "8a, ,d42 "8a, ,a8" 42, 42 42 "8b, ,aa 42,
18+ `"8bbdP"Y8 `"YbbdP"' "Y428 42 42 `"Ybbd8"' "Y428
2119
20+ """ ) ;
2221
2322// .NET information
2423WriteLine ( RuntimeInformation . FrameworkDescription ) ;
5049const long Gibi = Mebi * 1024 ;
5150GCMemoryInfo gcInfo = GC . GetGCMemoryInfo ( ) ;
5251long totalMemoryBytes = gcInfo . TotalAvailableMemoryBytes ;
53- string totalAvailableMemory = GetInBestUnit ( totalMemoryBytes ) ;
5452
5553// Environment information
54+ WriteLine ( $ "{ nameof ( Environment . UserName ) } : { Environment . UserName } ") ;
5655WriteLine ( $ "{ nameof ( RuntimeInformation . OSArchitecture ) } : { RuntimeInformation . OSArchitecture } ") ;
5756WriteLine ( $ "{ nameof ( Environment . ProcessorCount ) } : { Environment . ProcessorCount } ") ;
58- WriteLine ( $ "{ nameof ( GCMemoryInfo . TotalAvailableMemoryBytes ) } : { totalAvailableMemory } ") ;
57+ WriteLine ( $ "{ nameof ( GCMemoryInfo . TotalAvailableMemoryBytes ) } : { totalMemoryBytes } ( { GetInBestUnit ( totalMemoryBytes ) } ) ") ;
5958
60- // cgroup information
61- if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) &&
62- Directory . Exists ( "/sys/fs/cgroup/cpu" ) &&
63- Directory . Exists ( "/sys/fs/cgroup/memory" ) &&
64- File . Exists ( "sys/fs/cgroup/cpu/cpu.cfs_quota_us" ) )
59+ string [ ] memoryLimitPaths = new string [ ]
6560{
66- // get cpu cgroup information
67- string cpuquota = File . ReadAllLines ( "/sys/fs/cgroup/cpu/cpu.cfs_quota_us" ) [ 0 ] ;
68- if ( int . TryParse ( cpuquota , out int quota ) &&
69- quota > 0 )
70- {
71- WriteLine ( $ "cfs_quota_us: { quota } ") ;
72- }
61+ "/sys/fs/cgroup/memory.max" ,
62+ "/sys/fs/cgroup/memory/memory.limit_in_bytes" ,
63+ } ;
7364
65+ string [ ] currentMemoryPaths = new string [ ]
66+ {
67+ "/sys/fs/cgroup/memory.current" ,
68+ "/sys/fs/cgroup/memory/memory.usage_in_bytes" ,
69+ } ;
70+
71+ // cgroup information
72+ if ( OperatingSystem . IsLinux ( ) )
73+ {
7474 // get memory cgroup information
75- string usageBytes = File . ReadAllLines ( "/sys/fs/cgroup/memory/memory.usage_in_bytes" ) [ 0 ] ;
76- string limitBytes = File . ReadAllLines ( "/sys/fs/cgroup/memory/memory.limit_in_bytes" ) [ 0 ] ;
77- if ( long . TryParse ( usageBytes , out long usage ) &&
78- long . TryParse ( limitBytes , out long limit ) &&
79- // above this size is unlikely to be an intentionally constrained cgroup
80- limit < 10 * Gibi )
75+ long memoryLimit = GetBestValue ( memoryLimitPaths ) ;
76+ long currentMemory = GetBestValue ( currentMemoryPaths ) ;
77+
78+ if ( memoryLimit > 0 )
8179 {
82- WriteLine ( $ "usage_in_bytes : { usageBytes } { GetInBestUnit ( usage ) } ") ;
83- WriteLine ( $ "limit_in_bytes : { limitBytes } { GetInBestUnit ( limit ) } ") ;
84- WriteLine ( $ "GC Hard limit %: { decimal . Divide ( totalMemoryBytes , limit ) * 100 } ") ;
80+ WriteLine ( $ "cgroup memory limit : { memoryLimit } ( { GetInBestUnit ( memoryLimit ) } ) ") ;
81+ WriteLine ( $ "cgroup memory usage : { currentMemory } ( { GetInBestUnit ( currentMemory ) } ) ") ;
82+ WriteLine ( $ "GC Hard limit %: { ( double ) totalMemoryBytes / memoryLimit * 100 : N0 } ") ;
8583 }
8684}
8785
@@ -93,12 +91,32 @@ string GetInBestUnit(long size)
9391 }
9492 else if ( size < Gibi )
9593 {
96- decimal mebibytes = Decimal . Divide ( size , Mebi ) ;
94+ double mebibytes = ( double ) ( size / Mebi ) ;
9795 return $ "{ mebibytes : F} MiB";
9896 }
9997 else
10098 {
101- decimal gibibytes = Decimal . Divide ( size , Gibi ) ;
99+ double gibibytes = ( double ) ( size / Gibi ) ;
102100 return $ "{ gibibytes : F} GiB";
103101 }
104102}
103+
104+ long GetBestValue ( string [ ] paths )
105+ {
106+ string value = string . Empty ;
107+ foreach ( string path in paths )
108+ {
109+ if ( Path . Exists ( path ) )
110+ {
111+ value = File . ReadAllText ( path ) ;
112+ break ;
113+ }
114+ }
115+
116+ if ( int . TryParse ( value , out int result ) )
117+ {
118+ return result ;
119+ }
120+
121+ return 0 ;
122+ }
0 commit comments