func (l *Librato) buildGauges(m telegraf.Metric) ([]*Gauge, error) { gauges := []*Gauge{} bucket := graphite.SerializeBucketName(m.Name(), m.Tags(), l.Template, "") for fieldName, value := range m.Fields() { gauge := &Gauge{ Name: graphite.InsertField(bucket, fieldName), MeasureTime: m.Time().Unix(), } if !gauge.verifyValue(value) { continue } if err := gauge.setValue(value); err != nil { return gauges, fmt.Errorf("unable to extract value from Fields, %s\n", err.Error()) } if l.SourceTag != "" { if source, ok := m.Tags()[l.SourceTag]; ok { gauge.Source = source } else { return gauges, fmt.Errorf("undeterminable Source type from Field, %s\n", l.SourceTag) } } gauges = append(gauges, gauge) } if l.Debug { fmt.Printf("[DEBUG] Built gauges: %v\n", gauges) } return gauges, nil }
func buildTags(metric telegraf.Metric) string { var keys []string tags := metric.Tags() for k := range tags { if k == "host" { continue } keys = append(keys, k) } sort.Strings(keys) var tag_str string if host, ok := tags["host"]; ok { if len(keys) > 0 { tag_str = strings.Replace(host, ".", "_", -1) + "." } else { tag_str = strings.Replace(host, ".", "_", -1) } } for i, k := range keys { tag_value := strings.Replace(tags[k], ".", "_", -1) if i == 0 { tag_str += tag_value } else { tag_str += "." + tag_value } } return sanitizedChars.Replace(tag_str) }
func (t *TestAggregator) Add(in telegraf.Metric) { for _, v := range in.Fields() { if vi, ok := v.(int64); ok { atomic.AddInt64(&t.sum, vi) } } }
// parser is launched as a goroutine to watch the l.lines channel. // when a line is available, parser parses it and adds the metric(s) to the // accumulator. func (l *LogParserPlugin) parser() { defer l.wg.Done() var m telegraf.Metric var err error var line string for { select { case <-l.done: return case line = <-l.lines: if line == "" || line == "\n" { continue } } for _, parser := range l.parsers { m, err = parser.ParseLine(line) if err == nil { if m != nil { l.acc.AddFields(m.Name(), m.Fields(), m.Tags(), m.Time()) } } else { log.Printf("Malformed log line in [%s], Error: %s\n", line, err) } } } }
func buildMetrics(m telegraf.Metric) (map[string]Point, error) { ms := make(map[string]Point) for k, v := range m.Fields() { var p Point if err := p.setValue(v); err != nil { return ms, fmt.Errorf("unable to extract value from Fields, %s", err.Error()) } p[0] = float64(m.Time().Unix()) ms[k] = p } return ms, nil }
func serialize(metric telegraf.Metric) ([]string, error) { out := []string{} m := make(map[string]interface{}) m["version"] = "1.1" m["timestamp"] = metric.UnixNano() / 1000000000 m["short_message"] = " " m["name"] = metric.Name() if host, ok := metric.Tags()["host"]; ok { m["host"] = host } else { host, err := os.Hostname() if err != nil { return []string{}, err } m["host"] = host } for key, value := range metric.Fields() { nkey := fmt.Sprintf("_%s", key) m[nkey] = value } serialized, err := ejson.Marshal(m) if err != nil { return []string{}, err } out = append(out, string(serialized)) return out, nil }
func buildEvents(p telegraf.Metric, s string) []*raidman.Event { events := []*raidman.Event{} for fieldName, value := range p.Fields() { host, ok := p.Tags()["host"] if !ok { hostname, err := os.Hostname() if err != nil { host = "unknown" } else { host = hostname } } event := &raidman.Event{ Host: host, Service: serviceName(s, p.Name(), p.Tags(), fieldName), } switch value.(type) { case string: event.State = value.(string) default: event.Metric = value } events = append(events, event) } return events }
// AddMetric adds a metric to the output. This function can also write cached // points if FlushBufferWhenFull is true. func (ro *RunningOutput) AddMetric(metric telegraf.Metric) { if ro.Config.Filter.IsActive { if !ro.Config.Filter.ShouldMetricPass(metric) { return } } // Filter any tagexclude/taginclude parameters before adding metric if len(ro.Config.Filter.TagExclude) != 0 || len(ro.Config.Filter.TagInclude) != 0 { // In order to filter out tags, we need to create a new metric, since // metrics are immutable once created. tags := metric.Tags() fields := metric.Fields() t := metric.Time() name := metric.Name() ro.Config.Filter.FilterTags(tags) // error is not possible if creating from another metric, so ignore. metric, _ = telegraf.NewMetric(name, tags, fields, t) } ro.metrics.Add(metric) if ro.metrics.Len() == ro.MetricBatchSize { batch := ro.metrics.Batch(ro.MetricBatchSize) err := ro.write(batch) if err != nil { ro.failMetrics.Add(batch...) } } }
// AddMetric adds a metric to the output. This function can also write cached // points if FlushBufferWhenFull is true. func (ro *RunningOutput) AddMetric(metric telegraf.Metric) { if ro.Config.Filter.IsActive { if !ro.Config.Filter.ShouldMetricPass(metric) { return } } ro.Lock() defer ro.Unlock() // Filter any tagexclude/taginclude parameters before adding metric if len(ro.Config.Filter.TagExclude) != 0 || len(ro.Config.Filter.TagInclude) != 0 { // In order to filter out tags, we need to create a new metric, since // metrics are immutable once created. tags := metric.Tags() fields := metric.Fields() t := metric.Time() name := metric.Name() ro.Config.Filter.FilterTags(tags) // error is not possible if creating from another metric, so ignore. metric, _ = telegraf.NewMetric(name, tags, fields, t) } if len(ro.metrics) < ro.MetricBufferLimit { ro.metrics = append(ro.metrics, metric) } else { if ro.FlushBufferWhenFull { ro.metrics = append(ro.metrics, metric) tmpmetrics := make([]telegraf.Metric, len(ro.metrics)) copy(tmpmetrics, ro.metrics) ro.metrics = make([]telegraf.Metric, 0) err := ro.write(tmpmetrics) if err != nil { log.Printf("ERROR writing full metric buffer to output %s, %s", ro.Name, err) if len(ro.tmpmetrics) == FULL_METRIC_BUFFERS_LIMIT { ro.mapI = 0 // overwrite one ro.tmpmetrics[ro.mapI] = tmpmetrics ro.mapI++ } else { ro.tmpmetrics[ro.mapI] = tmpmetrics ro.mapI++ } } } else { if ro.overwriteI == 0 { log.Printf("WARNING: overwriting cached metrics, you may want to " + "increase the metric_buffer_limit setting in your [agent] " + "config if you do not wish to overwrite metrics.\n") } if ro.overwriteI == len(ro.metrics) { ro.overwriteI = 0 } ro.metrics[ro.overwriteI] = metric ro.overwriteI++ } } }
func FormatMetric(k *KinesisOutput, point telegraf.Metric) (string, error) { if k.Format == "string" { return point.String(), nil } else { m := fmt.Sprintf("%+v,%+v,%+v", point.Name(), point.Tags(), point.String()) return m, nil } }
func (s *GraphiteSerializer) Serialize(metric telegraf.Metric) ([]string, error) { out := []string{} // Convert UnixNano to Unix timestamps timestamp := metric.UnixNano() / 1000000000 for field_name, value := range metric.Fields() { // Convert value value_str := fmt.Sprintf("%#v", value) // Write graphite metric var graphitePoint string graphitePoint = fmt.Sprintf("%s %s %d", s.SerializeBucketName(metric, field_name), value_str, timestamp) out = append(out, graphitePoint) } return out, nil }
// Make a MetricDatum for each field in a Point. Only fields with values that can be // converted to float64 are supported. Non-supported fields are skipped. func BuildMetricDatum(point telegraf.Metric) []*cloudwatch.MetricDatum { datums := make([]*cloudwatch.MetricDatum, len(point.Fields())) i := 0 var value float64 for k, v := range point.Fields() { switch t := v.(type) { case int: value = float64(t) case int32: value = float64(t) case int64: value = float64(t) case float64: value = t case bool: if t { value = 1 } else { value = 0 } case time.Time: value = float64(t.Unix()) default: // Skip unsupported type. datums = datums[:len(datums)-1] continue } datums[i] = &cloudwatch.MetricDatum{ MetricName: aws.String(strings.Join([]string{point.Name(), k}, "_")), Value: aws.Float64(value), Dimensions: BuildDimensions(point.Tags()), Timestamp: aws.Time(point.Time()), } i += 1 } return datums }
func (m *MinMax) Add(in telegraf.Metric) { id := in.HashID() if _, ok := m.cache[id]; !ok { // hit an uncached metric, create caches for first time: a := aggregate{ name: in.Name(), tags: in.Tags(), fields: make(map[string]minmax), } for k, v := range in.Fields() { if fv, ok := convert(v); ok { a.fields[k] = minmax{ min: fv, max: fv, } } } m.cache[id] = a } else { for k, v := range in.Fields() { if fv, ok := convert(v); ok { if _, ok := m.cache[id].fields[k]; !ok { // hit an uncached field of a cached metric m.cache[id].fields[k] = minmax{ min: fv, max: fv, } continue } if fv < m.cache[id].fields[k].min { tmp := m.cache[id].fields[k] tmp.min = fv m.cache[id].fields[k] = tmp } else if fv > m.cache[id].fields[k].max { tmp := m.cache[id].fields[k] tmp.max = fv m.cache[id].fields[k] = tmp } } } } }
func (s *GraphiteSerializer) Serialize(metric telegraf.Metric) ([]string, error) { out := []string{} // Get name name := metric.Name() // Convert UnixNano to Unix timestamps timestamp := metric.UnixNano() / 1000000000 tag_str := buildTags(metric) for field_name, value := range metric.Fields() { // Convert value value_str := fmt.Sprintf("%#v", value) // Write graphite metric var graphitePoint string if name == field_name { graphitePoint = fmt.Sprintf("%s.%s %s %d", tag_str, strings.Replace(name, ".", "_", -1), value_str, timestamp) } else { graphitePoint = fmt.Sprintf("%s.%s.%s %s %d", tag_str, strings.Replace(name, ".", "_", -1), strings.Replace(field_name, ".", "_", -1), value_str, timestamp) } if s.Prefix != "" { graphitePoint = fmt.Sprintf("%s.%s", s.Prefix, graphitePoint) } out = append(out, graphitePoint) } return out, nil }
func (l *Librato) buildGauges(m telegraf.Metric) ([]*Gauge, error) { gauges := []*Gauge{} for fieldName, value := range m.Fields() { gauge := &Gauge{ Name: l.buildGaugeName(m, fieldName), MeasureTime: m.Time().Unix(), } if err := gauge.setValue(value); err != nil { return gauges, fmt.Errorf("unable to extract value from Fields, %s\n", err.Error()) } if l.SourceTag != "" { if source, ok := m.Tags()[l.SourceTag]; ok { gauge.Source = source } else { return gauges, fmt.Errorf("undeterminable Source type from Field, %s\n", l.SourceTag) } } gauges = append(gauges, gauge) } if l.Debug { fmt.Printf("[DEBUG] Built gauges: %v\n", gauges) } return gauges, nil }
func copyMetric(m telegraf.Metric) telegraf.Metric { t := time.Time(m.Time()) tags := make(map[string]string) fields := make(map[string]interface{}) for k, v := range m.Tags() { tags[k] = v } for k, v := range m.Fields() { fields[k] = v } out, _ := telegraf.NewMetric(m.Name(), tags, fields, t) return out }
func (s *JsonSerializer) Serialize(metric telegraf.Metric) ([]string, error) { out := []string{} m := make(map[string]interface{}) m["tags"] = metric.Tags() m["fields"] = metric.Fields() m["name"] = metric.Name() m["timestamp"] = metric.UnixNano() / 1000000000 serialized, err := ejson.Marshal(m) if err != nil { return []string{}, err } out = append(out, string(serialized)) return out, nil }
func (s *GraphiteSerializer) SerializeBucketName(metric telegraf.Metric, field_name string) string { // Get the metric name name := metric.Name() // Convert UnixNano to Unix timestamps tag_str := buildTags(metric) // Write graphite metric var serializedBucketName string if name == field_name { serializedBucketName = fmt.Sprintf("%s.%s", tag_str, strings.Replace(name, ".", "_", -1)) } else { serializedBucketName = fmt.Sprintf("%s.%s.%s", tag_str, strings.Replace(name, ".", "_", -1), strings.Replace(field_name, ".", "_", -1)) } if s.Prefix != "" { serializedBucketName = fmt.Sprintf("%s.%s", s.Prefix, serializedBucketName) } return serializedBucketName }
// this is launched as a goroutine to continuously watch a tailed logfile // for changes, parse any incoming msgs, and add to the accumulator. func (t *Tail) receiver(tailer *tail.Tail) { defer t.wg.Done() var m telegraf.Metric var err error var line *tail.Line for line = range tailer.Lines { if line.Err != nil { log.Printf("ERROR tailing file %s, Error: %s\n", tailer.Filename, err) continue } m, err = t.parser.ParseLine(line.Text) if err == nil { t.acc.AddFields(m.Name(), m.Fields(), m.Tags(), m.Time()) } else { log.Printf("Malformed log line in %s: [%s], Error: %s\n", tailer.Filename, line.Text, err) } } }
// Add applies the given metric to the aggregator. // Before applying to the plugin, it will run any defined filters on the metric. // Apply returns true if the original metric should be dropped. func (r *RunningAggregator) Add(in telegraf.Metric) bool { if r.Config.Filter.IsActive() { // check if the aggregator should apply this metric name := in.Name() fields := in.Fields() tags := in.Tags() t := in.Time() if ok := r.Config.Filter.Apply(name, fields, tags); !ok { // aggregator should not apply this metric return false } in, _ = telegraf.NewMetric(name, tags, fields, t) } r.metrics <- in return r.Config.DropOriginal }
func (s *GraphiteSerializer) Serialize(metric telegraf.Metric) ([]string, error) { out := []string{} // Convert UnixNano to Unix timestamps timestamp := metric.UnixNano() / 1000000000 bucket := s.SerializeBucketName(metric.Name(), metric.Tags()) for fieldName, value := range metric.Fields() { // Convert value to string valueS := fmt.Sprintf("%#v", value) point := fmt.Sprintf("%s %s %d", // insert "field" section of template InsertField(bucket, fieldName), valueS, timestamp) out = append(out, point) } return out, nil }
func (s *GraphiteSerializer) Serialize(metric telegraf.Metric) ([]string, error) { out := []string{} // Convert UnixNano to Unix timestamps timestamp := metric.UnixNano() / 1000000000 bucket := SerializeBucketName(metric.Name(), metric.Tags(), s.Template, s.Prefix) if bucket == "" { return out, nil } for fieldName, value := range metric.Fields() { // Convert value to string valueS := fmt.Sprintf("%#v", value) point := fmt.Sprintf("%s %s %d", // insert "field" section of template sanitizedChars.Replace(InsertField(bucket, fieldName)), sanitizedChars.Replace(valueS), timestamp) out = append(out, point) } return out, nil }
func (l *Librato) buildGauges(m telegraf.Metric) ([]*Gauge, error) { gauges := []*Gauge{} for fieldName, value := range m.Fields() { gauge := &Gauge{ Name: m.Name() + "_" + fieldName, MeasureTime: m.Time().Unix(), } if err := gauge.setValue(value); err != nil { return gauges, fmt.Errorf("unable to extract value from Fields, %s\n", err.Error()) } if l.SourceTag != "" { if source, ok := m.Tags()[l.SourceTag]; ok { gauge.Source = source } else { return gauges, fmt.Errorf("undeterminable Source type from Field, %s\n", l.SourceTag) } } } return gauges, nil }
func buildMetrics(m telegraf.Metric, now time.Time, prefix string) []*MetricLine { ret := []*MetricLine{} for fieldName, value := range m.Fields() { metric := &MetricLine{ Metric: fmt.Sprintf("%s%s_%s", prefix, m.Name(), fieldName), Timestamp: now.Unix(), } metricValue, buildError := buildValue(value) if buildError != nil { fmt.Printf("OpenTSDB: %s\n", buildError.Error()) continue } metric.Value = metricValue tagsSlice := buildTags(m.Tags()) metric.Tags = fmt.Sprint(strings.Join(tagsSlice, " ")) ret = append(ret, metric) } return ret }
func buildEvents(p telegraf.Metric) []*raidman.Event { events := []*raidman.Event{} for fieldName, value := range p.Fields() { host, ok := p.Tags()["host"] if !ok { hostname, err := os.Hostname() if err != nil { host = "unknown" } else { host = hostname } } event := &raidman.Event{ Host: host, Service: p.Name() + "_" + fieldName, Metric: value, } events = append(events, event) } return events }
func (l *Librato) buildGauges(m telegraf.Metric) ([]*Gauge, error) { gauges := []*Gauge{} if m.Time().Unix() == 0 { return gauges, fmt.Errorf( "Measure time must not be zero\n <%s> \n", m.String()) } metricSource := graphite.InsertField( graphite.SerializeBucketName("", m.Tags(), l.Template, ""), "value") if metricSource == "" { return gauges, fmt.Errorf("undeterminable Source type from Field, %s\n", l.Template) } for fieldName, value := range m.Fields() { metricName := m.Name() if fieldName != "value" { metricName = fmt.Sprintf("%s.%s", m.Name(), fieldName) } gauge := &Gauge{ Source: reUnacceptedChar.ReplaceAllString(metricSource, "-"), Name: reUnacceptedChar.ReplaceAllString(metricName, "-"), MeasureTime: m.Time().Unix(), } if !verifyValue(value) { continue } if err := gauge.setValue(value); err != nil { return gauges, fmt.Errorf( "unable to extract value from Fields, %s\n", err.Error()) } gauges = append(gauges, gauge) } if l.Debug { fmt.Printf("[DEBUG] Built gauges: %v\n", gauges) } return gauges, nil }
func (s *InfluxSerializer) Serialize(metric telegraf.Metric) ([]string, error) { return []string{metric.String()}, nil }
// makeMetric either returns a metric, or returns nil if the metric doesn't // need to be created (because of filtering, an error, etc.) func (ac *accumulator) makeMetric( measurement string, fields map[string]interface{}, tags map[string]string, mType telegraf.ValueType, t ...time.Time, ) telegraf.Metric { if len(fields) == 0 || len(measurement) == 0 { return nil } if tags == nil { tags = make(map[string]string) } // Override measurement name if set if len(ac.inputConfig.NameOverride) != 0 { measurement = ac.inputConfig.NameOverride } // Apply measurement prefix and suffix if set if len(ac.inputConfig.MeasurementPrefix) != 0 { measurement = ac.inputConfig.MeasurementPrefix + measurement } if len(ac.inputConfig.MeasurementSuffix) != 0 { measurement = measurement + ac.inputConfig.MeasurementSuffix } // Apply plugin-wide tags if set for k, v := range ac.inputConfig.Tags { if _, ok := tags[k]; !ok { tags[k] = v } } // Apply daemon-wide tags if set for k, v := range ac.defaultTags { if _, ok := tags[k]; !ok { tags[k] = v } } // Apply the metric filter(s) if ok := ac.inputConfig.Filter.Apply(measurement, fields, tags); !ok { return nil } for k, v := range fields { // Validate uint64 and float64 fields switch val := v.(type) { case uint64: // InfluxDB does not support writing uint64 if val < uint64(9223372036854775808) { fields[k] = int64(val) } else { fields[k] = int64(9223372036854775807) } continue case float64: // NaNs are invalid values in influxdb, skip measurement if math.IsNaN(val) || math.IsInf(val, 0) { if ac.debug { log.Printf("Measurement [%s] field [%s] has a NaN or Inf "+ "field, skipping", measurement, k) } delete(fields, k) continue } } fields[k] = v } var timestamp time.Time if len(t) > 0 { timestamp = t[0] } else { timestamp = time.Now() } timestamp = timestamp.Round(ac.precision) var m telegraf.Metric var err error switch mType { case telegraf.Counter: m, err = telegraf.NewCounterMetric(measurement, tags, fields, timestamp) case telegraf.Gauge: m, err = telegraf.NewGaugeMetric(measurement, tags, fields, timestamp) default: m, err = telegraf.NewMetric(measurement, tags, fields, timestamp) } if err != nil { log.Printf("Error adding point [%s]: %s\n", measurement, err.Error()) return nil } if ac.trace { fmt.Println("> " + m.String()) } return m }
func (f *Filter) ShouldMetricPass(metric telegraf.Metric) bool { if f.ShouldNamePass(metric.Name()) && f.ShouldTagsPass(metric.Tags()) { return true } return false }