Skip to content

Commit f35e1d0

Browse files
authored
feat: add prometheus monitoring (#356)
* feat: add prometheus monitoring * chore: progress * fix: create object * chore: port config * chore: set initial metrics on start * fix: monitor predicates * test: add
1 parent 5692426 commit f35e1d0

File tree

12 files changed

+304
-43
lines changed

12 files changed

+304
-43
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/ordhook-cli/src/cli/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use ordhook::scan::bitcoin::scan_bitcoin_chainstate_via_rpc_using_predicate;
3737
use ordhook::service::observers::initialize_observers_db;
3838
use ordhook::service::{start_observer_forwarding, Service};
3939
use ordhook::utils::bitcoind::bitcoind_get_block_height;
40+
use ordhook::utils::monitoring::PrometheusMonitoring;
4041
use ordhook::{hex, initialize_databases, try_error, try_info, try_warn};
4142
use reqwest::Client as HttpClient;
4243
use std::collections::HashSet;
@@ -883,8 +884,12 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
883884
_ => None,
884885
};
885886
let blocks = cmd.get_blocks();
886-
let inscription_indexing_processor =
887-
start_inscription_indexing_processor(&config, ctx, block_post_processor);
887+
let inscription_indexing_processor = start_inscription_indexing_processor(
888+
&config,
889+
ctx,
890+
block_post_processor,
891+
&PrometheusMonitoring::new(),
892+
);
888893

889894
download_and_pipeline_blocks(
890895
&config,

components/ordhook-cli/src/config/file.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
use ordhook::chainhook_sdk::indexer::IndexerConfig;
21
use ordhook::chainhook_sdk::observer::DEFAULT_INGESTION_PORT;
32
use ordhook::chainhook_sdk::types::{
43
BitcoinBlockSignaling, BitcoinNetwork, StacksNetwork, StacksNodeConfig,
54
};
65
use ordhook::config::{
7-
Config, LogConfig, MetaProtocolsConfig, PredicatesApi, PredicatesApiConfig, ResourcesConfig,
8-
SnapshotConfig, SnapshotConfigDownloadUrls, StorageConfig, DEFAULT_BITCOIND_RPC_THREADS,
9-
DEFAULT_BITCOIND_RPC_TIMEOUT, DEFAULT_BRC20_LRU_CACHE_SIZE, DEFAULT_CONTROL_PORT,
10-
DEFAULT_MEMORY_AVAILABLE, DEFAULT_ULIMIT,
6+
Config, IndexerConfig, LogConfig, MetaProtocolsConfig, PredicatesApi, PredicatesApiConfig,
7+
ResourcesConfig, SnapshotConfig, SnapshotConfigDownloadUrls, StorageConfig,
8+
DEFAULT_BITCOIND_RPC_THREADS, DEFAULT_BITCOIND_RPC_TIMEOUT, DEFAULT_BRC20_LRU_CACHE_SIZE,
9+
DEFAULT_CONTROL_PORT, DEFAULT_MEMORY_AVAILABLE, DEFAULT_ULIMIT,
1110
};
1211
use std::fs::File;
1312
use std::io::{BufReader, Read};
@@ -43,7 +42,7 @@ impl ConfigFile {
4342
}
4443

4544
pub fn from_config_file(config_file: ConfigFile) -> Result<Config, String> {
46-
let (stacks_network, bitcoin_network) = match config_file.network.mode.as_str() {
45+
let (_, bitcoin_network) = match config_file.network.mode.as_str() {
4746
"devnet" => (StacksNetwork::Devnet, BitcoinNetwork::Regtest),
4847
"testnet" => (StacksNetwork::Testnet, BitcoinNetwork::Testnet),
4948
"mainnet" => (StacksNetwork::Mainnet, BitcoinNetwork::Mainnet),
@@ -115,14 +114,11 @@ impl ConfigFile {
115114
bitcoin_block_signaling: match config_file.network.bitcoind_zmq_url {
116115
Some(ref zmq_url) => BitcoinBlockSignaling::ZeroMQ(zmq_url.clone()),
117116
None => BitcoinBlockSignaling::Stacks(StacksNodeConfig::default_localhost(
118-
config_file
119-
.network
120-
.stacks_events_ingestion_port
121-
.unwrap_or(DEFAULT_INGESTION_PORT),
117+
DEFAULT_INGESTION_PORT,
122118
)),
123119
},
124-
stacks_network,
125120
bitcoin_network,
121+
prometheus_monitoring_port: config_file.network.prometheus_monitoring_port,
126122
},
127123
logs: LogConfig {
128124
ordinals_internals: config_file
@@ -220,6 +216,5 @@ pub struct NetworkConfigFile {
220216
pub bitcoind_rpc_username: String,
221217
pub bitcoind_rpc_password: String,
222218
pub bitcoind_zmq_url: Option<String>,
223-
pub stacks_node_rpc_url: Option<String>,
224-
pub stacks_events_ingestion_port: Option<u16>,
219+
pub prometheus_monitoring_port: Option<u16>,
225220
}

components/ordhook-core/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ hyper = { version = "=0.14.27" }
4646
lazy_static = { version = "1.4.0" }
4747
ciborium = "0.2.1"
4848
regex = "1.10.3"
49+
prometheus = "0.13.3"
4950

5051
[dev-dependencies]
5152
test-case = "3.1.0"

components/ordhook-core/src/config/mod.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::core::OrdhookConfig;
2-
pub use chainhook_sdk::indexer::IndexerConfig;
32
use chainhook_sdk::observer::EventObserverConfig;
43
use chainhook_sdk::types::{
54
BitcoinBlockSignaling, BitcoinNetwork, StacksNetwork, StacksNodeConfig,
@@ -81,6 +80,16 @@ pub struct UrlConfig {
8180
pub file_url: String,
8281
}
8382

83+
#[derive(Debug, Clone)]
84+
pub struct IndexerConfig {
85+
pub bitcoin_network: BitcoinNetwork,
86+
pub bitcoind_rpc_url: String,
87+
pub bitcoind_rpc_username: String,
88+
pub bitcoind_rpc_password: String,
89+
pub bitcoin_block_signaling: BitcoinBlockSignaling,
90+
pub prometheus_monitoring_port: Option<u16>,
91+
}
92+
8493
#[derive(Deserialize, Debug, Clone)]
8594
pub struct ResourcesConfig {
8695
pub ulimit: usize,
@@ -136,7 +145,7 @@ impl Config {
136145
display_logs: false,
137146
cache_path: self.storage.working_dir.clone(),
138147
bitcoin_network: self.network.bitcoin_network.clone(),
139-
stacks_network: self.network.stacks_network.clone(),
148+
stacks_network: StacksNetwork::Devnet,
140149
prometheus_monitoring_port: None,
141150
data_handler_tx: None,
142151
}
@@ -192,8 +201,8 @@ impl Config {
192201
bitcoin_block_signaling: BitcoinBlockSignaling::Stacks(
193202
StacksNodeConfig::default_localhost(DEFAULT_INGESTION_PORT),
194203
),
195-
stacks_network: StacksNetwork::Devnet,
196204
bitcoin_network: BitcoinNetwork::Regtest,
205+
prometheus_monitoring_port: None,
197206
},
198207
logs: LogConfig {
199208
ordinals_internals: true,
@@ -227,8 +236,8 @@ impl Config {
227236
bitcoin_block_signaling: BitcoinBlockSignaling::Stacks(
228237
StacksNodeConfig::default_localhost(DEFAULT_INGESTION_PORT),
229238
),
230-
stacks_network: StacksNetwork::Testnet,
231239
bitcoin_network: BitcoinNetwork::Testnet,
240+
prometheus_monitoring_port: Some(9153),
232241
},
233242
logs: LogConfig {
234243
ordinals_internals: true,
@@ -265,8 +274,8 @@ impl Config {
265274
bitcoin_block_signaling: BitcoinBlockSignaling::Stacks(
266275
StacksNodeConfig::default_localhost(DEFAULT_INGESTION_PORT),
267276
),
268-
stacks_network: StacksNetwork::Mainnet,
269277
bitcoin_network: BitcoinNetwork::Mainnet,
278+
prometheus_monitoring_port: Some(9153),
270279
},
271280
logs: LogConfig {
272281
ordinals_internals: true,

components/ordhook-core/src/core/pipeline/processors/inscription_indexing.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ use crate::{
3939
OrdhookConfig,
4040
},
4141
db::{
42-
get_any_entry_in_ordinal_activities, open_ordhook_db_conn_rocks_db_loop,
43-
open_readonly_ordhook_db_conn,
42+
get_any_entry_in_ordinal_activities, get_latest_indexed_inscription_number,
43+
open_ordhook_db_conn_rocks_db_loop, open_readonly_ordhook_db_conn,
4444
},
4545
service::write_brc20_block_operations,
4646
try_error, try_info,
47+
utils::monitoring::PrometheusMonitoring,
4748
};
4849

4950
use crate::db::{TransactionBytesCursor, TraversalResult};
@@ -61,12 +62,14 @@ pub fn start_inscription_indexing_processor(
6162
config: &Config,
6263
ctx: &Context,
6364
post_processor: Option<Sender<BitcoinBlockData>>,
65+
prometheus: &PrometheusMonitoring,
6466
) -> PostProcessorController {
6567
let (commands_tx, commands_rx) = crossbeam_channel::bounded::<PostProcessorCommand>(2);
6668
let (events_tx, events_rx) = crossbeam_channel::unbounded::<PostProcessorEvent>();
6769

6870
let config = config.clone();
6971
let ctx = ctx.clone();
72+
let prometheus = prometheus.clone();
7073
let handle: JoinHandle<()> = hiro_system_kit::thread_named("Inscription indexing runloop")
7174
.spawn(move || {
7275
let cache_l2 = Arc::new(new_traversals_lazy_cache(2048));
@@ -143,6 +146,7 @@ pub fn start_inscription_indexing_processor(
143146
&mut brc20_db_conn_rw,
144147
&ordhook_config,
145148
&post_processor,
149+
&prometheus,
146150
&ctx,
147151
);
148152

@@ -181,6 +185,7 @@ pub fn process_blocks(
181185
brc20_db_conn_rw: &mut Option<Connection>,
182186
ordhook_config: &OrdhookConfig,
183187
post_processor: &Option<Sender<BitcoinBlockData>>,
188+
prometheus: &PrometheusMonitoring,
184189
ctx: &Context,
185190
) -> Vec<BitcoinBlockData> {
186191
let mut cache_l1 = BTreeMap::new();
@@ -216,6 +221,7 @@ pub fn process_blocks(
216221
&inscriptions_db_tx,
217222
brc20_db_tx.as_ref(),
218223
brc20_cache.as_mut(),
224+
prometheus,
219225
ordhook_config,
220226
ctx,
221227
);
@@ -284,6 +290,7 @@ pub fn process_block(
284290
inscriptions_db_tx: &Transaction,
285291
brc20_db_tx: Option<&Transaction>,
286292
brc20_cache: Option<&mut Brc20MemoryCache>,
293+
prometheus: &PrometheusMonitoring,
287294
ordhook_config: &OrdhookConfig,
288295
ctx: &Context,
289296
) -> Result<(), String> {
@@ -307,7 +314,7 @@ pub fn process_block(
307314
Context::empty()
308315
};
309316

310-
// Handle inscriptions
317+
// Inscriptions
311318
if any_processable_transactions {
312319
let _ = augment_block_with_ordinals_inscriptions_data_and_write_to_db_tx(
313320
block,
@@ -317,10 +324,9 @@ pub fn process_block(
317324
&inner_ctx,
318325
);
319326
}
320-
321-
// Handle transfers
327+
// Transfers
322328
let _ = augment_block_with_ordinals_transfer_data(block, inscriptions_db_tx, true, &inner_ctx);
323-
329+
// BRC-20
324330
match (brc20_db_tx, brc20_cache) {
325331
(Some(brc20_db_tx), Some(brc20_cache)) => write_brc20_block_operations(
326332
block,
@@ -332,5 +338,11 @@ pub fn process_block(
332338
_ => {}
333339
}
334340

341+
// Monitoring
342+
prometheus.metrics_block_indexed(block.block_identifier.index);
343+
prometheus.metrics_inscription_indexed(
344+
get_latest_indexed_inscription_number(inscriptions_db_tx, &inner_ctx).unwrap_or(0),
345+
);
346+
335347
Ok(())
336348
}

components/ordhook-core/src/db/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,12 @@ pub fn find_latest_transfers_block_height(db_conn: &Connection, ctx: &Context) -
835835
entry
836836
}
837837

838+
pub fn get_latest_indexed_inscription_number(db_conn: &Connection, ctx: &Context) -> Option<u64> {
839+
let args: &[&dyn ToSql] = &[];
840+
let query = "SELECT MAX(jubilee_inscription_number) FROM inscriptions";
841+
perform_query_one(query, args, db_conn, ctx, |row| row.get(0).unwrap())
842+
}
843+
838844
#[derive(Debug, Clone)]
839845
pub struct TransferData {
840846
pub inscription_offset_intra_output: u64,

components/ordhook-core/src/service/http_api.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ use rocket::{
2222
use rocket::{response::status::Custom, State};
2323

2424
use crate::{
25-
config::PredicatesApi,
26-
service::observers::{
25+
config::PredicatesApi, service::observers::{
2726
insert_entry_in_observers, open_readwrite_observers_db_conn, remove_entry_from_observers,
2827
update_observer_progress, update_observer_streaming_enabled,
29-
},
30-
try_error, try_info,
28+
}, try_error, try_info, utils::monitoring::PrometheusMonitoring
3129
};
3230

3331
use super::observers::{
@@ -39,6 +37,7 @@ pub async fn start_observers_http_server(
3937
observer_commands_tx: &std::sync::mpsc::Sender<ObserverCommand>,
4038
observer_event_rx: crossbeam_channel::Receiver<ObserverEvent>,
4139
bitcoin_scan_op_tx: crossbeam_channel::Sender<BitcoinChainhookSpecification>,
40+
prometheus: &PrometheusMonitoring,
4241
ctx: &Context,
4342
) -> Result<Shutdown, String> {
4443
// Build and start HTTP server.
@@ -51,6 +50,7 @@ pub async fn start_observers_http_server(
5150
// Spawn predicate observer event tread.
5251
let moved_config = config.clone();
5352
let moved_ctx = ctx.clone();
53+
let moved_prometheus = prometheus.clone();
5454
let _ = hiro_system_kit::thread_named("observers_api-events").spawn(move || loop {
5555
let event = match observer_event_rx.recv() {
5656
Ok(cmd) => cmd,
@@ -72,8 +72,10 @@ pub async fn start_observers_http_server(
7272
};
7373
let report = ObserverReport::default();
7474
insert_entry_in_observers(&spec, &report, &observers_db_conn, &moved_ctx);
75+
moved_prometheus.metrics_register_predicate();
7576
match spec {
7677
ChainhookSpecification::Bitcoin(predicate_spec) => {
78+
// TODO: This action blocks this thread until the scan operation is complete. We should not do this.
7779
let _ = bitcoin_scan_op_tx.send(predicate_spec);
7880
}
7981
_ => {}
@@ -109,6 +111,7 @@ pub async fn start_observers_http_server(
109111
}
110112
};
111113
remove_entry_from_observers(&uuid, &observers_db_conn, &moved_ctx);
114+
moved_prometheus.metrics_deregister_predicate();
112115
}
113116
ObserverEvent::BitcoinPredicateTriggered(data) => {
114117
if let Some(ref tip) = data.apply.last() {
@@ -426,7 +429,7 @@ mod test {
426429

427430
use crate::{
428431
config::{Config, PredicatesApi, PredicatesApiConfig},
429-
service::observers::{delete_observers_db, initialize_observers_db},
432+
service::observers::{delete_observers_db, initialize_observers_db}, utils::monitoring::PrometheusMonitoring,
430433
};
431434

432435
use super::start_observers_http_server;
@@ -448,6 +451,7 @@ mod test {
448451
&observer_command_tx,
449452
observer_event_rx,
450453
bitcoin_scan_op_tx,
454+
&PrometheusMonitoring::new(),
451455
&ctx,
452456
)
453457
.await

0 commit comments

Comments
 (0)