github.com/galamsiva2020/kubernetes-heapster-monitoring@v0.0.0-20210823134957-3c1baa7c1e70/events/sinks/riemann/driver.go (about)

     1  // Copyright 2017 Google Inc. All Rights Reserved.
     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 riemann
    16  
    17  import (
    18  	"net/url"
    19  	"strconv"
    20  	"strings"
    21  	"sync"
    22  
    23  	"github.com/golang/glog"
    24  	"github.com/riemann/riemann-go-client"
    25  	kube_api "k8s.io/api/core/v1"
    26  	riemannCommon "k8s.io/heapster/common/riemann"
    27  	"k8s.io/heapster/events/core"
    28  )
    29  
    30  // contains the riemann client, the riemann configuration, and a RWMutex
    31  type RiemannSink struct {
    32  	client riemanngo.Client
    33  	config riemannCommon.RiemannConfig
    34  	sync.RWMutex
    35  }
    36  
    37  // creates a Riemann sink. Returns a riemannSink
    38  func CreateRiemannSink(uri *url.URL) (core.EventSink, error) {
    39  	var sink, err = riemannCommon.CreateRiemannSink(uri)
    40  	if err != nil {
    41  		glog.Warningf("Error creating the Riemann metrics sink: %v", err)
    42  		return nil, err
    43  	}
    44  	rs := &RiemannSink{
    45  		client: sink.Client,
    46  		config: sink.Config,
    47  	}
    48  	return rs, nil
    49  }
    50  
    51  // Return a user-friendly string describing the sink
    52  func (sink *RiemannSink) Name() string {
    53  	return "Riemann Sink"
    54  }
    55  
    56  func (sink *RiemannSink) Stop() {
    57  	sink.client.Close()
    58  }
    59  
    60  func getEventState(event *kube_api.Event) string {
    61  	switch event.Type {
    62  	case "Normal":
    63  		return "ok"
    64  	case "Warning":
    65  		return "warning"
    66  	default:
    67  		return "warning"
    68  	}
    69  }
    70  
    71  func appendEvent(events []riemanngo.Event, sink *RiemannSink, event *kube_api.Event, timestamp int64) []riemanngo.Event {
    72  	firstTimestamp := ""
    73  	lastTimestamp := ""
    74  	if !event.FirstTimestamp.IsZero() {
    75  		firstTimestamp = strconv.FormatInt(event.FirstTimestamp.Unix(), 10)
    76  	}
    77  	if !event.LastTimestamp.IsZero() {
    78  		lastTimestamp = strconv.FormatInt(event.LastTimestamp.Unix(), 10)
    79  	}
    80  	riemannEvent := riemanngo.Event{
    81  		Time:        timestamp,
    82  		Service:     strings.Join([]string{event.InvolvedObject.Kind, event.Reason}, "."),
    83  		Host:        event.Source.Host,
    84  		Description: event.Message,
    85  		Attributes: map[string]string{
    86  			"namespace":        event.InvolvedObject.Namespace,
    87  			"uid":              string(event.InvolvedObject.UID),
    88  			"name":             event.InvolvedObject.Name,
    89  			"api-version":      event.InvolvedObject.APIVersion,
    90  			"resource-version": event.InvolvedObject.ResourceVersion,
    91  			"field-path":       event.InvolvedObject.FieldPath,
    92  			"component":        event.Source.Component,
    93  			"last-timestamp":   lastTimestamp,
    94  			"first-timestamp":  firstTimestamp,
    95  		},
    96  		Metric: event.Count,
    97  		Ttl:    sink.config.Ttl,
    98  		State:  getEventState(event),
    99  		Tags:   sink.config.Tags,
   100  	}
   101  
   102  	events = append(events, riemannEvent)
   103  	if len(events) >= sink.config.BatchSize {
   104  		err := riemannCommon.SendData(sink.client, events)
   105  		if err != nil {
   106  			glog.Warningf("Error sending events to Riemann: %v", err)
   107  			// client will reconnect later
   108  			sink.client = nil
   109  		}
   110  		events = nil
   111  	}
   112  	return events
   113  }
   114  
   115  func (sink *RiemannSink) ExportEvents(eventBatch *core.EventBatch) {
   116  	sink.Lock()
   117  	defer sink.Unlock()
   118  
   119  	if sink.client == nil {
   120  		// the client could be nil here, so we reconnect
   121  		client, err := riemannCommon.GetRiemannClient(sink.config)
   122  		if err != nil {
   123  			glog.Warningf("Riemann sink not connected: %v", err)
   124  			return
   125  		}
   126  		sink.client = client
   127  	}
   128  
   129  	var events []riemanngo.Event
   130  
   131  	for _, event := range eventBatch.Events {
   132  		timestamp := eventBatch.Timestamp.Unix()
   133  		// creates an event and add it to dataEvent
   134  		events = appendEvent(events, sink, event, timestamp)
   135  	}
   136  
   137  	if len(events) > 0 {
   138  		err := riemannCommon.SendData(sink.client, events)
   139  		if err != nil {
   140  			glog.Warningf("Error sending events to Riemann: %v", err)
   141  			// client will reconnect later
   142  			sink.client = nil
   143  		}
   144  		events = nil
   145  	}
   146  }