@aztec/telemetry-client 0.0.0-test.0 → 0.0.1-commit.03f7ef2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dest/attributes.d.ts +32 -9
  2. package/dest/attributes.d.ts.map +1 -1
  3. package/dest/attributes.js +21 -8
  4. package/dest/bench.d.ts +4 -1
  5. package/dest/bench.d.ts.map +1 -1
  6. package/dest/bench.js +7 -0
  7. package/dest/config.d.ts +7 -2
  8. package/dest/config.d.ts.map +1 -1
  9. package/dest/config.js +29 -1
  10. package/dest/index.d.ts +2 -1
  11. package/dest/index.d.ts.map +1 -1
  12. package/dest/index.js +1 -0
  13. package/dest/l1_metrics.d.ts +17 -0
  14. package/dest/l1_metrics.d.ts.map +1 -0
  15. package/dest/l1_metrics.js +70 -0
  16. package/dest/lmdb_metrics.d.ts +4 -2
  17. package/dest/lmdb_metrics.d.ts.map +1 -1
  18. package/dest/lmdb_metrics.js +8 -0
  19. package/dest/metrics.d.ts +115 -13
  20. package/dest/metrics.d.ts.map +1 -1
  21. package/dest/metrics.js +116 -13
  22. package/dest/nodejs_metrics_monitor.d.ts +21 -0
  23. package/dest/nodejs_metrics_monitor.d.ts.map +1 -0
  24. package/dest/{event_loop_monitor.js → nodejs_metrics_monitor.js} +55 -12
  25. package/dest/noop.d.ts +4 -2
  26. package/dest/noop.d.ts.map +1 -1
  27. package/dest/noop.js +2 -0
  28. package/dest/otel.d.ts +9 -5
  29. package/dest/otel.d.ts.map +1 -1
  30. package/dest/otel.js +93 -19
  31. package/dest/otel_filter_metric_exporter.d.ts +12 -4
  32. package/dest/otel_filter_metric_exporter.d.ts.map +1 -1
  33. package/dest/otel_filter_metric_exporter.js +38 -4
  34. package/dest/otel_logger_provider.d.ts +1 -1
  35. package/dest/otel_propagation.d.ts +1 -1
  36. package/dest/otel_resource.d.ts +1 -1
  37. package/dest/otel_resource.d.ts.map +1 -1
  38. package/dest/otel_resource.js +31 -2
  39. package/dest/prom_otel_adapter.d.ts +58 -9
  40. package/dest/prom_otel_adapter.d.ts.map +1 -1
  41. package/dest/prom_otel_adapter.js +143 -43
  42. package/dest/start.d.ts +2 -2
  43. package/dest/start.d.ts.map +1 -1
  44. package/dest/start.js +7 -6
  45. package/dest/telemetry.d.ts +29 -12
  46. package/dest/telemetry.d.ts.map +1 -1
  47. package/dest/telemetry.js +1 -1
  48. package/dest/vendor/attributes.d.ts +1 -1
  49. package/dest/vendor/otel-pino-stream.d.ts +1 -2
  50. package/dest/vendor/otel-pino-stream.d.ts.map +1 -1
  51. package/dest/vendor/otel-pino-stream.js +2 -2
  52. package/dest/with_tracer.d.ts +1 -1
  53. package/dest/with_tracer.d.ts.map +1 -1
  54. package/dest/wrappers/fetch.d.ts +2 -2
  55. package/dest/wrappers/fetch.d.ts.map +1 -1
  56. package/dest/wrappers/fetch.js +7 -5
  57. package/dest/wrappers/index.d.ts +1 -1
  58. package/dest/wrappers/json_rpc_server.d.ts +2 -2
  59. package/dest/wrappers/json_rpc_server.d.ts.map +1 -1
  60. package/dest/wrappers/l2_block_stream.d.ts +4 -3
  61. package/dest/wrappers/l2_block_stream.d.ts.map +1 -1
  62. package/package.json +21 -15
  63. package/src/attributes.ts +40 -11
  64. package/src/bench.ts +15 -5
  65. package/src/config.ts +54 -2
  66. package/src/index.ts +1 -0
  67. package/src/l1_metrics.ts +80 -0
  68. package/src/lmdb_metrics.ts +24 -3
  69. package/src/metrics.ts +140 -12
  70. package/src/{event_loop_monitor.ts → nodejs_metrics_monitor.ts} +59 -10
  71. package/src/noop.ts +4 -1
  72. package/src/otel.ts +80 -21
  73. package/src/otel_filter_metric_exporter.ts +47 -5
  74. package/src/otel_resource.ts +40 -2
  75. package/src/prom_otel_adapter.ts +191 -59
  76. package/src/start.ts +7 -6
  77. package/src/telemetry.ts +50 -12
  78. package/src/vendor/otel-pino-stream.ts +1 -4
  79. package/src/wrappers/fetch.ts +24 -31
  80. package/src/wrappers/json_rpc_server.ts +1 -1
  81. package/src/wrappers/l2_block_stream.ts +3 -2
  82. package/dest/event_loop_monitor.d.ts +0 -18
  83. package/dest/event_loop_monitor.d.ts.map +0 -1
package/src/metrics.ts CHANGED
@@ -6,9 +6,15 @@
6
6
  * @see {@link https://opentelemetry.io/docs/specs/semconv/general/metrics/ | OpenTelemetry Metrics} for naming conventions.
7
7
  */
8
8
 
9
+ export const BLOB_SINK_STORE_REQUESTS = 'aztec.blob_sink.store_request_count';
10
+ export const BLOB_SINK_RETRIEVE_REQUESTS = 'aztec.blob_sink.retrieve_request_count';
9
11
  export const BLOB_SINK_OBJECTS_IN_BLOB_STORE = 'aztec.blob_sink.objects_in_blob_store';
10
12
  export const BLOB_SINK_BLOB_SIZE = 'aztec.blob_sink.blob_size';
11
13
 
14
+ export const BLOB_SINK_ARCHIVE_BLOB_REQUEST_COUNT = 'aztec.blob_sink.archive.block_request_count';
15
+ export const BLOB_SINK_ARCHIVE_BLOCK_REQUEST_COUNT = 'aztec.blob_sink.archive.blob_request_count';
16
+ export const BLOB_SINK_ARCHIVE_BLOB_COUNT = 'aztec.blob_sink.archive.blob_count';
17
+
12
18
  /** How long it takes to simulate a circuit */
13
19
  export const CIRCUIT_SIMULATION_DURATION = 'aztec.circuit.simulation.duration';
14
20
  export const CIRCUIT_SIMULATION_INPUT_SIZE = 'aztec.circuit.simulation.input_size';
@@ -28,34 +34,80 @@ export const CIRCUIT_SIZE = 'aztec.circuit.size';
28
34
 
29
35
  export const MEMPOOL_TX_COUNT = 'aztec.mempool.tx_count';
30
36
  export const MEMPOOL_TX_SIZE = 'aztec.mempool.tx_size';
37
+ export const MEMPOOL_TX_ADDED_COUNT = 'aztec.mempool.tx_added_count';
38
+ export const MEMPOOL_TX_MINED_DELAY = 'aztec.mempool.tx_mined_delay';
39
+
31
40
  export const DB_NUM_ITEMS = 'aztec.db.num_items';
32
41
  export const DB_MAP_SIZE = 'aztec.db.map_size';
42
+ export const DB_PHYSICAL_FILE_SIZE = 'aztec.db.physical_file_size';
33
43
  export const DB_USED_SIZE = 'aztec.db.used_size';
34
44
 
35
45
  export const MEMPOOL_ATTESTATIONS_COUNT = 'aztec.mempool.attestations_count';
36
46
  export const MEMPOOL_ATTESTATIONS_SIZE = 'aztec.mempool.attestations_size';
47
+ export const MEMPOOL_ATTESTATIONS_ADDED_COUNT = 'aztec.mempool.attestations_added_count';
48
+ export const MEMPOOL_ATTESTATIONS_MINED_DELAY = 'aztec.mempool.attestations_mined_delay';
37
49
 
38
- export const ARCHIVER_SYNC_DURATION = 'aztec.archiver.sync_duration';
39
- export const ARCHIVER_L1_BLOCKS_SYNCED = 'aztec.archiver.l1_blocks_synced';
40
50
  export const ARCHIVER_L1_BLOCK_HEIGHT = 'aztec.archiver.l1_block_height';
41
51
  export const ARCHIVER_BLOCK_HEIGHT = 'aztec.archiver.block_height';
42
- export const ARCHIVER_TX_COUNT = 'aztec.archiver.tx_count';
43
52
  export const ARCHIVER_ROLLUP_PROOF_DELAY = 'aztec.archiver.rollup_proof_delay';
44
53
  export const ARCHIVER_ROLLUP_PROOF_COUNT = 'aztec.archiver.rollup_proof_count';
54
+
55
+ export const ARCHIVER_MANA_PER_BLOCK = 'aztec.archiver.block.mana_count';
56
+ export const ARCHIVER_TXS_PER_BLOCK = 'aztec.archiver.block.tx_count';
57
+ export const ARCHIVER_SYNC_PER_BLOCK = 'aztec.archiver.block.sync_per_item_duration';
58
+ export const ARCHIVER_SYNC_BLOCK_COUNT = 'aztec.archiver.block.sync_count';
59
+
60
+ export const ARCHIVER_SYNC_PER_MESSAGE = 'aztec.archiver.message.sync_per_item_duration';
61
+ export const ARCHIVER_SYNC_MESSAGE_COUNT = 'aztec.archiver.message.sync_count';
62
+
63
+ export const ARCHIVER_PRUNE_DURATION = 'aztec.archiver.prune_duration';
45
64
  export const ARCHIVER_PRUNE_COUNT = 'aztec.archiver.prune_count';
46
65
 
66
+ export const ARCHIVER_TOTAL_TXS = 'aztec.archiver.tx_count';
67
+
68
+ export const ARCHIVER_BLOCK_PROPOSAL_TX_TARGET_COUNT = 'aztec.archiver.block_proposal_tx_target_count';
69
+
47
70
  export const NODE_RECEIVE_TX_DURATION = 'aztec.node.receive_tx.duration';
48
71
  export const NODE_RECEIVE_TX_COUNT = 'aztec.node.receive_tx.count';
49
72
 
73
+ export const NODE_SNAPSHOT_DURATION = 'aztec.node.snapshot_duration';
74
+ export const NODE_SNAPSHOT_ERROR_COUNT = 'aztec.node.snapshot_error_count';
75
+
50
76
  export const SEQUENCER_STATE_TRANSITION_BUFFER_DURATION = 'aztec.sequencer.state_transition_buffer.duration';
51
77
  export const SEQUENCER_BLOCK_BUILD_DURATION = 'aztec.sequencer.block.build_duration';
52
78
  export const SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND = 'aztec.sequencer.block.build_mana_per_second';
53
79
  export const SEQUENCER_BLOCK_COUNT = 'aztec.sequencer.block.count';
54
- export const SEQUENCER_CURRENT_STATE = 'aztec.sequencer.current.state';
55
- export const SEQUENCER_CURRENT_BLOCK_NUMBER = 'aztec.sequencer.current.block_number';
56
- export const SEQUENCER_CURRENT_BLOCK_SIZE = 'aztec.sequencer.current.block_size';
57
- export const SEQUENCER_TIME_TO_COLLECT_ATTESTATIONS = 'aztec.sequencer.time_to_collect_attestations';
58
- export const SEQUENCER_BLOCK_BUILD_INSERTION_TIME = 'aztec.sequencer.block_builder_tree_insertion_duration';
80
+ export const SEQUENCER_CURRENT_BLOCK_REWARDS = 'aztec.sequencer.current_block_rewards';
81
+ export const SEQUENCER_SLOT_COUNT = 'aztec.sequencer.slot.total_count';
82
+ export const SEQUENCER_FILLED_SLOT_COUNT = 'aztec.sequencer.slot.filled_count';
83
+
84
+ export const SEQUENCER_BLOCK_ATTESTATION_DELAY = 'aztec.sequencer.block.attestation_delay';
85
+
86
+ export const SEQUENCER_COLLECTED_ATTESTATIONS_COUNT = 'aztec.sequencer.attestations.collected_count';
87
+ export const SEQUENCER_REQUIRED_ATTESTATIONS_COUNT = 'aztec.sequencer.attestations.required_count';
88
+ export const SEQUENCER_COLLECT_ATTESTATIONS_DURATION = 'aztec.sequencer.attestations.collect_duration';
89
+ export const SEQUENCER_COLLECT_ATTESTATIONS_TIME_ALLOWANCE = 'aztec.sequencer.attestations.collect_allowance';
90
+
91
+ export const SEQUENCER_BLOCK_PROPOSAL_FAILED_COUNT = 'aztec.sequencer.block.proposal_failed_count';
92
+ export const SEQUENCER_BLOCK_PROPOSAL_SUCCESS_COUNT = 'aztec.sequencer.block.proposal_success_count';
93
+ export const SEQUENCER_BLOCK_PROPOSAL_PRECHECK_FAILED_COUNT = 'aztec.sequencer.block.proposal_precheck_failed_count';
94
+ export const SEQUENCER_SLASHING_ATTEMPTS_COUNT = 'aztec.sequencer.slashing.attempts_count';
95
+ export const SEQUENCER_CHECKPOINT_SUCCESS_COUNT = 'aztec.sequencer.checkpoint.success_count';
96
+
97
+ // Fisherman fee analysis metrics
98
+ export const FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED = 'aztec.fisherman.fee_analysis.would_be_included';
99
+ export const FISHERMAN_FEE_ANALYSIS_TIME_BEFORE_BLOCK = 'aztec.fisherman.fee_analysis.time_before_block';
100
+ export const FISHERMAN_FEE_ANALYSIS_PENDING_BLOB_TX_COUNT = 'aztec.fisherman.fee_analysis.pending_blob_tx_count';
101
+ export const FISHERMAN_FEE_ANALYSIS_INCLUDED_BLOB_TX_COUNT = 'aztec.fisherman.fee_analysis.included_blob_tx_count';
102
+ export const FISHERMAN_FEE_ANALYSIS_CALCULATED_PRIORITY_FEE = 'aztec.fisherman.fee_analysis.calculated_priority_fee';
103
+ export const FISHERMAN_FEE_ANALYSIS_PRIORITY_FEE_DELTA = 'aztec.fisherman.fee_analysis.priority_fee_delta';
104
+ export const FISHERMAN_FEE_ANALYSIS_ESTIMATED_COST = 'aztec.fisherman.fee_analysis.estimated_cost';
105
+ export const FISHERMAN_FEE_ANALYSIS_ESTIMATED_OVERPAYMENT = 'aztec.fisherman.fee_analysis.estimated_overpayment';
106
+ export const FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_PRIORITY_FEE =
107
+ 'aztec.fisherman.fee_analysis.mined_blob_tx_priority_fee';
108
+ export const FISHERMAN_FEE_ANALYSIS_MINED_BLOB_TX_TOTAL_COST = 'aztec.fisherman.fee_analysis.mined_blob_tx_total_cost';
109
+
110
+ export const VALIDATOR_INVALID_ATTESTATION_RECEIVED_COUNT = 'aztec.validator.invalid_attestation_received_count';
59
111
 
60
112
  export const L1_PUBLISHER_GAS_PRICE = 'aztec.l1_publisher.gas_price';
61
113
  export const L1_PUBLISHER_TX_COUNT = 'aztec.l1_publisher.tx_count';
@@ -70,15 +122,51 @@ export const L1_PUBLISHER_BLOB_INCLUSION_BLOCKS = 'aztec.l1_publisher.blob_inclu
70
122
  export const L1_PUBLISHER_BLOB_TX_SUCCESS = 'aztec.l1_publisher.blob_tx_success';
71
123
  export const L1_PUBLISHER_BLOB_TX_FAILURE = 'aztec.l1_publisher.blob_tx_failure';
72
124
  export const L1_PUBLISHER_BALANCE = 'aztec.l1_publisher.balance';
125
+ export const L1_PUBLISHER_TX_TOTAL_FEE = 'aztec.l1_publisher.tx_total_fee';
126
+
127
+ export const L1_BLOCK_HEIGHT = 'aztec.l1.block_height';
128
+ export const L1_BALANCE_ETH = 'aztec.l1.balance';
129
+ export const L1_GAS_PRICE_WEI = 'aztec.l1.gas_price';
130
+ export const L1_BLOB_BASE_FEE_WEI = 'aztec.l1.blob_base_fee';
131
+
132
+ export const L1_TX_MINED_DURATION = 'aztec.l1_tx.mined_duration';
133
+ export const L1_TX_MINED_COUNT = 'aztec.l1_tx.mined_count';
134
+ export const L1_TX_REVERTED_COUNT = 'aztec.l1_tx.reverted_count';
135
+ export const L1_TX_CANCELLED_COUNT = 'aztec.l1_tx.cancelled_count';
136
+ export const L1_TX_NOT_MINED_COUNT = 'aztec.l1_tx.not_mined_count';
137
+ export const L1_TX_ATTEMPTS_UNTIL_MINED = 'aztec.l1_tx.attempts_until_mined';
138
+ export const L1_TX_MAX_PRIORITY_FEE = 'aztec.l1_tx.max_priority_fee';
139
+ export const L1_TX_MAX_FEE = 'aztec.l1_tx.max_fee';
140
+ export const L1_TX_BLOB_FEE = 'aztec.l1_tx.blob_fee';
73
141
 
74
142
  export const PEER_MANAGER_GOODBYES_SENT = 'aztec.peer_manager.goodbyes_sent';
75
143
  export const PEER_MANAGER_GOODBYES_RECEIVED = 'aztec.peer_manager.goodbyes_received';
144
+ export const PEER_MANAGER_PEER_COUNT = 'aztec.peer_manager.peer_count';
145
+ export const PEER_MANAGER_LOW_SCORE_DISCONNECTS = 'aztec.peer_manager.low_score_disconnects';
146
+ export const P2P_PEER_STATE_COUNT = 'aztec.p2p.peer_state_count';
76
147
 
77
148
  export const P2P_REQ_RESP_SENT_REQUESTS = 'aztec.p2p.req_resp.sent_requests';
78
149
  export const P2P_REQ_RESP_RECEIVED_REQUESTS = 'aztec.p2p.req_resp.received_requests';
79
150
  export const P2P_REQ_RESP_FAILED_OUTBOUND_REQUESTS = 'aztec.p2p.req_resp.failed_outbound_requests';
80
151
  export const P2P_REQ_RESP_FAILED_INBOUND_REQUESTS = 'aztec.p2p.req_resp.failed_inbound_requests';
81
152
 
153
+ export const P2P_GOSSIP_MESSAGE_VALIDATION_DURATION = 'aztec.p2p.gossip.message_validation_duration';
154
+ export const P2P_GOSSIP_MESSAGE_PREVALIDATION_COUNT = 'aztec.p2p.gossip.message_validation_count';
155
+ export const P2P_GOSSIP_MESSAGE_LATENCY = 'aztec.p2p.gossip.message_latency';
156
+ export const P2P_GOSSIP_TX_RECEIVED_COUNT = 'aztec.p2p.gossip.tx_received_count';
157
+
158
+ export const P2P_GOSSIP_AGG_MESSAGE_LATENCY_MIN = 'aztec.p2p.gossip.agg_message_latency_min';
159
+ export const P2P_GOSSIP_AGG_MESSAGE_LATENCY_MAX = 'aztec.p2p.gossip.agg_message_latency_max';
160
+ export const P2P_GOSSIP_AGG_MESSAGE_LATENCY_P50 = 'aztec.p2p.gossip.agg_message_latency_p50';
161
+ export const P2P_GOSSIP_AGG_MESSAGE_LATENCY_P90 = 'aztec.p2p.gossip.agg_message_latency_p90';
162
+ export const P2P_GOSSIP_AGG_MESSAGE_LATENCY_AVG = 'aztec.p2p.gossip.agg_message_latency_avg';
163
+
164
+ export const P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_MIN = 'aztec.p2p.gossip.agg_message_validation_duration_min';
165
+ export const P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_MAX = 'aztec.p2p.gossip.agg_message_validation_duration_max';
166
+ export const P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_P50 = 'aztec.p2p.gossip.agg_message_validation_duration_p50';
167
+ export const P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_P90 = 'aztec.p2p.gossip.agg_message_validation_duration_p90';
168
+ export const P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_AVG = 'aztec.p2p.gossip.agg_message_validation_duration_avg';
169
+
82
170
  export const PUBLIC_PROCESSOR_TX_DURATION = 'aztec.public_processor.tx_duration';
83
171
  export const PUBLIC_PROCESSOR_TX_COUNT = 'aztec.public_processor.tx_count';
84
172
  export const PUBLIC_PROCESSOR_TX_PHASE_COUNT = 'aztec.public_processor.tx_phase_count';
@@ -91,11 +179,15 @@ export const PUBLIC_PROCESSOR_TOTAL_GAS_HISTOGRAM = 'aztec.public_processor.tota
91
179
  export const PUBLIC_PROCESSOR_GAS_RATE = 'aztec.public_processor.gas_rate';
92
180
  export const PUBLIC_PROCESSOR_TREE_INSERTION = 'aztec.public_processor.tree_insertion';
93
181
 
182
+ export const PUBLIC_EXECUTOR_PREFIX = 'aztec.public_executor.';
94
183
  export const PUBLIC_EXECUTOR_SIMULATION_COUNT = 'aztec.public_executor.simulation_count';
95
184
  export const PUBLIC_EXECUTOR_SIMULATION_DURATION = 'aztec.public_executor.simulation_duration';
96
185
  export const PUBLIC_EXECUTOR_SIMULATION_MANA_PER_SECOND = 'aztec.public_executor.simulation_mana_per_second';
97
- export const PUBLIC_EXECUTION_SIMULATION_BYTECODE_SIZE = 'aztec.public_executor.simulation_bytecode_size';
98
- export const PUBLIC_EXECUTION_PRIVATE_EFFECTS_INSERTION = 'aztec.public_executor.private_effects_insertion';
186
+ export const PUBLIC_EXECUTOR_SIMULATION_MANA_USED = 'aztec.public_executor.simulation_mana_used';
187
+ export const PUBLIC_EXECUTOR_SIMULATION_TOTAL_INSTRUCTIONS = 'aztec.public_executor.simulation_total_instructions';
188
+ export const PUBLIC_EXECUTOR_TX_HASHING = 'aztec.public_executor.tx_hashing';
189
+ export const PUBLIC_EXECUTOR_PRIVATE_EFFECTS_INSERTION = 'aztec.public_executor.private_effects_insertion';
190
+ export const PUBLIC_EXECUTOR_SIMULATION_BYTECODE_SIZE = 'aztec.public_executor.simulation_bytecode_size';
99
191
 
100
192
  export const PROVING_ORCHESTRATOR_BASE_ROLLUP_INPUTS_DURATION =
101
193
  'aztec.proving_orchestrator.base_rollup.inputs_duration';
@@ -119,17 +211,21 @@ export const PROVING_AGENT_IDLE = 'aztec.proving_queue.agent.idle';
119
211
 
120
212
  export const PROVER_NODE_EXECUTION_DURATION = 'aztec.prover_node.execution.duration';
121
213
  export const PROVER_NODE_JOB_DURATION = 'aztec.prover_node.job_duration';
214
+ export const PROVER_NODE_JOB_CHECKPOINTS = 'aztec.prover_node.job_checkpoints';
122
215
  export const PROVER_NODE_JOB_BLOCKS = 'aztec.prover_node.job_blocks';
123
216
  export const PROVER_NODE_JOB_TRANSACTIONS = 'aztec.prover_node.job_transactions';
217
+ export const PROVER_NODE_REWARDS_TOTAL = 'aztec.prover_node.rewards_total';
218
+ export const PROVER_NODE_REWARDS_PER_EPOCH = 'aztec.prover_node.rewards_per_epoch';
124
219
 
125
220
  export const WORLD_STATE_FORK_DURATION = 'aztec.world_state.fork.duration';
126
221
  export const WORLD_STATE_SYNC_DURATION = 'aztec.world_state.sync.duration';
127
222
  export const WORLD_STATE_MERKLE_TREE_SIZE = 'aztec.world_state.merkle_tree_size';
128
223
  export const WORLD_STATE_DB_SIZE = 'aztec.world_state.db_size';
129
224
  export const WORLD_STATE_DB_MAP_SIZE = 'aztec.world_state.db_map_size';
225
+ export const WORLD_STATE_DB_PHYSICAL_SIZE = 'aztec.world_state.db_physical_size';
130
226
  export const WORLD_STATE_TREE_SIZE = 'aztec.world_state.tree_size';
131
- export const WORLD_STATE_UNFINALISED_HEIGHT = 'aztec.world_state.unfinalised_height';
132
- export const WORLD_STATE_FINALISED_HEIGHT = 'aztec.world_state.finalised_height';
227
+ export const WORLD_STATE_UNFINALIZED_HEIGHT = 'aztec.world_state.unfinalized_height';
228
+ export const WORLD_STATE_FINALIZED_HEIGHT = 'aztec.world_state.finalized_height';
133
229
  export const WORLD_STATE_OLDEST_BLOCK = 'aztec.world_state.oldest_block';
134
230
  export const WORLD_STATE_DB_USED_SIZE = 'aztec.world_state.db_used_size';
135
231
  export const WORLD_STATE_DB_NUM_ITEMS = 'aztec.world_state.db_num_items';
@@ -139,7 +235,13 @@ export const WORLD_STATE_CRITICAL_ERROR_COUNT = 'aztec.world_state.critical_erro
139
235
  export const PROOF_VERIFIER_COUNT = 'aztec.proof_verifier.count';
140
236
 
141
237
  export const VALIDATOR_RE_EXECUTION_TIME = 'aztec.validator.re_execution_time';
238
+ export const VALIDATOR_RE_EXECUTION_MANA = 'aztec.validator.re_execution_mana';
239
+ export const VALIDATOR_RE_EXECUTION_TX_COUNT = 'aztec.validator.re_execution_tx_count';
240
+
142
241
  export const VALIDATOR_FAILED_REEXECUTION_COUNT = 'aztec.validator.failed_reexecution_count';
242
+ export const VALIDATOR_ATTESTATION_SUCCESS_COUNT = 'aztec.validator.attestation_success_count';
243
+ export const VALIDATOR_ATTESTATION_FAILED_BAD_PROPOSAL_COUNT = 'aztec.validator.attestation_failed_bad_proposal_count';
244
+ export const VALIDATOR_ATTESTATION_FAILED_NODE_ISSUE_COUNT = 'aztec.validator.attestation_failed_node_issue_count';
143
245
 
144
246
  export const NODEJS_EVENT_LOOP_DELAY_MIN = 'nodejs.eventloop.delay.min';
145
247
  export const NODEJS_EVENT_LOOP_DELAY_MEAN = 'nodejs.eventloop.delay.mean';
@@ -151,3 +253,29 @@ export const NODEJS_EVENT_LOOP_DELAY_P99 = 'nodejs.eventloop.delay.p99';
151
253
 
152
254
  export const NODEJS_EVENT_LOOP_UTILIZATION = 'nodejs.eventloop.utilization';
153
255
  export const NODEJS_EVENT_LOOP_TIME = 'nodejs.eventloop.time';
256
+
257
+ export const NODEJS_MEMORY_HEAP_USAGE = 'nodejs.memory.v8_heap.usage';
258
+ export const NODEJS_MEMORY_HEAP_TOTAL = 'nodejs.memory.v8_heap.total';
259
+ export const NODEJS_MEMORY_NATIVE_USAGE = 'nodejs.memory.native.usage';
260
+ export const NODEJS_MEMORY_BUFFER_USAGE = 'nodejs.memory.array_buffer.usage';
261
+
262
+ export const TX_PROVIDER_TXS_FROM_PROPOSALS_COUNT = 'aztec.tx_collector.txs_from_proposal_count';
263
+ export const TX_PROVIDER_TXS_FROM_MEMPOOL_COUNT = 'aztec.tx_collector.txs_from_mempool_count';
264
+ export const TX_PROVIDER_TXS_FROM_P2P_COUNT = 'aztec.tx_collector.txs_from_p2p_count';
265
+ export const TX_PROVIDER_MISSING_TXS_COUNT = 'aztec.tx_collector.missing_txs_count';
266
+ export const TX_PROVIDER_P2P_TXS_REQUESTED_FRACTION = 'aztec.tx_collector.txs_requested_fraction';
267
+ export const TX_PROVIDER_P2P_TXS_REQUEST_DELAY = 'aztec.tx_collector.txs_requested_delay';
268
+
269
+ export const TX_COLLECTOR_COUNT = 'aztec.tx_collector.tx_count';
270
+ export const TX_COLLECTOR_DURATION_PER_REQUEST = 'aztec.tx_collector.duration_per_request';
271
+ export const TX_COLLECTOR_DURATION_PER_TX = 'aztec.tx_collector.duration_per_tx';
272
+
273
+ export const IVC_VERIFIER_TIME = 'aztec.ivc_verifier.time';
274
+ export const IVC_VERIFIER_TOTAL_TIME = 'aztec.ivc_verifier.total_time';
275
+ export const IVC_VERIFIER_FAILURE_COUNT = 'aztec.ivc_verifier.failure_count';
276
+
277
+ export const IVC_VERIFIER_AGG_DURATION_MIN = 'aztec.ivc_verifier.agg_duration_min';
278
+ export const IVC_VERIFIER_AGG_DURATION_MAX = 'aztec.ivc_verifier.agg_duration_max';
279
+ export const IVC_VERIFIER_AGG_DURATION_P50 = 'aztec.ivc_verifier.agg_duration_p50';
280
+ export const IVC_VERIFIER_AGG_DURATION_P90 = 'aztec.ivc_verifier.agg_duration_p90';
281
+ export const IVC_VERIFIER_AGG_DURATION_AVG = 'aztec.ivc_verifier.agg_duration_avg';
@@ -1,3 +1,4 @@
1
+ import type { Observable } from '@opentelemetry/api';
1
2
  import { type EventLoopUtilization, type IntervalHistogram, monitorEventLoopDelay, performance } from 'node:perf_hooks';
2
3
 
3
4
  import * as Attributes from './attributes.js';
@@ -13,7 +14,7 @@ import {
13
14
  /**
14
15
  * Detector for custom Aztec attributes
15
16
  */
16
- export class EventLoopMonitor {
17
+ export class NodejsMetricsMonitor {
17
18
  private eventLoopDelayGauges: {
18
19
  min: ObservableGauge;
19
20
  max: ObservableGauge;
@@ -24,6 +25,10 @@ export class EventLoopMonitor {
24
25
  p99: ObservableGauge;
25
26
  };
26
27
 
28
+ // skip `rss` because that's already tracked by @opentelemetry/host-metrics
29
+ // description of each field here https://nodejs.org/api/process.html#processmemoryusage
30
+ private memoryGauges: Record<Exclude<keyof NodeJS.MemoryUsage, 'rss'>, ObservableGauge>;
31
+
27
32
  private eventLoopUilization: ObservableGauge;
28
33
  private eventLoopTime: UpDownCounter;
29
34
 
@@ -62,6 +67,25 @@ export class EventLoopMonitor {
62
67
  });
63
68
 
64
69
  this.eventLoopDelay = monitorEventLoopDelay();
70
+
71
+ this.memoryGauges = {
72
+ heapUsed: meter.createObservableGauge(Metrics.NODEJS_MEMORY_HEAP_USAGE, {
73
+ unit: 'By',
74
+ description: 'Memory used by the V8 heap',
75
+ }),
76
+ heapTotal: meter.createObservableGauge(Metrics.NODEJS_MEMORY_HEAP_TOTAL, {
77
+ unit: 'By',
78
+ description: 'The max size the V8 heap can grow to',
79
+ }),
80
+ arrayBuffers: meter.createObservableGauge(Metrics.NODEJS_MEMORY_BUFFER_USAGE, {
81
+ unit: 'By',
82
+ description: 'Memory allocated for buffers (includes native memory used)',
83
+ }),
84
+ external: meter.createObservableGauge(Metrics.NODEJS_MEMORY_NATIVE_USAGE, {
85
+ unit: 'By',
86
+ description: 'Memory allocated for native C++ objects',
87
+ }),
88
+ };
65
89
  }
66
90
 
67
91
  start(): void {
@@ -74,6 +98,7 @@ export class EventLoopMonitor {
74
98
  this.meter.addBatchObservableCallback(this.measure, [
75
99
  this.eventLoopUilization,
76
100
  ...Object.values(this.eventLoopDelayGauges),
101
+ ...Object.values(this.memoryGauges),
77
102
  ]);
78
103
  }
79
104
 
@@ -84,6 +109,7 @@ export class EventLoopMonitor {
84
109
  this.meter.removeBatchObservableCallback(this.measure, [
85
110
  this.eventLoopUilization,
86
111
  ...Object.values(this.eventLoopDelayGauges),
112
+ ...Object.values(this.memoryGauges),
87
113
  ]);
88
114
  this.eventLoopDelay.disable();
89
115
  this.eventLoopDelay.reset();
@@ -91,6 +117,20 @@ export class EventLoopMonitor {
91
117
  }
92
118
 
93
119
  private measure = (obs: BatchObservableResult): void => {
120
+ this.measureMemoryUsage(obs);
121
+ this.measureEventLoopDelay(obs);
122
+ };
123
+
124
+ private measureMemoryUsage = (observer: BatchObservableResult) => {
125
+ const mem = process.memoryUsage();
126
+
127
+ observer.observe(this.memoryGauges.heapUsed, mem.heapUsed);
128
+ observer.observe(this.memoryGauges.heapTotal, mem.heapTotal);
129
+ observer.observe(this.memoryGauges.arrayBuffers, mem.arrayBuffers);
130
+ observer.observe(this.memoryGauges.external, mem.external);
131
+ };
132
+
133
+ private measureEventLoopDelay = (obs: BatchObservableResult): void => {
94
134
  const newELU = performance.eventLoopUtilization();
95
135
  const delta = performance.eventLoopUtilization(newELU, this.lastELU);
96
136
  this.lastELU = newELU;
@@ -103,17 +143,26 @@ export class EventLoopMonitor {
103
143
  // - https://youtu.be/WetXnEPraYM
104
144
  obs.observe(this.eventLoopUilization, delta.utilization);
105
145
 
106
- this.eventLoopTime.add(Math.floor(delta.idle), { [Attributes.NODEJS_EVENT_LOOP_STATE]: 'idle' });
107
- this.eventLoopTime.add(Math.floor(delta.active), { [Attributes.NODEJS_EVENT_LOOP_STATE]: 'active' });
146
+ this.eventLoopTime.add(Math.trunc(delta.idle), { [Attributes.NODEJS_EVENT_LOOP_STATE]: 'idle' });
147
+ this.eventLoopTime.add(Math.trunc(delta.active), { [Attributes.NODEJS_EVENT_LOOP_STATE]: 'active' });
108
148
 
109
- obs.observe(this.eventLoopDelayGauges.min, Math.floor(this.eventLoopDelay.min));
110
- obs.observe(this.eventLoopDelayGauges.mean, Math.floor(this.eventLoopDelay.mean));
111
- obs.observe(this.eventLoopDelayGauges.max, Math.floor(this.eventLoopDelay.max));
112
- obs.observe(this.eventLoopDelayGauges.stddev, Math.floor(this.eventLoopDelay.stddev));
113
- obs.observe(this.eventLoopDelayGauges.p50, Math.floor(this.eventLoopDelay.percentile(50)));
114
- obs.observe(this.eventLoopDelayGauges.p90, Math.floor(this.eventLoopDelay.percentile(90)));
115
- obs.observe(this.eventLoopDelayGauges.p99, Math.floor(this.eventLoopDelay.percentile(99)));
149
+ safeObserveInt(obs, this.eventLoopDelayGauges.min, this.eventLoopDelay.min);
150
+ safeObserveInt(obs, this.eventLoopDelayGauges.mean, this.eventLoopDelay.mean);
151
+ safeObserveInt(obs, this.eventLoopDelayGauges.max, this.eventLoopDelay.max);
152
+ safeObserveInt(obs, this.eventLoopDelayGauges.stddev, this.eventLoopDelay.stddev);
153
+ safeObserveInt(obs, this.eventLoopDelayGauges.p50, this.eventLoopDelay.percentile(50));
154
+ safeObserveInt(obs, this.eventLoopDelayGauges.p90, this.eventLoopDelay.percentile(90));
155
+ safeObserveInt(obs, this.eventLoopDelayGauges.p99, this.eventLoopDelay.percentile(99));
116
156
 
117
157
  this.eventLoopDelay.reset();
118
158
  };
119
159
  }
160
+
161
+ function safeObserveInt(observer: BatchObservableResult, metric: Observable, value: number, attrs?: object) {
162
+ // discard NaN, Infinity, -Infinity
163
+ if (!Number.isFinite(value)) {
164
+ return;
165
+ }
166
+
167
+ observer.observe(metric, Math.trunc(value), attrs);
168
+ }
package/src/noop.ts CHANGED
@@ -3,6 +3,9 @@ import { type Meter, type Span, type SpanContext, type Tracer, createNoopMeter }
3
3
  import type { TelemetryClient } from './telemetry.js';
4
4
 
5
5
  export class NoopTelemetryClient implements TelemetryClient {
6
+ setExportedPublicTelemetry(_prefixes: string[]): void {}
7
+ setPublicTelemetryCollectFrom(_roles: string[]): void {}
8
+
6
9
  getMeter(): Meter {
7
10
  return createNoopMeter();
8
11
  }
@@ -32,7 +35,7 @@ export class NoopTracer implements Tracer {
32
35
  return new NoopSpan();
33
36
  }
34
37
 
35
- startActiveSpan<F extends (...args: any[]) => any>(_name: string, ...args: (unknown | F)[]): ReturnType<F> {
38
+ startActiveSpan<F extends (...args: any[]) => any>(_name: string, ...args: unknown[]): ReturnType<F> {
36
39
  // there are three different signatures for startActiveSpan, grab the function, we don't care about the rest
37
40
  const fn = args.find(arg => typeof arg === 'function') as F;
38
41
  return fn(new NoopSpan());
package/src/otel.ts CHANGED
@@ -28,8 +28,8 @@ import { BatchSpanProcessor, NodeTracerProvider } from '@opentelemetry/sdk-trace
28
28
  import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
29
29
 
30
30
  import type { TelemetryClientConfig } from './config.js';
31
- import { EventLoopMonitor } from './event_loop_monitor.js';
32
- import { OtelFilterMetricExporter } from './otel_filter_metric_exporter.js';
31
+ import { NodejsMetricsMonitor } from './nodejs_metrics_monitor.js';
32
+ import { OtelFilterMetricExporter, PublicOtelFilterMetricExporter } from './otel_filter_metric_exporter.js';
33
33
  import { registerOtelLoggerProvider } from './otel_logger_provider.js';
34
34
  import { getOtelResource } from './otel_resource.js';
35
35
  import type { TelemetryClient } from './telemetry.js';
@@ -38,7 +38,7 @@ export type OpenTelemetryClientFactory = (resource: IResource, log: Logger) => O
38
38
 
39
39
  export class OpenTelemetryClient implements TelemetryClient {
40
40
  hostMetrics: HostMetrics | undefined;
41
- eventLoopMonitor: EventLoopMonitor | undefined;
41
+ nodejsMetricsMonitor: NodejsMetricsMonitor | undefined;
42
42
  private meters: Map<string, Meter> = new Map<string, Meter>();
43
43
  private tracers: Map<string, Tracer> = new Map<string, Tracer>();
44
44
 
@@ -47,9 +47,18 @@ export class OpenTelemetryClient implements TelemetryClient {
47
47
  private meterProvider: MeterProvider,
48
48
  private traceProvider: TracerProvider,
49
49
  private loggerProvider: LoggerProvider | undefined,
50
+ private publicMetricExporter: PublicOtelFilterMetricExporter | undefined,
50
51
  private log: Logger,
51
52
  ) {}
52
53
 
54
+ setExportedPublicTelemetry(metrics: string[]): void {
55
+ this.publicMetricExporter?.setMetricPrefixes(metrics);
56
+ }
57
+
58
+ setPublicTelemetryCollectFrom(roles: string[]): void {
59
+ this.publicMetricExporter?.setAllowedRoles(roles);
60
+ }
61
+
53
62
  getMeter(name: string): Meter {
54
63
  let meter = this.meters.get(name);
55
64
  if (!meter) {
@@ -91,12 +100,12 @@ export class OpenTelemetryClient implements TelemetryClient {
91
100
  meterProvider: this.meterProvider,
92
101
  });
93
102
 
94
- this.eventLoopMonitor = new EventLoopMonitor(
103
+ this.nodejsMetricsMonitor = new NodejsMetricsMonitor(
95
104
  this.meterProvider.getMeter(this.resource.attributes[ATTR_SERVICE_NAME] as string),
96
105
  );
97
106
 
98
107
  this.hostMetrics.start();
99
- this.eventLoopMonitor.start();
108
+ this.nodejsMetricsMonitor.start();
100
109
  }
101
110
 
102
111
  public isEnabled() {
@@ -112,7 +121,7 @@ export class OpenTelemetryClient implements TelemetryClient {
112
121
  }
113
122
 
114
123
  public async stop() {
115
- this.eventLoopMonitor?.stop();
124
+ this.nodejsMetricsMonitor?.stop();
116
125
 
117
126
  const flushAndShutdown = async (provider?: { forceFlush: () => Promise<void>; shutdown: () => Promise<void> }) => {
118
127
  if (!provider) {
@@ -131,16 +140,31 @@ export class OpenTelemetryClient implements TelemetryClient {
131
140
 
132
141
  public static createMeterProvider(
133
142
  resource: IResource,
134
- options: Partial<PeriodicExportingMetricReaderOptions>,
143
+ exporters: Array<PeriodicExportingMetricReaderOptions>,
135
144
  ): MeterProvider {
136
145
  return new MeterProvider({
137
146
  resource,
138
- readers: options.exporter
139
- ? [new PeriodicExportingMetricReader(options as PeriodicExportingMetricReaderOptions)]
140
- : [],
147
+ readers: exporters.map(options => new PeriodicExportingMetricReader(options)),
141
148
 
142
149
  views: [
143
150
  // Every histogram matching the selector (type + unit) gets these custom buckets assigned
151
+ new View({
152
+ instrumentType: InstrumentType.HISTOGRAM,
153
+ instrumentUnit: 'Mmana',
154
+ aggregation: new ExplicitBucketHistogramAggregation(
155
+ [0.1, 0.5, 1, 2, 4, 8, 10, 25, 50, 100, 500, 1000, 5000, 10000],
156
+ true,
157
+ ),
158
+ }),
159
+ new View({
160
+ instrumentType: InstrumentType.HISTOGRAM,
161
+ instrumentUnit: 'tx',
162
+ aggregation: new ExplicitBucketHistogramAggregation(
163
+ // TPS
164
+ [0.1 * 36, 0.2 * 36, 0.5 * 36, 1 * 36, 2 * 36, 5 * 36, 10 * 36, 15 * 36].map(Math.ceil),
165
+ true,
166
+ ),
167
+ }),
144
168
  new View({
145
169
  instrumentType: InstrumentType.HISTOGRAM,
146
170
  instrumentUnit: 's',
@@ -257,20 +281,55 @@ export class OpenTelemetryClient implements TelemetryClient {
257
281
 
258
282
  tracerProvider.register();
259
283
 
260
- const meterProvider = OpenTelemetryClient.createMeterProvider(resource, {
261
- exporter: config.metricsCollectorUrl
262
- ? new OtelFilterMetricExporter(
263
- new OTLPMetricExporter({ url: config.metricsCollectorUrl.href }),
264
- config.otelExcludeMetrics ?? [],
265
- )
266
- : undefined,
267
- exportTimeoutMillis: config.otelExportTimeoutMs,
268
- exportIntervalMillis: config.otelCollectIntervalMs,
269
- });
284
+ const exporters: PeriodicExportingMetricReaderOptions[] = [];
285
+ if (config.metricsCollectorUrl) {
286
+ // Default to a blacklist that is empty (allow all metrics)
287
+ let filter: string[] = [];
288
+ let mode: 'allow' | 'deny' = 'deny';
289
+ if (config.otelExcludeMetrics.length > 0) {
290
+ // Implement a blacklist as specified in config
291
+ log.info(`Excluding metrics from export: ${config.otelExcludeMetrics}`);
292
+ filter = config.otelExcludeMetrics;
293
+ mode = 'deny';
294
+ } else if (config.otelIncludeMetrics.length > 0) {
295
+ // Implement a whitelist as specified in config
296
+ log.info(`Including only specified metrics for export: ${config.otelIncludeMetrics}`);
297
+ filter = config.otelIncludeMetrics;
298
+ mode = 'allow';
299
+ }
300
+ exporters.push({
301
+ exporter: new OtelFilterMetricExporter(
302
+ new OTLPMetricExporter({ url: config.metricsCollectorUrl.href }),
303
+ filter,
304
+ mode,
305
+ ),
306
+ exportTimeoutMillis: config.otelExportTimeoutMs,
307
+ exportIntervalMillis: config.otelCollectIntervalMs,
308
+ });
309
+ }
310
+
311
+ let publicExporter: PublicOtelFilterMetricExporter | undefined;
312
+ if (config.publicMetricsCollectorUrl && !config.publicMetricsOptOut) {
313
+ log.info(`Exporting public metrics: ${config.publicIncludeMetrics}`, {
314
+ publicMetrics: config.publicIncludeMetrics,
315
+ collectorUrl: config.publicMetricsCollectorUrl,
316
+ });
317
+ publicExporter = new PublicOtelFilterMetricExporter(
318
+ config.publicMetricsCollectFrom,
319
+ new OTLPMetricExporter({ url: config.publicMetricsCollectorUrl.href }),
320
+ config.publicIncludeMetrics,
321
+ );
322
+ exporters.push({
323
+ exporter: publicExporter,
324
+ exportTimeoutMillis: config.otelExportTimeoutMs,
325
+ exportIntervalMillis: config.otelCollectIntervalMs,
326
+ });
327
+ }
270
328
 
329
+ const meterProvider = OpenTelemetryClient.createMeterProvider(resource, exporters);
271
330
  const loggerProvider = registerOtelLoggerProvider(resource, config.logsCollectorUrl);
272
331
 
273
- return new OpenTelemetryClient(resource, meterProvider, tracerProvider, loggerProvider, log);
332
+ return new OpenTelemetryClient(resource, meterProvider, tracerProvider, loggerProvider, publicExporter, log);
274
333
  };
275
334
  }
276
335
 
@@ -1,8 +1,14 @@
1
- import type { ExportResult } from '@opentelemetry/core';
1
+ import { type ExportResult, ExportResultCode } from '@opentelemetry/core';
2
2
  import type { MetricData, PushMetricExporter, ResourceMetrics } from '@opentelemetry/sdk-metrics';
3
3
 
4
+ import { AZTEC_NODE_ROLE } from './attributes.js';
5
+
4
6
  export class OtelFilterMetricExporter implements PushMetricExporter {
5
- constructor(private readonly exporter: PushMetricExporter, private readonly excludeMetricPrefixes: string[]) {
7
+ constructor(
8
+ private readonly exporter: PushMetricExporter,
9
+ private metricPrefix: string[],
10
+ private readonly filter: 'allow' | 'deny' = 'deny',
11
+ ) {
6
12
  if (exporter.selectAggregation) {
7
13
  (this as PushMetricExporter).selectAggregation = exporter.selectAggregation.bind(exporter);
8
14
  }
@@ -23,9 +29,17 @@ export class OtelFilterMetricExporter implements PushMetricExporter {
23
29
  }
24
30
 
25
31
  private filterMetrics(metrics: MetricData[]): MetricData[] {
26
- return metrics.filter(
27
- metric => !this.excludeMetricPrefixes.some(prefix => metric.descriptor.name.startsWith(prefix)),
28
- );
32
+ return metrics.filter(metric => {
33
+ const matched = this.metricPrefix.some(prefix => metric.descriptor.name.startsWith(prefix));
34
+
35
+ if (this.filter === 'deny') {
36
+ return !matched;
37
+ }
38
+
39
+ if (this.filter === 'allow') {
40
+ return matched;
41
+ }
42
+ });
29
43
  }
30
44
 
31
45
  public forceFlush(): Promise<void> {
@@ -35,4 +49,32 @@ export class OtelFilterMetricExporter implements PushMetricExporter {
35
49
  public shutdown(): Promise<void> {
36
50
  return this.exporter.shutdown();
37
51
  }
52
+
53
+ public setMetricPrefixes(metrics: string[]) {
54
+ this.metricPrefix = metrics;
55
+ }
56
+ }
57
+
58
+ export class PublicOtelFilterMetricExporter extends OtelFilterMetricExporter {
59
+ constructor(
60
+ private allowedRoles: string[],
61
+ exporter: PushMetricExporter,
62
+ metricPrefix: string[],
63
+ ) {
64
+ super(exporter, metricPrefix, 'allow');
65
+ }
66
+
67
+ public override export(metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void): void {
68
+ const role = String(metrics.resource.attributes[AZTEC_NODE_ROLE] ?? '');
69
+ if (!role || !this.allowedRoles.includes(role)) {
70
+ // noop
71
+ return resultCallback({ code: ExportResultCode.SUCCESS });
72
+ }
73
+
74
+ super.export(metrics, resultCallback);
75
+ }
76
+
77
+ public setAllowedRoles(roles: string[]) {
78
+ this.allowedRoles = roles;
79
+ }
38
80
  }