golang.org/x/tools@v0.21.0/internal/event/export/metric/exporter.go (about)

     1  // Copyright 2019 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  // Package metric aggregates events into metrics that can be exported.
     6  package metric
     7  
     8  import (
     9  	"context"
    10  	"sync"
    11  	"time"
    12  
    13  	"golang.org/x/tools/internal/event"
    14  	"golang.org/x/tools/internal/event/core"
    15  	"golang.org/x/tools/internal/event/keys"
    16  	"golang.org/x/tools/internal/event/label"
    17  )
    18  
    19  var Entries = keys.New("metric_entries", "The set of metrics calculated for an event")
    20  
    21  type Config struct {
    22  	subscribers map[interface{}][]subscriber
    23  }
    24  
    25  type subscriber func(time.Time, label.Map, label.Label) Data
    26  
    27  func (e *Config) subscribe(key label.Key, s subscriber) {
    28  	if e.subscribers == nil {
    29  		e.subscribers = make(map[interface{}][]subscriber)
    30  	}
    31  	e.subscribers[key] = append(e.subscribers[key], s)
    32  }
    33  
    34  func (e *Config) Exporter(output event.Exporter) event.Exporter {
    35  	var mu sync.Mutex
    36  	return func(ctx context.Context, ev core.Event, lm label.Map) context.Context {
    37  		if !event.IsMetric(ev) {
    38  			return output(ctx, ev, lm)
    39  		}
    40  		mu.Lock()
    41  		defer mu.Unlock()
    42  		var metrics []Data
    43  		for index := 0; ev.Valid(index); index++ {
    44  			l := ev.Label(index)
    45  			if !l.Valid() {
    46  				continue
    47  			}
    48  			id := l.Key()
    49  			if list := e.subscribers[id]; len(list) > 0 {
    50  				for _, s := range list {
    51  					metrics = append(metrics, s(ev.At(), lm, l))
    52  				}
    53  			}
    54  		}
    55  		lm = label.MergeMaps(label.NewMap(Entries.Of(metrics)), lm)
    56  		return output(ctx, ev, lm)
    57  	}
    58  }