github.com/uber-go/tally/v4@v4.1.17/instrument/call.go (about)

     1  // Copyright (c) 2021 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package instrument
    22  
    23  import (
    24  	tally "github.com/uber-go/tally/v4"
    25  )
    26  
    27  const (
    28  	resultType        = "result_type"
    29  	resultTypeError   = "error"
    30  	resultTypeSuccess = "success"
    31  	timingSuffix      = "latency"
    32  )
    33  
    34  // NewCall returns a Call that instruments a function using a given scope
    35  // and a label to name the metrics.
    36  // The following counters are created excluding {{ and }}:
    37  // {{name}}+result_type=success
    38  // {{name}}+result_type=error
    39  // The following timers are created excluding {{ and }} and replacing . with
    40  // the scope's separator:
    41  // {{name}}.latency
    42  func NewCall(scope tally.Scope, name string) Call {
    43  	return &call{
    44  		err:     scope.Tagged(map[string]string{resultType: resultTypeError}).Counter(name),
    45  		success: scope.Tagged(map[string]string{resultType: resultTypeSuccess}).Counter(name),
    46  		timing:  scope.SubScope(name).Timer(timingSuffix),
    47  	}
    48  }
    49  
    50  type call struct {
    51  	success tally.Counter
    52  	err     tally.Counter
    53  	timing  tally.Timer
    54  }
    55  
    56  func (c *call) Exec(f ExecFn) error {
    57  	sw := c.timing.Start()
    58  	err := f()
    59  	sw.Stop()
    60  
    61  	if err != nil {
    62  		c.err.Inc(1)
    63  		return err
    64  	}
    65  
    66  	c.success.Inc(1)
    67  	return nil
    68  }