227 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
package logfmt
 | 
						|
 | 
						|
import (
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/influxdata/telegraf"
 | 
						|
	"github.com/influxdata/telegraf/metric"
 | 
						|
	"github.com/influxdata/telegraf/testutil"
 | 
						|
)
 | 
						|
 | 
						|
func MustMetric(t *testing.T, m *testutil.Metric) telegraf.Metric {
 | 
						|
	t.Helper()
 | 
						|
	v, err := metric.New(m.Measurement, m.Tags, m.Fields, m.Time)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	return v
 | 
						|
}
 | 
						|
 | 
						|
func TestParse(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		name        string
 | 
						|
		measurement string
 | 
						|
		now         func() time.Time
 | 
						|
		bytes       []byte
 | 
						|
		want        []telegraf.Metric
 | 
						|
		wantErr     bool
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name: "no bytes returns no metrics",
 | 
						|
			now:  func() time.Time { return time.Unix(0, 0) },
 | 
						|
			want: []telegraf.Metric{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "test without trailing end",
 | 
						|
			bytes:       []byte("foo=\"bar\""),
 | 
						|
			now:         func() time.Time { return time.Unix(0, 0) },
 | 
						|
			measurement: "testlog",
 | 
						|
			want: []telegraf.Metric{
 | 
						|
				testutil.MustMetric(
 | 
						|
					"testlog",
 | 
						|
					map[string]string{},
 | 
						|
					map[string]interface{}{
 | 
						|
						"foo": "bar",
 | 
						|
					},
 | 
						|
					time.Unix(0, 0),
 | 
						|
				),
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "test with trailing end",
 | 
						|
			bytes:       []byte("foo=\"bar\"\n"),
 | 
						|
			now:         func() time.Time { return time.Unix(0, 0) },
 | 
						|
			measurement: "testlog",
 | 
						|
			want: []telegraf.Metric{
 | 
						|
				testutil.MustMetric(
 | 
						|
					"testlog",
 | 
						|
					map[string]string{},
 | 
						|
					map[string]interface{}{
 | 
						|
						"foo": "bar",
 | 
						|
					},
 | 
						|
					time.Unix(0, 0),
 | 
						|
				),
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "logfmt parser returns all the fields",
 | 
						|
			bytes:       []byte(`ts=2018-07-24T19:43:40.275Z lvl=info msg="http request" method=POST`),
 | 
						|
			now:         func() time.Time { return time.Unix(0, 0) },
 | 
						|
			measurement: "testlog",
 | 
						|
			want: []telegraf.Metric{
 | 
						|
				testutil.MustMetric(
 | 
						|
					"testlog",
 | 
						|
					map[string]string{},
 | 
						|
					map[string]interface{}{
 | 
						|
						"lvl":    "info",
 | 
						|
						"msg":    "http request",
 | 
						|
						"method": "POST",
 | 
						|
						"ts":     "2018-07-24T19:43:40.275Z",
 | 
						|
					},
 | 
						|
					time.Unix(0, 0),
 | 
						|
				),
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "logfmt parser parses every line",
 | 
						|
			bytes:       []byte("ts=2018-07-24T19:43:40.275Z lvl=info msg=\"http request\" method=POST\nparent_id=088876RL000 duration=7.45 log_id=09R4e4Rl000"),
 | 
						|
			now:         func() time.Time { return time.Unix(0, 0) },
 | 
						|
			measurement: "testlog",
 | 
						|
			want: []telegraf.Metric{
 | 
						|
				testutil.MustMetric(
 | 
						|
					"testlog",
 | 
						|
					map[string]string{},
 | 
						|
					map[string]interface{}{
 | 
						|
						"lvl":    "info",
 | 
						|
						"msg":    "http request",
 | 
						|
						"method": "POST",
 | 
						|
						"ts":     "2018-07-24T19:43:40.275Z",
 | 
						|
					},
 | 
						|
					time.Unix(0, 0),
 | 
						|
				),
 | 
						|
				testutil.MustMetric(
 | 
						|
					"testlog",
 | 
						|
					map[string]string{},
 | 
						|
					map[string]interface{}{
 | 
						|
						"parent_id": "088876RL000",
 | 
						|
						"duration":  7.45,
 | 
						|
						"log_id":    "09R4e4Rl000",
 | 
						|
					},
 | 
						|
					time.Unix(0, 0),
 | 
						|
				),
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:    "keys without = or values are ignored",
 | 
						|
			now:     func() time.Time { return time.Unix(0, 0) },
 | 
						|
			bytes:   []byte(`i am no data.`),
 | 
						|
			want:    []telegraf.Metric{},
 | 
						|
			wantErr: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:    "keys without values are ignored",
 | 
						|
			now:     func() time.Time { return time.Unix(0, 0) },
 | 
						|
			bytes:   []byte(`foo="" bar=`),
 | 
						|
			want:    []telegraf.Metric{},
 | 
						|
			wantErr: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "unterminated quote produces error",
 | 
						|
			now:         func() time.Time { return time.Unix(0, 0) },
 | 
						|
			measurement: "testlog",
 | 
						|
			bytes:       []byte(`bar=baz foo="bar`),
 | 
						|
			want:        []telegraf.Metric{},
 | 
						|
			wantErr:     true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "malformed key",
 | 
						|
			now:         func() time.Time { return time.Unix(0, 0) },
 | 
						|
			measurement: "testlog",
 | 
						|
			bytes:       []byte(`"foo=" bar=baz`),
 | 
						|
			want:        []telegraf.Metric{},
 | 
						|
			wantErr:     true,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			l := Parser{
 | 
						|
				MetricName: tt.measurement,
 | 
						|
				Now:        tt.now,
 | 
						|
			}
 | 
						|
			got, err := l.Parse(tt.bytes)
 | 
						|
			if (err != nil) != tt.wantErr {
 | 
						|
				t.Errorf("Logfmt.Parse error = %v, wantErr %v", err, tt.wantErr)
 | 
						|
				return
 | 
						|
			}
 | 
						|
 | 
						|
			testutil.RequireMetricsEqual(t, tt.want, got)
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestParseLine(t *testing.T) {
 | 
						|
	tests := []struct {
 | 
						|
		name        string
 | 
						|
		s           string
 | 
						|
		measurement string
 | 
						|
		now         func() time.Time
 | 
						|
		want        telegraf.Metric
 | 
						|
		wantErr     bool
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			name:    "No Metric In line",
 | 
						|
			now:     func() time.Time { return time.Unix(0, 0) },
 | 
						|
			want:    nil,
 | 
						|
			wantErr: true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "Log parser fmt returns all fields",
 | 
						|
			now:         func() time.Time { return time.Unix(0, 0) },
 | 
						|
			measurement: "testlog",
 | 
						|
			s:           `ts=2018-07-24T19:43:35.207268Z lvl=5 msg="Write failed" log_id=09R4e4Rl000`,
 | 
						|
			want: testutil.MustMetric(
 | 
						|
				"testlog",
 | 
						|
				map[string]string{},
 | 
						|
				map[string]interface{}{
 | 
						|
					"ts":     "2018-07-24T19:43:35.207268Z",
 | 
						|
					"lvl":    int64(5),
 | 
						|
					"msg":    "Write failed",
 | 
						|
					"log_id": "09R4e4Rl000",
 | 
						|
				},
 | 
						|
				time.Unix(0, 0),
 | 
						|
			),
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "ParseLine only returns metrics from first string",
 | 
						|
			now:         func() time.Time { return time.Unix(0, 0) },
 | 
						|
			measurement: "testlog",
 | 
						|
			s:           "ts=2018-07-24T19:43:35.207268Z lvl=5 msg=\"Write failed\" log_id=09R4e4Rl000\nmethod=POST parent_id=088876RL000 duration=7.45 log_id=09R4e4Rl000",
 | 
						|
			want: testutil.MustMetric(
 | 
						|
				"testlog",
 | 
						|
				map[string]string{},
 | 
						|
				map[string]interface{}{
 | 
						|
					"ts":     "2018-07-24T19:43:35.207268Z",
 | 
						|
					"lvl":    int64(5),
 | 
						|
					"msg":    "Write failed",
 | 
						|
					"log_id": "09R4e4Rl000",
 | 
						|
				},
 | 
						|
				time.Unix(0, 0),
 | 
						|
			),
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, tt := range tests {
 | 
						|
		t.Run(tt.name, func(t *testing.T) {
 | 
						|
			l := Parser{
 | 
						|
				MetricName: tt.measurement,
 | 
						|
				Now:        tt.now,
 | 
						|
			}
 | 
						|
			got, err := l.ParseLine(tt.s)
 | 
						|
			if (err != nil) != tt.wantErr {
 | 
						|
				t.Fatalf("Logfmt.Parse error = %v, wantErr %v", err, tt.wantErr)
 | 
						|
			}
 | 
						|
			testutil.RequireMetricEqual(t, tt.want, got)
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |