@@ -76,23 +76,44 @@ macro_rules! metric_refs {
7676 ) ,*
7777 $( , ) ?
7878 }
79+ stable_derived {
80+ $(
81+ #[ doc = $derived_doc: tt]
82+ $derived_name: ident: $derived_kind: tt <$derived_unit: ident> $derived_opts: tt
83+ ) ,*
84+ $( , ) ?
85+ }
7986 unstable {
8087 $(
8188 #[ doc = $unstable_doc: tt]
8289 $unstable_name: ident: $unstable_kind: tt <$unstable_unit: ident> $unstable_opts: tt
8390 ) ,*
8491 $( , ) ?
8592 }
93+ unstable_derived {
94+ $(
95+ #[ doc = $unstable_derived_doc: tt]
96+ $unstable_derived_name: ident: $unstable_derived_kind: tt <$unstable_derived_unit: ident> $unstable_derived_opts: tt
97+ ) ,*
98+ $( , ) ?
99+ }
86100 }
87101 ) => {
88102 struct $struct_name {
89103 $(
90104 $name: crate :: metrics_rs:: kind_to_type!( $kind) ,
91105 ) *
106+ $(
107+ $derived_name: crate :: metrics_rs:: kind_to_type!( $derived_kind) ,
108+ ) *
92109 $(
93110 #[ cfg( tokio_unstable) ]
94111 $unstable_name: crate :: metrics_rs:: kind_to_type!( $unstable_kind) ,
95112 ) *
113+ $(
114+ #[ cfg( tokio_unstable) ]
115+ $unstable_derived_name: crate :: metrics_rs:: kind_to_type!( $unstable_derived_kind) ,
116+ ) *
96117 }
97118
98119 impl $struct_name {
@@ -101,14 +122,30 @@ macro_rules! metric_refs {
101122 $(
102123 $name: crate :: metrics_rs:: capture_metric_ref!( transform_fn, $name: $kind $opts) ,
103124 ) *
125+ $(
126+ $derived_name: crate :: metrics_rs:: capture_metric_ref!( transform_fn, $derived_name: $derived_kind $derived_opts) ,
127+ ) *
104128 $(
105129 #[ cfg( tokio_unstable) ]
106130 $unstable_name: crate :: metrics_rs:: capture_metric_ref!( transform_fn, $unstable_name: $unstable_kind $unstable_opts) ,
107131 ) *
132+ $(
133+ #[ cfg( tokio_unstable) ]
134+ $unstable_derived_name: crate :: metrics_rs:: capture_metric_ref!( transform_fn, $unstable_derived_name: $unstable_derived_kind $unstable_derived_opts) ,
135+ ) *
108136 }
109137 }
110138
111139 fn emit( & self , metrics: $metrics_name, emit_arg: $emit_arg_type) {
140+ // Emit derived metrics before base metrics because emitting base metrics may move
141+ // out of `$metrics`.
142+ $(
143+ crate :: metrics_rs:: MyMetricOp :: op( ( & self . $derived_name, metrics. $derived_name( ) ) , emit_arg) ;
144+ ) *
145+ $(
146+ #[ cfg( tokio_unstable) ]
147+ crate :: metrics_rs:: MyMetricOp :: op( ( & self . $unstable_derived_name, metrics. $unstable_derived_name( ) ) , emit_arg) ;
148+ ) *
112149 $(
113150 crate :: metrics_rs:: MyMetricOp :: op( ( & self . $name, metrics. $name) , emit_arg) ;
114151 ) *
@@ -122,10 +159,17 @@ macro_rules! metric_refs {
122159 $(
123160 crate :: metrics_rs:: describe_metric_ref!( transform_fn, $doc, $name: $kind<$unit> $opts) ;
124161 ) *
162+ $(
163+ crate :: metrics_rs:: describe_metric_ref!( transform_fn, $derived_doc, $derived_name: $derived_kind<$derived_unit> $derived_opts) ;
164+ ) *
125165 $(
126166 #[ cfg( tokio_unstable) ]
127167 crate :: metrics_rs:: describe_metric_ref!( transform_fn, $unstable_doc, $unstable_name: $unstable_kind<$unstable_unit> $unstable_opts) ;
128168 ) *
169+ $(
170+ #[ cfg( tokio_unstable) ]
171+ crate :: metrics_rs:: describe_metric_ref!( transform_fn, $unstable_derived_doc, $unstable_derived_name: $unstable_derived_kind<$unstable_derived_unit> $unstable_derived_opts) ;
172+ ) *
129173 }
130174 }
131175
@@ -161,6 +205,28 @@ macro_rules! metric_refs {
161205 panic!( "missing metric {:?}" , line) ;
162206 }
163207 }
208+
209+ #[ test]
210+ fn test_no_derived_metrics_missing( ) {
211+ // test that no derived metrics are missing.
212+ for derived_metric in <$metrics_name>:: DERIVED_METRICS {
213+ $(
214+ if * derived_metric == stringify!( $derived_name) {
215+ continue
216+ }
217+ ) ;*
218+ panic!( "missing metric {:?}" , derived_metric) ;
219+ }
220+ #[ cfg( tokio_unstable) ]
221+ for unstable_derived_metric in <$metrics_name>:: UNSTABLE_DERIVED_METRICS {
222+ $(
223+ if * unstable_derived_metric == stringify!( $unstable_derived_name) {
224+ continue
225+ }
226+ ) ;*
227+ panic!( "missing metric {:?}" , unstable_derived_metric) ;
228+ }
229+ }
164230 }
165231}
166232
@@ -205,6 +271,12 @@ impl<T> MyMetricOp<T> for (&metrics::Gauge, usize) {
205271 }
206272}
207273
274+ impl < T > MyMetricOp < T > for ( & metrics:: Gauge , f64 ) {
275+ fn op ( self , _t : T ) {
276+ self . 0 . set ( self . 1 ) ;
277+ }
278+ }
279+
208280#[ cfg( tokio_unstable) ]
209281impl MyMetricOp < & tokio:: runtime:: RuntimeMetrics > for ( & metrics:: Histogram , Vec < u64 > ) {
210282 fn op ( self , tokio : & tokio:: runtime:: RuntimeMetrics ) {
0 commit comments