mirror of
https://github.com/golang/go
synced 2024-11-06 03:26:15 -07:00
c4206d458c
We no longer use the span as the core type of tracing, instead that is an artifact of the exporter, and start and end tracing is just event based. This both makes the interface normalized, and also means the null exporter case is considerably cheaper in memory and cpu. See below for benchstat changes name old time/op new time/op delta TracingNoExporter-8 4.19µs ±12% 2.71µs ±11% -35.33% (p=0.000 n=20+20) Tracing-8 24.1µs ± 3% 5.1µs ±17% -78.66% (p=0.000 n=16+20) name old alloc/op new alloc/op delta TracingNoExporter-8 2.32kB ± 0% 0.40kB ± 0% -82.76% (p=0.000 n=20+20) Tracing-8 6.32kB ± 0% 2.32kB ± 0% -63.30% (p=0.000 n=20+20) name old allocs/op new allocs/op delta TracingNoExporter-8 35.0 ± 0% 15.0 ± 0% -57.14% (p=0.000 n=20+20) Tracing-8 215 ± 0% 35 ± 0% -83.72% (p=0.000 n=20+20) Change-Id: I3cf25871fa49584819504b5c19aa580e5dd03395 Reviewed-on: https://go-review.googlesource.com/c/tools/+/221740 Run-TryBot: Ian Cottrell <iancottrell@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Package export holds the definition of the telemetry Exporter interface,
|
|
// along with some simple implementations.
|
|
// Larger more complex exporters are in sub packages of their own.
|
|
package export
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"sync/atomic"
|
|
"time"
|
|
"unsafe"
|
|
|
|
"golang.org/x/tools/internal/telemetry"
|
|
)
|
|
|
|
type Exporter interface {
|
|
// ProcessEvent is a function that handles all events.
|
|
// Exporters may use information in the context to decide what to do with a
|
|
// given event.
|
|
ProcessEvent(context.Context, telemetry.Event) context.Context
|
|
|
|
Metric(context.Context, telemetry.MetricData)
|
|
}
|
|
|
|
var (
|
|
exporter unsafe.Pointer
|
|
)
|
|
|
|
func init() {
|
|
SetExporter(LogWriter(os.Stderr, true))
|
|
}
|
|
|
|
func SetExporter(e Exporter) {
|
|
p := unsafe.Pointer(&e)
|
|
if e == nil {
|
|
p = nil
|
|
}
|
|
atomic.StorePointer(&exporter, p)
|
|
}
|
|
|
|
func Tag(ctx context.Context, at time.Time, tags telemetry.TagList) {
|
|
exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
|
|
if exporterPtr == nil {
|
|
return
|
|
}
|
|
// If context has a span we need to add the tags to it
|
|
span := GetSpan(ctx)
|
|
if span == nil {
|
|
return
|
|
}
|
|
if span.Start.IsZero() {
|
|
// span still being created, tag it directly
|
|
span.Tags = append(span.Tags, tags...)
|
|
return
|
|
}
|
|
// span in progress, add an event to the span
|
|
span.Events = append(span.Events, telemetry.Event{
|
|
At: at,
|
|
Tags: tags,
|
|
})
|
|
}
|
|
|
|
func ProcessEvent(ctx context.Context, event telemetry.Event) context.Context {
|
|
exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
|
|
if exporterPtr == nil {
|
|
return ctx
|
|
}
|
|
// and now also hand the event of to the current exporter
|
|
return (*exporterPtr).ProcessEvent(ctx, event)
|
|
}
|
|
|
|
func Metric(ctx context.Context, data telemetry.MetricData) {
|
|
exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
|
|
if exporterPtr == nil {
|
|
return
|
|
}
|
|
(*exporterPtr).Metric(ctx, data)
|
|
}
|