cuelang.org/go@v0.10.1/internal/golangorgx/telemetry/counter/counter.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build go1.19 && !openbsd && !js && !wasip1 && !solaris && !android && !plan9 && !386
     6  
     7  package counter
     8  
     9  // The implementation of this package and tests are located in
    10  // internal/counter, which can be shared with the upload package.
    11  // TODO(hyangah): use of type aliases prevents nice documentation
    12  // rendering in go doc or pkgsite. Fix this either by avoiding
    13  // type aliasing or restructuring the internal/counter package.
    14  import (
    15  	"flag"
    16  
    17  	"cuelang.org/go/internal/golangorgx/telemetry/internal/counter"
    18  )
    19  
    20  // Inc increments the counter with the given name.
    21  func Inc(name string) {
    22  	New(name).Inc()
    23  }
    24  
    25  // Add adds n to the counter with the given name.
    26  func Add(name string, n int64) {
    27  	New(name).Add(n)
    28  }
    29  
    30  // New returns a counter with the given name.
    31  // New can be called in global initializers and will be compiled down to
    32  // linker-initialized data. That is, calling New to initialize a global
    33  // has no cost at program startup.
    34  func New(name string) *Counter {
    35  	// Note: not calling DefaultFile.New in order to keep this
    36  	// function something the compiler can inline and convert
    37  	// into static data initializations, with no init-time footprint.
    38  	// TODO(hyangah): is it trivial enough for the compiler to inline?
    39  	return counter.New(name)
    40  }
    41  
    42  // A Counter is a single named event counter.
    43  // A Counter is safe for use by multiple goroutines simultaneously.
    44  //
    45  // Counters should typically be created using New
    46  // and stored as global variables, like:
    47  //
    48  //	package mypackage
    49  //	var errorCount = counter.New("mypackage/errors")
    50  //
    51  // (The initialization of errorCount in this example is handled
    52  // entirely by the compiler and linker; this line executes no code
    53  // at program startup.)
    54  //
    55  // Then code can call Add to increment the counter
    56  // each time the corresponding event is observed.
    57  //
    58  // Although it is possible to use New to create
    59  // a Counter each time a particular event needs to be recorded,
    60  // that usage fails to amortize the construction cost over
    61  // multiple calls to Add, so it is more expensive and not recommended.
    62  type Counter = counter.Counter
    63  
    64  // a StackCounter is the in-memory knowledge about a stack counter.
    65  // StackCounters are more expensive to use than regular Counters,
    66  // requiring, at a minimum, a call to runtime.Callers.
    67  type StackCounter = counter.StackCounter
    68  
    69  // NewStack returns a new stack counter with the given name and depth.
    70  func NewStack(name string, depth int) *StackCounter {
    71  	return counter.NewStack(name, depth)
    72  }
    73  
    74  // Open prepares telemetry counters for recording to the file system.
    75  //
    76  // If the telemetry mode is "off", Open is a no-op. Otherwise, it opens the
    77  // counter file on disk and starts to mmap telemetry counters to the file.
    78  // Open also persists any counters already created in the current process.
    79  //
    80  // Programs using telemetry should call Open exactly once.
    81  func Open() {
    82  	counter.Open()
    83  }
    84  
    85  // CountFlags creates a counter for every flag that is set
    86  // and increments the counter. The name of the counter is
    87  // the concatenation of prefix and the flag name.
    88  //
    89  //	For instance, CountFlags("gopls:flag-", flag.CommandLine)
    90  func CountFlags(prefix string, fs flag.FlagSet) {
    91  	fs.Visit(func(f *flag.Flag) {
    92  		New(prefix + f.Name).Inc()
    93  	})
    94  }