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

     1  // Copyright 2014 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  	"sync"
    20  
    21  	"github.com/golang/glog"
    22  	"github.com/riemann/riemann-go-client"
    23  	riemannCommon "k8s.io/heapster/common/riemann"
    24  	"k8s.io/heapster/metrics/core"
    25  )
    26  
    27  // contains the riemann client, the riemann configuration, and a RWMutex
    28  type RiemannSink struct {
    29  	client riemanngo.Client
    30  	config riemannCommon.RiemannConfig
    31  	sync.RWMutex
    32  }
    33  
    34  // creates a Riemann sink. Returns a riemannSink
    35  func CreateRiemannSink(uri *url.URL) (core.DataSink, error) {
    36  	var sink, err = riemannCommon.CreateRiemannSink(uri)
    37  	if err != nil {
    38  		glog.Warningf("Error creating the Riemann metrics sink: %v", err)
    39  		return nil, err
    40  	}
    41  	rs := &RiemannSink{
    42  		client: sink.Client,
    43  		config: sink.Config,
    44  	}
    45  	return rs, nil
    46  }
    47  
    48  // Return a user-friendly string describing the sink
    49  func (sink *RiemannSink) Name() string {
    50  	return "Riemann Sink"
    51  }
    52  
    53  func (sink *RiemannSink) Stop() {
    54  	// nothing needs to be done.
    55  }
    56  
    57  // Receives a list of riemanngo.Event, the sink, and parameters.
    58  // Creates a new event using the parameters and the sink config, and add it into the Event list.
    59  // Can send events if events is full
    60  // Return the list.
    61  func appendEvent(events []riemanngo.Event, sink *RiemannSink, host, name string, value interface{}, labels map[string]string, timestamp int64) []riemanngo.Event {
    62  	event := riemanngo.Event{
    63  		Time:        timestamp,
    64  		Service:     name,
    65  		Host:        host,
    66  		Description: "",
    67  		Attributes:  labels,
    68  		Metric:      value,
    69  		Ttl:         sink.config.Ttl,
    70  		State:       sink.config.State,
    71  		Tags:        sink.config.Tags,
    72  	}
    73  	// state everywhere
    74  	events = append(events, event)
    75  	if len(events) >= sink.config.BatchSize {
    76  		err := riemannCommon.SendData(sink.client, events)
    77  		if err != nil {
    78  			glog.Warningf("Error sending events to Riemann: %v", err)
    79  			// client will reconnect later
    80  			sink.client = nil
    81  		}
    82  		events = nil
    83  	}
    84  	return events
    85  }
    86  
    87  // ExportData Send a collection of Timeseries to Riemann
    88  func (sink *RiemannSink) ExportData(dataBatch *core.DataBatch) {
    89  	sink.Lock()
    90  	defer sink.Unlock()
    91  
    92  	if sink.client == nil {
    93  		// the client could be nil here, so we reconnect
    94  		client, err := riemannCommon.GetRiemannClient(sink.config)
    95  		if err != nil {
    96  			glog.Warningf("Riemann sink not connected: %v", err)
    97  			return
    98  		}
    99  		sink.client = client
   100  	}
   101  
   102  	var events []riemanngo.Event
   103  
   104  	for _, metricSet := range dataBatch.MetricSets {
   105  		host := metricSet.Labels[core.LabelHostname.Key]
   106  		for metricName, metricValue := range metricSet.MetricValues {
   107  			if value := metricValue.GetValue(); value != nil {
   108  				timestamp := dataBatch.Timestamp.Unix()
   109  				// creates an event and add it to dataEvent
   110  				events = appendEvent(events, sink, host, metricName, value, metricSet.Labels, timestamp)
   111  			}
   112  		}
   113  		for _, metric := range metricSet.LabeledMetrics {
   114  			if value := metric.GetValue(); value != nil {
   115  				labels := make(map[string]string)
   116  				for k, v := range metricSet.Labels {
   117  					labels[k] = v
   118  				}
   119  				for k, v := range metric.Labels {
   120  					labels[k] = v
   121  				}
   122  				timestamp := dataBatch.Timestamp.Unix()
   123  				// creates an event and add it to dataEvent
   124  				events = appendEvent(events, sink, host, metric.Name, value, labels, timestamp)
   125  			}
   126  		}
   127  	}
   128  	// Send events to Riemann if events is not empty
   129  	if len(events) > 0 {
   130  		err := riemannCommon.SendData(sink.client, events)
   131  		if err != nil {
   132  			glog.Warningf("Error sending events to Riemann: %v", err)
   133  			// client will reconnect later
   134  			sink.client = nil
   135  		}
   136  	}
   137  }