github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/events/events.go (about)

     1  // Copyright 2019 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package events
    16  
    17  import (
    18  	"sync"
    19  	"time"
    20  
    21  	"github.com/golang/protobuf/ptypes"
    22  	"github.com/golang/protobuf/ptypes/timestamp"
    23  	"github.com/google/uuid"
    24  
    25  	eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1"
    26  )
    27  
    28  // EventNowFunc function is used to get the current time and can be overridden for testing.
    29  var EventNowFunc = time.Now
    30  
    31  func nowTimestamp() *timestamp.Timestamp {
    32  	now := EventNowFunc()
    33  	ts, err := ptypes.TimestampProto(now)
    34  
    35  	if err != nil {
    36  		panic(err)
    37  	}
    38  
    39  	return ts
    40  }
    41  
    42  // Event is an event to be added to a collector and logged
    43  type Event struct {
    44  	ce         *eventsapi.ClientEvent
    45  	m          *sync.Mutex
    46  	attributes map[eventsapi.AttributeID]string
    47  }
    48  
    49  // NewEvent creates an Event of a given type.  The event creation time is recorded as the start time for the event.
    50  // When the event is passed to a collector's CloseEventAndAdd method the end time of the event is recorded
    51  func NewEvent(ceType eventsapi.ClientEventType) *Event {
    52  	return &Event{
    53  		ce: &eventsapi.ClientEvent{
    54  			Id:        uuid.New().String(),
    55  			StartTime: nowTimestamp(),
    56  			Type:      ceType,
    57  		},
    58  		m:          &sync.Mutex{},
    59  		attributes: make(map[eventsapi.AttributeID]string),
    60  	}
    61  }
    62  
    63  // AddMetric adds a metric to the event.  This method is thread safe.
    64  func (evt *Event) AddMetric(em EventMetric) {
    65  	evt.m.Lock()
    66  	defer evt.m.Unlock()
    67  
    68  	evt.ce.Metrics = append(evt.ce.Metrics, em.AsClientEventMetric())
    69  }
    70  
    71  // SetAttribute adds an attribute to the event.  This method is thread safe
    72  func (evt *Event) SetAttribute(attID eventsapi.AttributeID, attVal string) {
    73  	evt.m.Lock()
    74  	defer evt.m.Unlock()
    75  
    76  	evt.attributes[attID] = attVal
    77  }
    78  
    79  func (evt *Event) close() *eventsapi.ClientEvent {
    80  	if evt.ce == nil {
    81  		panic("multiple close calls for the same event.")
    82  	}
    83  
    84  	evt.m.Lock()
    85  	defer evt.m.Unlock()
    86  
    87  	evt.ce.EndTime = nowTimestamp()
    88  
    89  	for k, v := range evt.attributes {
    90  		evt.ce.Attributes = append(evt.ce.Attributes, &eventsapi.ClientEventAttribute{Id: k, Value: v})
    91  	}
    92  
    93  	ce := evt.ce
    94  	evt.ce = nil
    95  
    96  	return ce
    97  }