1
+ using System . Diagnostics ;
1
2
using NTorSpectator . Observer . TorIntegration ;
2
3
using NTorSpectator . Services ;
3
4
using NTorSpectator . Services . Models ;
5
+ using Prometheus ;
4
6
using Quartz ;
5
7
6
8
namespace NTorSpectator . Observer . Services ;
7
9
8
10
public class SpectatorJob : IJob
9
11
{
12
+ private static readonly Gauge QueueLength = Metrics . CreateGauge ( "sites_queue_length" , "Length of the queue left to observe" ) ;
13
+ private static readonly Counter ObservationsCount = Metrics . CreateCounter ( "observations" , "counts all observations" ) ;
14
+ private static readonly Counter RetriesCount = Metrics . CreateCounter ( "enqueued_retries" , "counts retires" ) ;
15
+ private static readonly Histogram RequestDuration = Metrics . CreateHistogram ( "observation_duration" , "duration of site observation" ,
16
+ new HistogramConfiguration
17
+ {
18
+ Buckets = Histogram . LinearBuckets ( 0.5 , 0.5 , 20 )
19
+ } ) ;
20
+ private static readonly Gauge TotalSessionDuration = Metrics . CreateGauge ( "observation_session_duration" , "Total observation session duration, ms" ) ;
21
+
10
22
private readonly ILogger < SpectatorJob > _logger ;
11
23
private readonly ISitesCatalogue _sitesCatalogue ;
12
24
private readonly TorControlManager _torControl ;
@@ -22,18 +34,22 @@ public SpectatorJob(ILogger<SpectatorJob> logger, ISitesCatalogue sitesCatalogue
22
34
23
35
public async Task Execute ( IJobExecutionContext context )
24
36
{
37
+ TotalSessionDuration . Set ( 0 ) ;
38
+ var sw = Stopwatch . StartNew ( ) ;
25
39
_logger . LogDebug ( "Starting sites observations" ) ;
26
40
var sites = await _sitesCatalogue . GetAllSites ( ) ;
27
41
_logger . LogDebug ( "Got {Count} sites to observe" , sites . Count ) ;
28
42
29
43
var siteQueue = new Queue < QueuedSite > ( sites . Select ( x => new QueuedSite ( x , 0 ) ) ) ;
30
44
while ( siteQueue . TryDequeue ( out var queuedSite ) )
31
45
{
46
+ QueueLength . Set ( siteQueue . Count ) ;
32
47
using var _ = _logger . BeginScope ( new Dictionary < string , object > { { "HiddenService" , queuedSite . Site . SiteUri } } ) ;
33
48
_logger . LogDebug ( "Starting observations on the next site" ) ;
34
49
try
35
50
{
36
51
var observations = await ObserveSite ( queuedSite . Site . SiteUri ) ;
52
+ ObservationsCount . Inc ( ) ;
37
53
if ( ! observations . IsOk )
38
54
{
39
55
_logger . LogDebug ( "Site observed as not available" ) ;
@@ -42,6 +58,7 @@ public async Task Execute(IJobExecutionContext context)
42
58
{
43
59
_logger . LogDebug ( "Site has been observed {Count} times, returning it to queue" , siteObservationsCount ) ;
44
60
siteQueue . Enqueue ( queuedSite with { ObservationsCount = siteObservationsCount + 1 } ) ;
61
+ RetriesCount . Inc ( ) ;
45
62
continue ;
46
63
}
47
64
}
@@ -55,12 +72,15 @@ public async Task Execute(IJobExecutionContext context)
55
72
}
56
73
}
57
74
_logger . LogDebug ( "The queue is finally empty, observations finished" ) ;
75
+ sw . Stop ( ) ;
76
+ TotalSessionDuration . Set ( sw . ElapsedMilliseconds ) ;
58
77
}
59
78
60
79
private record QueuedSite ( Site Site , int ObservationsCount ) ;
61
80
62
81
private async Task < TorWatchResults > ObserveSite ( string site )
63
82
{
83
+ using var _ = RequestDuration . NewTimer ( ) ;
64
84
var torReply = await _torControl . HsFetch ( site ) ;
65
85
var positive = torReply . Count ( x => x . Action == HsDescAction . Received ) ;
66
86
var negative = torReply . Count ( x => x . Action == HsDescAction . Failed ) ;
0 commit comments