diff --git a/etherlink/bin_node/lib_dev/evm_context.ml b/etherlink/bin_node/lib_dev/evm_context.ml index 05e5753c0422151c818eeee7893e4b063eb7b51b..e0ed7627f3a8254ed5ba996fe7ca3e63f1c07ad4 100644 --- a/etherlink/bin_node/lib_dev/evm_context.ml +++ b/etherlink/bin_node/lib_dev/evm_context.ml @@ -879,6 +879,15 @@ module State = struct let* context, split_info = commit_next_head ctxt conn timestamp evm_state in + + Octez_telemetry.Trace.add_attrs (fun () -> + Telemetry.Attributes. + [ + Block.number ctxt.session.next_blueprint_number; + Block.transaction_count (List.length receipts); + Block.execution_gas execution_gas; + ]) ; + return ( evm_state, context, diff --git a/etherlink/bin_node/lib_dev/evm_store.ml b/etherlink/bin_node/lib_dev/evm_store.ml index 69321b55ae619fb5a70a3d15355054ef9c8a04f8..02a0bfb0de60895ab158a8ded6519f1f23a3a8ff 100644 --- a/etherlink/bin_node/lib_dev/evm_store.ml +++ b/etherlink/bin_node/lib_dev/evm_store.ml @@ -697,6 +697,8 @@ DO UPDATE SET value = excluded.value ->. unit) ~name:__FUNCTION__ ~table + ~attrs:(fun (_, _, _, hash, _, _, _, _) -> + [Telemetry.Attributes.Transaction.hash hash]) @@ {eos|INSERT INTO transactions (block_hash, block_number, index_, hash, from_, to_, receipt_fields, object_fields) VALUES (?, ?, ?, ?, ?, ?, ?, ?)|eos} let select_receipt = diff --git a/etherlink/bin_node/lib_dev/services.ml b/etherlink/bin_node/lib_dev/services.ml index ca58e552a4f6714c1c7567f96131b71928247545..311bd6fe8bb5a70865fcaffe1efbd6af4d3500d7 100644 --- a/etherlink/bin_node/lib_dev/services.ml +++ b/etherlink/bin_node/lib_dev/services.ml @@ -709,6 +709,9 @@ let dispatch_request (type f) ~websocket build_with_input ~f module_ parameters | Get_transaction_receipt.Method -> let f tx_hash = + Octez_telemetry.Trace.add_attrs (fun () -> + Telemetry.Attributes.[Transaction.hash tx_hash]) ; + let* receipt = Backend_rpc.Etherlink_block_storage.transaction_receipt tx_hash in @@ -768,6 +771,10 @@ let dispatch_request (type f) ~websocket build_with_input ~f module_ parameters | Get_transaction_by_hash.Method -> let f tx_hash = + Octez_telemetry.Trace.( + add_attrs (fun () -> + Telemetry.Attributes.[Transaction.hash tx_hash])) ; + let* (module Tx_container) = match tx_container with | Evm_tx_container m -> return m @@ -861,6 +868,11 @@ let dispatch_request (type f) ~websocket in rpc_error (Rpc_errors.transaction_rejected err None) | Ok (next_nonce, transaction_object) -> ( + Octez_telemetry.Trace.( + add_attrs (fun () -> + Telemetry.Attributes. + [Transaction.hash transaction_object.hash])) ; + let* (module Tx_container) = match tx_container with | Evm_tx_container m -> return m @@ -1125,6 +1137,10 @@ let dispatch_private_request (type f) ~websocket let f ( (transaction_object : Ethereum_types.legacy_transaction_object), raw_txn ) = + Octez_telemetry.Trace.( + add_attrs (fun () -> + Telemetry.Attributes.[Transaction.hash transaction_object.hash])) ; + let* is_valid = let get_nonce () = let* next_nonce = diff --git a/etherlink/bin_node/lib_dev/telemetry.ml b/etherlink/bin_node/lib_dev/telemetry.ml index c16d586248233423daaf67bdda1bf1da1bd640a4..40c00d5d7afdb961d627209b84bc3ec48f8eb2b0 100644 --- a/etherlink/bin_node/lib_dev/telemetry.ml +++ b/etherlink/bin_node/lib_dev/telemetry.ml @@ -57,3 +57,21 @@ module Jsonrpc = struct | None -> ()) ; Lwt.return_error err end + +module Attributes = struct + module Transaction = struct + let hash hash = + ( "etherlink.transaction.hash", + `String (Ethereum_types.hash_to_string hash) ) + end + + module Block = struct + let number (Ethereum_types.Qty number) = + ("etherlink.block.number", `Int (Z.to_int number)) + + let execution_gas qty = + ("etherlink.block.execution_gas", `Int (Z.to_int qty)) + + let transaction_count qty = ("etherlink.block.transactions_count", `Int qty) + end +end diff --git a/etherlink/bin_node/lib_dev/telemetry.mli b/etherlink/bin_node/lib_dev/telemetry.mli index 018103ce28d3875cb9e96fc9486fa330f036d506..3b42c364dc5617168a1412965f9c9594075c172b 100644 --- a/etherlink/bin_node/lib_dev/telemetry.mli +++ b/etherlink/bin_node/lib_dev/telemetry.mli @@ -33,3 +33,25 @@ module Jsonrpc : sig related to [err]. *) val return_error : JSONRPC.error -> ('a, JSONRPC.error) result Lwt.t end + +(** OpenTelemetry Etherlink-specific semantics conventions *) +module Attributes : sig + module Transaction : sig + (** Hex-encoded hash of the transaction being processed *) + val hash : Ethereum_types.hash -> Opentelemetry.key_value + end + + (** Tags to add to a span or event handling a given block. *) + module Block : sig + (** Integer representation of the block number being processed *) + val number : Ethereum_types.quantity -> Opentelemetry.key_value + + (** Integer representation of the amount of gas units necessary to process + the block *) + val execution_gas : Z.t -> Opentelemetry.key_value + + (** Integer representation of the number of transactions included in the + block being processed *) + val transaction_count : int -> Opentelemetry.key_value + end +end diff --git a/etherlink/bin_node/lib_dev/tx_queue.ml b/etherlink/bin_node/lib_dev/tx_queue.ml index 9cc7f479b2cd24d2f95a6348627b38c5623e7167..54986554c12796038b134ee2bcb68f6f0fb41602 100644 --- a/etherlink/bin_node/lib_dev/tx_queue.ml +++ b/etherlink/bin_node/lib_dev/tx_queue.ml @@ -540,6 +540,11 @@ module Worker = Worker.MakeSingle (Name) (Request) (Types) type worker = Worker.infinite Worker.queue Worker.t +let tx_queue_event ?attrs name = + Opentelemetry_lwt.Event.make + ?attrs + Format.(sprintf "%s/%s" (String.concat "." Name.base) name) + module Handlers = struct open Request @@ -555,7 +560,11 @@ module Handlers = struct else let rev_batch, callbacks = Seq.fold_left - (fun (rev_batch, callbacks) {hash = _; payload; queue_callback} -> + (fun (rev_batch, callbacks) {hash; payload; queue_callback} -> + Octez_telemetry.Trace.add_event (fun () -> + tx_queue_event + ~attrs:Telemetry.Attributes.[Transaction.hash hash] + "selected_transaction") ; let req_id = Uuidm.(v4_gen uuid_seed () |> to_string ~upper:false) in diff --git a/src/lib_telemetry/trace.ml b/src/lib_telemetry/trace.ml index edc905eb471497da0cbe34dfe7f6341325fb2910..d18aee21da27416a762ef661dbfb75df28eed13b 100644 --- a/src/lib_telemetry/trace.ml +++ b/src/lib_telemetry/trace.ml @@ -40,3 +40,15 @@ let with_result ?(message_on_success = Fun.const "Success") | res -> Lwt.return res let with_tzresult = with_result ~message_on_error:message_on_tztrace + +let add_attrs f = + if Opentelemetry.Collector.has_backend () then + match Opentelemetry.Scope.get_ambient_scope () with + | Some scope -> Opentelemetry_lwt.Trace.add_attrs scope @@ f + | None -> () + +let add_event f = + if Opentelemetry.Collector.has_backend () then + match Opentelemetry.Scope.get_ambient_scope () with + | Some scope -> Opentelemetry_lwt.Trace.add_event scope @@ f + | None -> () diff --git a/src/lib_telemetry/trace.mli b/src/lib_telemetry/trace.mli index 65f00192b9f6bd5f1a06d529e781cd72232efbe1..c24d6048f0e40f0987ad272e2695717c8cd4f7c8 100644 --- a/src/lib_telemetry/trace.mli +++ b/src/lib_telemetry/trace.mli @@ -21,3 +21,11 @@ val with_tzresult : string -> (Opentelemetry.Scope.t -> 'a tzresult Lwt.t) -> 'a tzresult Lwt.t + +(** [add_attrs f] adds the attributes generated by [f] to the current trace + being recorded, if any. Does nothing otherwise. *) +val add_attrs : (unit -> Opentelemetry.key_value list) -> unit + +(** [add_attrs f] adds the event generated by [f] to the current trace being + recorded, if any. Does nothing otherwise. *) +val add_event : (unit -> Opentelemetry.Event.t) -> unit