@@ -18,6 +18,7 @@ pub struct SubgraphInstanceMetrics {
18
18
pub firehose_connection_errors : Counter ,
19
19
pub stopwatch : StopwatchMetrics ,
20
20
pub deployment_status : DeploymentStatusMetric ,
21
+ pub deployment_synced : DeploymentSyncedMetric ,
21
22
22
23
trigger_processing_duration : Box < Histogram > ,
23
24
blocks_processed_secs : Box < Counter > ,
@@ -91,13 +92,16 @@ impl SubgraphInstanceMetrics {
91
92
)
92
93
. expect ( "failed to create blocks_processed_count counter" ) ;
93
94
95
+ let deployment_synced = DeploymentSyncedMetric :: register ( & registry, subgraph_hash) ;
96
+
94
97
Self {
95
98
block_trigger_count,
96
99
block_processing_duration,
97
100
block_ops_transaction_duration,
98
101
firehose_connection_errors,
99
102
stopwatch,
100
103
deployment_status,
104
+ deployment_synced,
101
105
trigger_processing_duration,
102
106
blocks_processed_secs,
103
107
blocks_processed_count,
@@ -120,6 +124,7 @@ impl SubgraphInstanceMetrics {
120
124
registry. unregister ( self . block_trigger_count . clone ( ) ) ;
121
125
registry. unregister ( self . trigger_processing_duration . clone ( ) ) ;
122
126
registry. unregister ( self . block_ops_transaction_duration . clone ( ) ) ;
127
+ registry. unregister ( Box :: new ( self . deployment_synced . inner . clone ( ) ) ) ;
123
128
}
124
129
}
125
130
@@ -213,3 +218,52 @@ impl DeploymentStatusMetric {
213
218
self . inner . set ( Self :: STATUS_FAILED ) ;
214
219
}
215
220
}
221
+
222
+ /// Indicates whether a deployment has reached the chain head since it was deployed.
223
+ pub struct DeploymentSyncedMetric {
224
+ inner : IntGauge ,
225
+
226
+ // If, for some reason, a deployment reports that it is synced, and then reports that it is not
227
+ // synced during an execution, this prevents the metric from reverting to the not synced state.
228
+ previously_synced : std:: sync:: OnceLock < ( ) > ,
229
+ }
230
+
231
+ impl DeploymentSyncedMetric {
232
+ const NOT_SYNCED : i64 = 0 ;
233
+ const SYNCED : i64 = 1 ;
234
+
235
+ /// Registers the metric.
236
+ pub fn register ( registry : & MetricsRegistry , deployment_hash : & str ) -> Self {
237
+ let metric = registry
238
+ . new_int_gauge (
239
+ "deployment_synced" ,
240
+ "Indicates whether a deployment has reached the chain head since it was deployed.\n \
241
+ Possible values:\n \
242
+ 0 - deployment is not synced;\n \
243
+ 1 - deployment is synced;",
244
+ [ ( "deployment" , deployment_hash) ] ,
245
+ )
246
+ . expect ( "failed to register `deployment_synced` gauge" ) ;
247
+
248
+ Self {
249
+ inner : metric,
250
+ previously_synced : std:: sync:: OnceLock :: new ( ) ,
251
+ }
252
+ }
253
+
254
+ /// Records the current sync status of the deployment.
255
+ /// Will ignore all values after the first `true` is received.
256
+ pub fn record ( & self , synced : bool ) {
257
+ if self . previously_synced . get ( ) . is_some ( ) {
258
+ return ;
259
+ }
260
+
261
+ if synced {
262
+ self . inner . set ( Self :: SYNCED ) ;
263
+ let _ = self . previously_synced . set ( ( ) ) ;
264
+ return ;
265
+ }
266
+
267
+ self . inner . set ( Self :: NOT_SYNCED ) ;
268
+ }
269
+ }
0 commit comments