@@ -144,81 +144,106 @@ func NewInstrumentation(id int64) (*Instrumentation, error) {
144144 return i , err
145145}
146146
147- // RecordDurationDone is a function that is called when a call to an Exporters'
148- // RecordOperationDuration or RecordCollectionDuration completes.
147+ // RecordOperationDuration starts the timing of an operation.
149148//
150- // Any error that is encountered is provided as err.
151- type RecordDurationDone func (error )
152-
153- func (i * Instrumentation ) RecordOperationDuration (ctx context.Context ) RecordDurationDone {
154- return i .recordDuration (ctx , i .operationDuration )
149+ // It returns a [Timer] that tracks the operation duration. The [Timer.Stop]
150+ // method must be called when the operation completes.
151+ func (i * Instrumentation ) RecordOperationDuration (ctx context.Context ) Timer {
152+ return Timer {
153+ ctx : ctx ,
154+ start : time .Now (),
155+ inst : i ,
156+ hist : i .operationDuration ,
157+ }
155158}
156159
157- func (i * Instrumentation ) RecordCollectionDuration (ctx context.Context ) RecordDurationDone {
158- return i .recordDuration (ctx , i .collectionDuration )
160+ // RecordCollectionDuration starts the timing of a collection operation.
161+ //
162+ // It returns a [Timer] that tracks the collection duration. The [Timer.Stop]
163+ // method must be called when the collection completes.
164+ func (i * Instrumentation ) RecordCollectionDuration (ctx context.Context ) Timer {
165+ return Timer {
166+ ctx : ctx ,
167+ start : time .Now (),
168+ inst : i ,
169+ hist : i .collectionDuration ,
170+ }
159171}
160172
161- func (i * Instrumentation ) recordDuration (
162- ctx context.Context ,
163- h metric.Float64Histogram ,
164- ) RecordDurationDone {
165- start := time .Now ()
173+ // Timer tracks the duration of an operation.
174+ type Timer struct {
175+ ctx context.Context
176+ start time.Time
166177
167- return func (err error ) {
168- recordOpt := get [metric.RecordOption ](recordOptPool )
169- defer put (recordOptPool , recordOpt )
170- * recordOpt = append (* recordOpt , i .setOpt )
171-
172- if err != nil {
173- attrs := get [attribute.KeyValue ](measureAttrsPool )
174- defer put (measureAttrsPool , attrs )
175- * attrs = append (* attrs , i .attrs ... )
176- * attrs = append (* attrs , semconv .ErrorType (err ))
177-
178- set := attribute .NewSet (* attrs ... )
179- * recordOpt = append ((* recordOpt )[:0 ], metric .WithAttributeSet (set ))
180- }
178+ inst * Instrumentation
179+ hist metric.Float64Histogram
180+ }
181181
182- h .Record (ctx , time .Since (start ).Seconds (), * recordOpt ... )
182+ // Stop ends the timing operation and records the elapsed duration.
183+ //
184+ // If err is non-nil, an appropriate error type attribute will be included.
185+ func (t Timer ) Stop (err error ) {
186+ recordOpt := get [metric.RecordOption ](recordOptPool )
187+ defer put (recordOptPool , recordOpt )
188+ * recordOpt = append (* recordOpt , t .inst .setOpt )
189+
190+ if err != nil {
191+ attrs := get [attribute.KeyValue ](measureAttrsPool )
192+ defer put (measureAttrsPool , attrs )
193+ * attrs = append (* attrs , t .inst .attrs ... )
194+ * attrs = append (* attrs , semconv .ErrorType (err ))
195+
196+ set := attribute .NewSet (* attrs ... )
197+ * recordOpt = append ((* recordOpt )[:0 ], metric .WithAttributeSet (set ))
183198 }
199+
200+ t .hist .Record (t .ctx , time .Since (t .start ).Seconds (), * recordOpt ... )
184201}
185202
186- // ExportMetricsDone is a function that is called when a call to an Exporter's
187- // export methods completes.
203+ // ExportMetrics starts the observation of a metric export operation.
188204//
189- // The number of successful exports is provided as success. Any error that is
190- // encountered is provided as err.
191- type ExportMetricsDone func (success int64 , err error )
192-
193- func (i * Instrumentation ) ExportMetrics (ctx context.Context , n int64 ) ExportMetricsDone {
205+ // It returns an [ExportOp] that tracks the export operation. The
206+ // [ExportOp.End] method must be called when the export completes.
207+ func (i * Instrumentation ) ExportMetrics (ctx context.Context , n int64 ) ExportOp {
194208 addOpt := get [metric.AddOption ](addOptPool )
195209 defer put (addOptPool , addOpt )
196210 * addOpt = append (* addOpt , i .setOpt )
197211
198212 i .inflightMetric .Add (ctx , n , * addOpt ... )
199213
200- return i .end (ctx , n )
214+ return ExportOp {ctx : ctx , nMetrics : n , inst : i }
215+ }
216+
217+ // ExportOp tracks a metric export operation.
218+ type ExportOp struct {
219+ ctx context.Context
220+ nMetrics int64
221+
222+ inst * Instrumentation
201223}
202224
203- func (i * Instrumentation ) end (ctx context.Context , n int64 ) ExportMetricsDone {
204- return func (success int64 , err error ) {
205- addOpt := get [metric.AddOption ](addOptPool )
206- defer put (addOptPool , addOpt )
207- * addOpt = append (* addOpt , i .setOpt )
225+ // End ends the observation of a metric export operation.
226+ //
227+ // The success parameter is the number of metrics that were successfully
228+ // exported. If a non-nil error is provided, the number of failed metrics will
229+ // be recorded with the error type attribute.
230+ func (e ExportOp ) End (success int64 , err error ) {
231+ addOpt := get [metric.AddOption ](addOptPool )
232+ defer put (addOptPool , addOpt )
233+ * addOpt = append (* addOpt , e .inst .setOpt )
208234
209- i . inflightMetric .Add (ctx , - n , * addOpt ... )
210- i . exportedMetric .Add (ctx , success , * addOpt ... )
235+ e . inst . inflightMetric .Add (e . ctx , - e . nMetrics , * addOpt ... )
236+ e . inst . exportedMetric .Add (e . ctx , success , * addOpt ... )
211237
212- if err != nil {
213- attrs := get [attribute.KeyValue ](measureAttrsPool )
214- defer put (measureAttrsPool , attrs )
215- * attrs = append (* attrs , i .attrs ... )
216- * attrs = append (* attrs , semconv .ErrorType (err ))
238+ if err != nil {
239+ attrs := get [attribute.KeyValue ](measureAttrsPool )
240+ defer put (measureAttrsPool , attrs )
241+ * attrs = append (* attrs , e . inst .attrs ... )
242+ * attrs = append (* attrs , semconv .ErrorType (err ))
217243
218- set := attribute .NewSet (* attrs ... )
244+ set := attribute .NewSet (* attrs ... )
219245
220- * addOpt = append ((* addOpt )[:0 ], metric .WithAttributeSet (set ))
221- i .exportedMetric .Add (ctx , n - success , * addOpt ... )
222- }
246+ * addOpt = append ((* addOpt )[:0 ], metric .WithAttributeSet (set ))
247+ e .inst .exportedMetric .Add (e .ctx , e .nMetrics - success , * addOpt ... )
223248 }
224249}
0 commit comments