11use crate :: { AttachMetricLabels , LONG_POLL_METHOD_NAMES } ;
22use futures:: { future:: BoxFuture , FutureExt } ;
3- use opentelemetry:: {
4- metrics:: { Counter , Histogram } ,
5- KeyValue ,
6- } ;
73use std:: {
84 sync:: Arc ,
95 task:: { Context , Poll } ,
106 time:: { Duration , Instant } ,
117} ;
8+ use temporal_sdk_core_api:: telemetry:: metrics:: {
9+ CoreMeter , Counter , Histogram , MetricAttributes , MetricKeyValue , MetricsAttributesOptions ,
10+ } ;
1211use tonic:: { body:: BoxBody , transport:: Channel } ;
1312use tower:: Service ;
1413
1514/// Used to track context associated with metrics, and record/update them
1615// Possible improvement: make generic over some type tag so that methods are only exposed if the
1716// appropriate k/vs have already been set.
18- #[ derive( Clone , Debug ) ]
17+ #[ derive( Clone , derive_more:: DebugCustom ) ]
18+ #[ debug( fmt = "MetricsContext {{ attribs: {kvs:?}, poll_is_long: {poll_is_long} }}" ) ]
1919pub struct MetricsContext {
20- ctx : opentelemetry:: Context ,
21- kvs : Arc < Vec < KeyValue > > ,
20+ kvs : MetricAttributes ,
2221 poll_is_long : bool ,
2322
24- svc_request : Counter < u64 > ,
25- svc_request_failed : Counter < u64 > ,
26- long_svc_request : Counter < u64 > ,
27- long_svc_request_failed : Counter < u64 > ,
28-
29- svc_request_latency : Histogram < u64 > ,
30- long_svc_request_latency : Histogram < u64 > ,
31- }
23+ svc_request : Arc < dyn Counter > ,
24+ svc_request_failed : Arc < dyn Counter > ,
25+ long_svc_request : Arc < dyn Counter > ,
26+ long_svc_request_failed : Arc < dyn Counter > ,
3227
33- /// Things that can provide metrics for the client implement this. Trait exists to avoid having
34- /// to make a whole new lower-level crate just for a tiny shared wrapper around OTel meters.
35- pub trait ClientMetricProvider : Send + Sync {
36- /// Construct a counter metric
37- fn counter ( & self , name : & ' static str ) -> Counter < u64 > ;
38- /// Construct a histogram metric
39- fn histogram ( & self , name : & ' static str ) -> Histogram < u64 > ;
28+ svc_request_latency : Arc < dyn Histogram > ,
29+ long_svc_request_latency : Arc < dyn Histogram > ,
4030}
4131
4232impl MetricsContext {
43- pub ( crate ) fn new ( kvs : Vec < KeyValue > , metric_provider : & dyn ClientMetricProvider ) -> Self {
33+ pub ( crate ) fn new ( metric_provider : & dyn CoreMeter ) -> Self {
4434 Self {
45- ctx : opentelemetry:: Context :: current ( ) ,
46- kvs : Arc :: new ( kvs) ,
35+ kvs : metric_provider. new_attributes ( MetricsAttributesOptions :: default ( ) ) ,
4736 poll_is_long : false ,
4837 svc_request : metric_provider. counter ( "request" ) ,
4938 svc_request_failed : metric_provider. counter ( "request_failure" ) ,
@@ -55,15 +44,15 @@ impl MetricsContext {
5544 }
5645
5746 /// Extend an existing metrics context with new attributes, returning a new one
58- pub ( crate ) fn with_new_attrs ( & self , new_kvs : impl IntoIterator < Item = KeyValue > ) -> Self {
47+ pub ( crate ) fn with_new_attrs ( & self , new_kvs : impl IntoIterator < Item = MetricKeyValue > ) -> Self {
5948 let mut r = self . clone ( ) ;
6049 r. add_new_attrs ( new_kvs) ;
6150 r
6251 }
6352
6453 /// Add new attributes to the context, mutating it
65- pub ( crate ) fn add_new_attrs ( & mut self , new_kvs : impl IntoIterator < Item = KeyValue > ) {
66- Arc :: make_mut ( & mut self . kvs ) . extend ( new_kvs) ;
54+ pub ( crate ) fn add_new_attrs ( & mut self , new_kvs : impl IntoIterator < Item = MetricKeyValue > ) {
55+ self . kvs . add_new_attrs ( new_kvs) ;
6756 }
6857
6958 pub ( crate ) fn set_is_long_poll ( & mut self ) {
@@ -73,29 +62,29 @@ impl MetricsContext {
7362 /// A request to the temporal service was made
7463 pub ( crate ) fn svc_request ( & self ) {
7564 if self . poll_is_long {
76- self . long_svc_request . add ( & self . ctx , 1 , & self . kvs ) ;
65+ self . long_svc_request . add ( 1 , & self . kvs ) ;
7766 } else {
78- self . svc_request . add ( & self . ctx , 1 , & self . kvs ) ;
67+ self . svc_request . add ( 1 , & self . kvs ) ;
7968 }
8069 }
8170
8271 /// A request to the temporal service failed
8372 pub ( crate ) fn svc_request_failed ( & self ) {
8473 if self . poll_is_long {
85- self . long_svc_request_failed . add ( & self . ctx , 1 , & self . kvs ) ;
74+ self . long_svc_request_failed . add ( 1 , & self . kvs ) ;
8675 } else {
87- self . svc_request_failed . add ( & self . ctx , 1 , & self . kvs ) ;
76+ self . svc_request_failed . add ( 1 , & self . kvs ) ;
8877 }
8978 }
9079
9180 /// Record service request latency
9281 pub ( crate ) fn record_svc_req_latency ( & self , dur : Duration ) {
9382 if self . poll_is_long {
9483 self . long_svc_request_latency
95- . record ( & self . ctx , dur. as_millis ( ) as u64 , & self . kvs ) ;
84+ . record ( dur. as_millis ( ) as u64 , & self . kvs ) ;
9685 } else {
9786 self . svc_request_latency
98- . record ( & self . ctx , dur. as_millis ( ) as u64 , & self . kvs ) ;
87+ . record ( dur. as_millis ( ) as u64 , & self . kvs ) ;
9988 }
10089 }
10190}
@@ -104,16 +93,16 @@ const KEY_NAMESPACE: &str = "namespace";
10493const KEY_SVC_METHOD : & str = "operation" ;
10594const KEY_TASK_QUEUE : & str = "task_queue" ;
10695
107- pub ( crate ) fn namespace_kv ( ns : String ) -> KeyValue {
108- KeyValue :: new ( KEY_NAMESPACE , ns)
96+ pub ( crate ) fn namespace_kv ( ns : String ) -> MetricKeyValue {
97+ MetricKeyValue :: new ( KEY_NAMESPACE , ns)
10998}
11099
111- pub ( crate ) fn task_queue_kv ( tq : String ) -> KeyValue {
112- KeyValue :: new ( KEY_TASK_QUEUE , tq)
100+ pub ( crate ) fn task_queue_kv ( tq : String ) -> MetricKeyValue {
101+ MetricKeyValue :: new ( KEY_TASK_QUEUE , tq)
113102}
114103
115- pub ( crate ) fn svc_operation ( op : String ) -> KeyValue {
116- KeyValue :: new ( KEY_SVC_METHOD , op)
104+ pub ( crate ) fn svc_operation ( op : String ) -> MetricKeyValue {
105+ MetricKeyValue :: new ( KEY_SVC_METHOD , op)
117106}
118107
119108/// Implements metrics functionality for gRPC (really, any http) calls
0 commit comments