...

Package counter

import "cmd/vendor/golang.org/x/telemetry/counter"
Overview
Index
Subdirectories

Overview ▾

Package counter implements a simple counter system for collecting totally public telemetry data.

There are two kinds of counters, basic counters and stack counters. Basic counters are created by New. Stack counters are created by NewStack. Both are incremented by calling Inc().

Basic counters are very cheap. Stack counters are more expensive, as they require parsing the stack. (Stack counters are implemented as basic counters whose names are the concatenation of the name and the stack trace. There is an upper limit on the size of this name, about 4K bytes. If the name is too long the stack will be truncated and "truncated" appended.)

When counter files expire they are turned into reports by the upload package. The first time any counter file is created for a user, a random day of the week is selected on which counter files will expire. For the first week, that day is more than 7 days (but not more than two weeks) in the future. After that the counter files expire weekly on the same day of the week.

Counter Naming

Counter names passed to New and NewStack should follow these conventions:

  • Names cannot contain whitespace or newlines.

  • Names must be valid unicode, with no unprintable characters.

  • Names may contain at most one ':'. In the counter "foo:bar", we refer to "foo" as the "chart name" and "bar" as the "bucket name".

  • The '/' character should partition counter names into a hierarchy. The root of this hierarchy should identify the logical entity that "owns" the counter. This could be an application, such as "gopls" in the case of "gopls/client:vscode", or a shared library, such as "crash" in the case of the "crash/crash" counter owned by the crashmonitor library. If the entity name itself contains a '/', that's ok: "cmd/go/flag" is fine.

  • Words should be '-' separated, as in "gopls/completion/errors-latency"

  • Histograms should use bucket names identifying upper bounds with '<'. For example given two counters "gopls/completion/latency:<50ms" and "gopls/completion/latency:<100ms", the "<100ms" bucket counts events with latency in the half-open interval [50ms, 100ms).

Debugging

The GODEBUG environment variable can enable printing of additional debug information for counters. Adding GODEBUG=countertrace=1 to the environment of a process using counters causes the x/telemetry/counter package to log counter information to stderr.

func Add

func Add(name string, n int64)

Add adds n to the counter with the given name.

func CountCommandLineFlags

func CountCommandLineFlags()

CountCommandLineFlags creates a counter for every flag that is set in the default flag.CommandLine FlagSet using the counter name binaryName+"/flag:"+flagName where binaryName is the base name of the Path embedded in the binary's build info. If the binary does not have embedded build info, the "flag:"+flagName counter will be incremented.

CountCommandLineFlags must be called after flags are parsed with flag.Parse.

For instance, if the -S flag is passed to cmd/compile and CountCommandLineFlags is called after flags are parsed, the "compile/flag:S" counter will be incremented.

func CountFlags

func CountFlags(prefix string, fs flag.FlagSet)

CountFlags creates a counter for every flag that is set and increments the counter. The name of the counter is the concatenation of prefix and the flag name.

For instance, CountFlags("gopls/flag:", *flag.CommandLine)

func Inc

func Inc(name string)

Inc increments the counter with the given name.

func Open

func Open()

Open prepares telemetry counters for recording to the file system.

If the telemetry mode is "off", Open is a no-op. Otherwise, it opens the counter file on disk and starts to mmap telemetry counters to the file. Open also persists any counters already created in the current process.

Open should only be called from short-lived processes such as command line tools. If your process is long-running, use OpenAndRotate.

func OpenAndRotate

func OpenAndRotate()

OpenAndRotate is like Open, but also schedules a rotation of the counter file when it expires.

See golang/go#68497 for background on why OpenAndRotate is a separate API.

TODO(rfindley): refactor Open and OpenAndRotate for Go 1.24.

func OpenDir

func OpenDir(telemetryDir string)

OpenDir prepares telemetry counters for recording to the file system, using the specified telemetry directory, if it is not the empty string.

If the telemetry mode is "off", Open is a no-op. Otherwise, it opens the counter file on disk and starts to mmap telemetry counters to the file. Open also persists any counters already created in the current process.

type Counter

A Counter is a single named event counter. A Counter is safe for use by multiple goroutines simultaneously.

Counters should typically be created using New and stored as global variables, like:

package mypackage
var errorCount = counter.New("mypackage/errors")

(The initialization of errorCount in this example is handled entirely by the compiler and linker; this line executes no code at program startup.)

Then code can call Add to increment the counter each time the corresponding event is observed.

Although it is possible to use New to create a Counter each time a particular event needs to be recorded, that usage fails to amortize the construction cost over multiple calls to Add, so it is more expensive and not recommended.

type Counter = counter.Counter

func New

func New(name string) *Counter

New returns a counter with the given name. New can be called in global initializers and will be compiled down to linker-initialized data. That is, calling New to initialize a global has no cost at program startup.

See "Counter Naming" in the package doc for a description of counter naming conventions.

type StackCounter

A StackCounter is the in-memory knowledge about a stack counter. StackCounters are more expensive to use than regular Counters, requiring, at a minimum, a call to runtime.Callers.

type StackCounter = counter.StackCounter

func NewStack

func NewStack(name string, depth int) *StackCounter

NewStack returns a new stack counter with the given name and depth.

See "Counter Naming" in the package doc for a description of counter naming conventions.

Subdirectories

Name Synopsis
..