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 }