github.com/aclisp/heapster@v0.19.2-0.20160613100040-51756f899a96/metrics/sinks/elasticsearch/driver.go (about) 1 // Copyright 2015 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 elasticsearch 16 17 import ( 18 "net/url" 19 "sync" 20 "time" 21 22 "github.com/golang/glog" 23 "github.com/olivere/elastic" 24 esCommon "k8s.io/heapster/common/elasticsearch" 25 "k8s.io/heapster/metrics/core" 26 ) 27 28 const ( 29 typeName = "k8s-heapster" 30 ) 31 32 // SaveDataFunc is a pluggable function to enforce limits on the object 33 type SaveDataFunc func(esClient *elastic.Client, indexName string, typeName string, sinkData interface{}) error 34 35 type elasticSearchSink struct { 36 esClient *elastic.Client 37 saveDataFunc SaveDataFunc 38 esConfig esCommon.ElasticSearchConfig 39 sync.RWMutex 40 } 41 42 type EsSinkPoint struct { 43 MetricsName string 44 MetricsValue interface{} 45 MetricsTimestamp time.Time 46 MetricsTags map[string]string 47 } 48 49 func (sink *elasticSearchSink) ExportData(dataBatch *core.DataBatch) { 50 sink.Lock() 51 defer sink.Unlock() 52 for _, metricSet := range dataBatch.MetricSets { 53 for metricName, metricValue := range metricSet.MetricValues { 54 point := EsSinkPoint{ 55 MetricsName: metricName, 56 MetricsTags: metricSet.Labels, 57 MetricsValue: map[string]interface{}{ 58 "value": metricValue.GetValue(), 59 }, 60 MetricsTimestamp: dataBatch.Timestamp.UTC(), 61 } 62 sink.saveDataFunc(sink.esClient, sink.esConfig.Index, typeName, point) 63 } 64 for _, metric := range metricSet.LabeledMetrics { 65 labels := make(map[string]string) 66 for k, v := range metricSet.Labels { 67 labels[k] = v 68 } 69 for k, v := range metric.Labels { 70 labels[k] = v 71 } 72 point := EsSinkPoint{ 73 MetricsName: metric.Name, 74 MetricsTags: labels, 75 MetricsValue: map[string]interface{}{ 76 "value": metric.GetValue(), 77 }, 78 MetricsTimestamp: dataBatch.Timestamp.UTC(), 79 } 80 sink.saveDataFunc(sink.esClient, sink.esConfig.Index, typeName, point) 81 } 82 } 83 } 84 85 func (sink *elasticSearchSink) Name() string { 86 return "ElasticSearch Sink" 87 } 88 89 func (sink *elasticSearchSink) Stop() { 90 // nothing needs to be done. 91 } 92 93 func NewElasticSearchSink(uri *url.URL) (core.DataSink, error) { 94 var esSink elasticSearchSink 95 elasticsearchConfig, err := esCommon.CreateElasticSearchConfig(uri) 96 if err != nil { 97 glog.V(2).Infof("failed to config elasticsearch") 98 return nil, err 99 100 } 101 esSink.esConfig = *elasticsearchConfig 102 esSink.saveDataFunc = esCommon.SaveDataIntoES 103 glog.V(2).Infof("elasticsearch sink setup successfully") 104 return &esSink, nil 105 }