1+ namespace ServiceControl . Audit . Persistence . RavenDB . CustomChecks ;
2+
3+ using System ;
4+ using System . Collections . Generic ;
5+ using System . Threading ;
6+ using System . Threading . Tasks ;
7+ using NServiceBus . CustomChecks ;
8+
9+ class CheckDirtyMemory ( IRavenDocumentStoreProvider documentStoreProvider ) : CustomCheck ( "ServiceControl.Audit database" , "Dirty memory trends" , TimeSpan . FromMinutes ( 5 ) )
10+ {
11+ readonly List < int > lastDirtyMemoryReads = [ ] ;
12+ public override async Task < CheckResult > PerformCheck ( CancellationToken cancellationToken = default )
13+ {
14+ var retriever = await GetMemoryRetriever ( cancellationToken ) ;
15+ var memoryInfo = await retriever . GetMemoryInformation ( cancellationToken ) ;
16+
17+ if ( memoryInfo . IsHighDirty )
18+ {
19+ //log warning
20+ return CheckResult . Failed ( "There is a high level of dirty memory. Check the ServiceControl " +
21+ "troubleshooting guide for guidance on how to mitigate the issue." ) ;
22+ }
23+
24+ lastDirtyMemoryReads . Add ( memoryInfo . DirtyMemory ) ;
25+ if ( lastDirtyMemoryReads . Count > 20 )
26+ {
27+ //cap the list at 20
28+ lastDirtyMemoryReads . RemoveAt ( lastDirtyMemoryReads . Count - 1 ) ;
29+ }
30+
31+ // evaluate the trends
32+ // if the amount of dirty memory is constantly growing log a warning and fail the check
33+
34+ return CheckResult . Pass ;
35+ }
36+
37+ MemoryInformationRetriever _retriever ;
38+ async Task < MemoryInformationRetriever > GetMemoryRetriever ( CancellationToken cancellationToken = default )
39+ {
40+ if ( _retriever == null )
41+ {
42+ var documentStore = await documentStoreProvider . GetDocumentStore ( cancellationToken ) ;
43+ var serverUrl = documentStore . Urls [ 0 ] ; //TODO is there a better way to get the RavenDB server URL?
44+ _retriever = new MemoryInformationRetriever ( serverUrl ) ;
45+ }
46+ return _retriever ;
47+ }
48+ }
0 commit comments