1
0
mirror of https://github.com/golang/go synced 2024-11-18 03:04:45 -07:00

internal/lsp: use standardised events for tagging

This means that tags also become cheap if there is no exporter and cleans up the
mess with how spans, tags and logs were related.
Also fixes the currently broken metrics that relied on the span tags.

Change-Id: I8e56b6218a60fd31a1f6c8d329dbb2cab1b9254d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/222065
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Ian Cottrell 2020-03-04 16:41:57 -05:00
parent 95d2e580d8
commit 32f14692fc
6 changed files with 39 additions and 38 deletions

View File

@ -554,6 +554,7 @@ func (e *exporter) ProcessEvent(ctx context.Context, event telemetry.Event) cont
if i == nil {
return ctx
}
ctx = export.Tag(ctx, event)
if i.ocagent != nil {
ctx = i.ocagent.ProcessEvent(ctx, event)
}

View File

@ -15,6 +15,7 @@ const (
EventLog = EventType(iota)
EventStartSpan
EventEndSpan
EventTag
)
type Event struct {

View File

@ -11,7 +11,6 @@ import (
"context"
"os"
"sync/atomic"
"time"
"unsafe"
"golang.org/x/tools/internal/telemetry"
@ -42,28 +41,6 @@ func SetExporter(e Exporter) {
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 {

View File

@ -0,0 +1,25 @@
// 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
import (
"context"
"golang.org/x/tools/internal/telemetry"
)
// Tag returns a context updated with tag values from the event.
// It ignores events that are not or type EventTag or EventStartSpan.
func Tag(ctx context.Context, event telemetry.Event) context.Context {
//TODO: Do we need to do something more efficient than just store tags
//TODO: directly on the context?
switch event.Type {
case telemetry.EventTag, telemetry.EventStartSpan:
for _, t := range event.Tags {
ctx = context.WithValue(ctx, t.Key, t.Value)
}
}
return ctx
}

View File

@ -41,9 +41,14 @@ func GetSpan(ctx context.Context) *Span {
return v.(*Span)
}
// ContextSpan is an exporter that maintains hierarchical span structure in the
// context.
// It creates new spans on EventStartSpan, adds events to the current span on
// EventLog or EventTag, and closes the span on EventEndSpan.
// The span structure can then be used by other exporters.
func ContextSpan(ctx context.Context, event telemetry.Event) context.Context {
switch event.Type {
case telemetry.EventLog:
case telemetry.EventLog, telemetry.EventTag:
if span := GetSpan(ctx); span != nil {
span.Events = append(span.Events, event)
}

View File

@ -15,21 +15,13 @@ import (
"golang.org/x/tools/internal/telemetry/export"
)
//TODO: Do we need to do something more efficient than just store tags
//TODO: directly on the context?
// With is roughly equivalent to context.WithValue except that it also notifies
// registered observers.
// Unlike WithValue, it takes a list of tags so that you can set many values
// at once if needed. Each call to With results in one invocation of each
// observer.
// With delivers the tag list to the telemetry exporter.
func With(ctx context.Context, tags ...telemetry.Tag) context.Context {
at := time.Now()
for _, t := range tags {
ctx = context.WithValue(ctx, t.Key, t.Value)
}
export.Tag(ctx, at, tags)
return ctx
return export.ProcessEvent(ctx, telemetry.Event{
Type: telemetry.EventTag,
At: time.Now(),
Tags: tags,
})
}
// Get collects a set of values from the context and returns them as a tag list.