Esempio n. 1
0
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
}
Esempio n. 2
0
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)
}
Esempio n. 3
0
func (t *TestAggregator) Add(in telegraf.Metric) {
	for _, v := range in.Fields() {
		if vi, ok := v.(int64); ok {
			atomic.AddInt64(&t.sum, vi)
		}
	}
}
Esempio n. 4
0
// 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)
			}
		}
	}
}
Esempio n. 5
0
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
}
Esempio n. 6
0
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
}
Esempio n. 7
0
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
}
Esempio n. 8
0
// 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...)
		}
	}
}
Esempio n. 9
0
// 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++
		}
	}
}
Esempio n. 10
0
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
	}
}
Esempio n. 11
0
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
}
Esempio n. 12
0
// 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
}
Esempio n. 13
0
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
				}
			}
		}
	}
}
Esempio n. 14
0
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
}
Esempio n. 15
0
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
}
Esempio n. 16
0
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
}
Esempio n. 17
0
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
}
Esempio n. 18
0
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
}
Esempio n. 19
0
// 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)
		}
	}
}
Esempio n. 20
0
// 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
}
Esempio n. 21
0
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
}
Esempio n. 22
0
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
}
Esempio n. 23
0
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
}
Esempio n. 24
0
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
}
Esempio n. 25
0
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
}
Esempio n. 26
0
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
}
Esempio n. 27
0
func (s *InfluxSerializer) Serialize(metric telegraf.Metric) ([]string, error) {
	return []string{metric.String()}, nil
}
Esempio n. 28
0
// 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
}
Esempio n. 29
0
func (f *Filter) ShouldMetricPass(metric telegraf.Metric) bool {
	if f.ShouldNamePass(metric.Name()) && f.ShouldTagsPass(metric.Tags()) {
		return true
	}
	return false
}