@@ -91,11 +91,56 @@ const runGtfsMatching = async (cfg, opt = {}) => {
91
91
}
92
92
ok ( Number . isInteger ( natsAckWait ) , 'opt.natsAckWait must be an integer' )
93
93
94
+ // NATS-related metrics
95
+ // Note: We mirror OpenDataVBB/gtfs-rt-feed's metrics here.
96
+ const natsNrOfMessagesReceivedTotal = new Counter ( {
97
+ name : 'nats_nr_of_msgs_received_total' ,
98
+ help : 'number of messages received from NATS' ,
99
+ registers : [ register ] ,
100
+ labelNames : [
101
+ 'stream' , // name of the JetStream stream
102
+ 'consumer' , // name of the JetStream consumer
103
+ 'topic_root' , // first "segment" of the topic, e.g. `AUS` with `aus.istfahrt.foo.bar`
104
+ 'redelivered' , // 1/0
105
+ ] ,
106
+ } )
107
+ const natsLatestMessageReceivedTimestampSeconds = new Gauge ( {
108
+ name : 'nats_latest_msg_received_timestamp_seconds' ,
109
+ help : 'when the latest message has been received from NATS' ,
110
+ registers : [ register ] ,
111
+ labelNames : [
112
+ 'stream' , // name of the JetStream stream
113
+ 'consumer' , // name of the JetStream consumer
114
+ 'topic_root' , // first "segment" of the topic, e.g. `AUS` with `aus.istfahrt.foo.bar`
115
+ 'redelivered' , // 1/0
116
+ ] ,
117
+ } )
118
+ // todo: track redeliveries as `Summary` using `msg.info.redeliveryCount`
119
+ const natsNrOfMessagesSentTotal = new Counter ( {
120
+ name : 'nats_nr_of_msgs_sent_total' ,
121
+ help : 'number of messages sent to NATS' ,
122
+ registers : [ register ] ,
123
+ labelNames : [
124
+ 'topic_root' , // first "segment" of the topic, e.g. `AUS` with `aus.istfahrt.foo.bar`
125
+ ] ,
126
+ } )
127
+ const natsLatestMessageSentTimestampSeconds = new Gauge ( {
128
+ name : 'nats_latest_msg_sent_timestamp_seconds' ,
129
+ help : 'when the latest message has been sent to NATS' ,
130
+ registers : [ register ] ,
131
+ labelNames : [
132
+ 'topic_root' , // first "segment" of the topic, e.g. `AUS` with `aus.istfahrt.foo.bar`
133
+ ] ,
134
+ } )
135
+ // NATS gives separate sequence numbers to both a) messages in a stream and b) messages as (re-)received by a consumer.
136
+ // We currently use `msg.seq`. – todo: what is that?
137
+ // todo [breaking]: change ot use the stream sequence or remove this metric, as it's misleading!
94
138
const natsMsgSeq = new Gauge ( {
95
139
name : 'nats_msg_seq' ,
96
140
help : 'sequence number of the latest NATS message being processed' ,
97
141
registers : [ register ] ,
98
142
} )
143
+
99
144
const successesTotal = new Counter ( {
100
145
name : 'matching_successes_total' ,
101
146
help : 'number of successfully matched movements/trips' ,
@@ -143,6 +188,7 @@ const runGtfsMatching = async (cfg, opt = {}) => {
143
188
} = await matchVdvAusIstFahrtWithGtfs ( vdvAusIstFahrt )
144
189
145
190
const topic = getNatsTopicFromGtfsRtTripUpdate ( gtfsRtTripUpdate )
191
+ const tPublished = Date . now ( )
146
192
147
193
logger . trace ( {
148
194
topic,
@@ -156,6 +202,18 @@ const runGtfsMatching = async (cfg, opt = {}) => {
156
202
} , 'publishing GTFS-RT TripUpdate' )
157
203
natsClient . publish ( topic , natsJson . encode ( gtfsRtTripUpdate ) )
158
204
205
+ // update NATS metrics
206
+ {
207
+ // We slice() to keep the cardinality low in case of a bug.
208
+ const topic_root = ( topic . split ( '.' ) [ 0 ] || '' ) . slice ( 0 , 7 )
209
+ natsNrOfMessagesSentTotal . inc ( {
210
+ topic_root,
211
+ } )
212
+ natsLatestMessageSentTimestampSeconds . set ( {
213
+ topic_root,
214
+ } , tPublished / 1000 )
215
+ }
216
+
159
217
if ( isMatched ) {
160
218
successesTotal . inc ( {
161
219
cached : isCached ? '1' : '0' ,
@@ -181,6 +239,7 @@ const runGtfsMatching = async (cfg, opt = {}) => {
181
239
}
182
240
183
241
const processAusIstFahrtMsg = async ( msg ) => {
242
+ const tReceived = Date . now ( )
184
243
const {
185
244
subject,
186
245
seq,
@@ -193,7 +252,30 @@ const runGtfsMatching = async (cfg, opt = {}) => {
193
252
redelivered,
194
253
dataSlice : data . slice ( 0 , 100 ) . toString ( 'utf8' ) ,
195
254
} , 'processing AUS IstFahrt msg' )
196
- natsMsgSeq . set ( seq ) // todo: is `seq` an integer?
255
+
256
+ // update NATS metrics
257
+ {
258
+ const {
259
+ stream,
260
+ consumer,
261
+ } = msg . info
262
+ // We slice() to keep the cardinality low in case of a bug.
263
+ const topic_root = ( subject . split ( '.' ) [ 0 ] || '' ) . slice ( 0 , 7 )
264
+ const redelivered = msg . info . redelivered ? '1' : '0'
265
+ natsNrOfMessagesReceivedTotal . inc ( {
266
+ stream, // name of the JetStream stream
267
+ consumer, // name of the JetStream consumer
268
+ topic_root,
269
+ redelivered,
270
+ } )
271
+ natsLatestMessageReceivedTimestampSeconds . set ( {
272
+ stream, // name of the JetStream stream
273
+ consumer, // name of the JetStream consumer
274
+ topic_root,
275
+ redelivered,
276
+ } , tReceived / 1000 )
277
+ natsMsgSeq . set ( seq )
278
+ }
197
279
198
280
let ausIstFahrt = null
199
281
try {
0 commit comments