Add date offset and timezone options to date processor (#6886)
This commit is contained in:
		
							parent
							
								
									5f2ed4ce4f
								
							
						
					
					
						commit
						e8c4efb572
					
				|  | @ -6,6 +6,9 @@ | |||
|   renamed to `sqlserver_azure_db_resource_stats` due to an issue where numeric | ||||
|   metrics were previously being reported incorrectly as strings. | ||||
| 
 | ||||
| - The `date` processor now uses the UTC timezone when creating its tag.  In | ||||
|   previous versions the local time was used. | ||||
| 
 | ||||
| #### New Outputs | ||||
| 
 | ||||
| - [warp10](/plugins/outputs/warp10/README.md) - Contributed by @aurrelhebert | ||||
|  |  | |||
|  | @ -19,6 +19,23 @@ A few example usecases include: | |||
|   ## Date format string, must be a representation of the Go "reference time" | ||||
|   ## which is "Mon Jan 2 15:04:05 -0700 MST 2006". | ||||
|   date_format = "Jan" | ||||
| 
 | ||||
|   ## Offset duration added to the date string when writing the new tag. | ||||
|   # date_offset = "0s" | ||||
| 
 | ||||
|   ## Timezone to use when generating the date.  This can be set to one of | ||||
|   ## "Local", "UTC", or to a location name in the IANA Time Zone database. | ||||
|   ##   example: timezone = "America/Los_Angeles" | ||||
|   # timezone = "UTC" | ||||
| ``` | ||||
| 
 | ||||
| #### timezone | ||||
| 
 | ||||
| On Windows, only the `Local` and `UTC` zones are available by default.  To use | ||||
| other timezones, set the `ZONEINFO` environment variable to the location of | ||||
| [`zoneinfo.zip`][zoneinfo]: | ||||
| ``` | ||||
| set ZONEINFO=C:\zoneinfo.zip | ||||
| ``` | ||||
| 
 | ||||
| ### Example | ||||
|  | @ -27,3 +44,5 @@ A few example usecases include: | |||
| - throughput lower=10i,upper=1000i,mean=500i 1560540094000000000 | ||||
| + throughput,month=Jun lower=10i,upper=1000i,mean=500i 1560540094000000000 | ||||
| ``` | ||||
| 
 | ||||
| [zoneinfo]: https://github.com/golang/go/raw/50bd1c4d4eb4fac8ddeb5f063c099daccfb71b26/lib/time/zoneinfo.zip | ||||
|  |  | |||
|  | @ -1,7 +1,10 @@ | |||
| package date | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/influxdata/telegraf" | ||||
| 	"github.com/influxdata/telegraf/internal" | ||||
| 	"github.com/influxdata/telegraf/plugins/processors" | ||||
| ) | ||||
| 
 | ||||
|  | @ -12,11 +15,25 @@ const sampleConfig = ` | |||
|   ## Date format string, must be a representation of the Go "reference time" | ||||
|   ## which is "Mon Jan 2 15:04:05 -0700 MST 2006". | ||||
|   date_format = "Jan" | ||||
| 
 | ||||
|   ## Offset duration added to the date string when writing the new tag. | ||||
|   # date_offset = "0s" | ||||
| 
 | ||||
|   ## Timezone to use when creating the tag.  This can be set to one of | ||||
|   ## "UTC", "Local", or to a location name in the IANA Time Zone database. | ||||
|   ##   example: timezone = "America/Los_Angeles" | ||||
|   # timezone = "UTC" | ||||
| ` | ||||
| 
 | ||||
| const defaultTimezone = "UTC" | ||||
| 
 | ||||
| type Date struct { | ||||
| 	TagKey     string `toml:"tag_key"` | ||||
| 	DateFormat string `toml:"date_format"` | ||||
| 	TagKey     string            `toml:"tag_key"` | ||||
| 	DateFormat string            `toml:"date_format"` | ||||
| 	DateOffset internal.Duration `toml:"date_offset"` | ||||
| 	Timezone   string            `toml:"timezone"` | ||||
| 
 | ||||
| 	location *time.Location | ||||
| } | ||||
| 
 | ||||
| func (d *Date) SampleConfig() string { | ||||
|  | @ -27,9 +44,17 @@ func (d *Date) Description() string { | |||
| 	return "Dates measurements, tags, and fields that pass through this filter." | ||||
| } | ||||
| 
 | ||||
| func (d *Date) Init() error { | ||||
| 	var err error | ||||
| 	// LoadLocation returns UTC if timezone is the empty string.
 | ||||
| 	d.location, err = time.LoadLocation(d.Timezone) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| func (d *Date) Apply(in ...telegraf.Metric) []telegraf.Metric { | ||||
| 	for _, point := range in { | ||||
| 		point.AddTag(d.TagKey, point.Time().Format(d.DateFormat)) | ||||
| 		tm := point.Time().In(d.location).Add(d.DateOffset.Duration) | ||||
| 		point.AddTag(d.TagKey, tm.Format(d.DateFormat)) | ||||
| 	} | ||||
| 
 | ||||
| 	return in | ||||
|  | @ -37,6 +62,8 @@ func (d *Date) Apply(in ...telegraf.Metric) []telegraf.Metric { | |||
| 
 | ||||
| func init() { | ||||
| 	processors.Add("date", func() telegraf.Processor { | ||||
| 		return &Date{} | ||||
| 		return &Date{ | ||||
| 			Timezone: defaultTimezone, | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  |  | |||
|  | @ -5,8 +5,11 @@ import ( | |||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/influxdata/telegraf" | ||||
| 	"github.com/influxdata/telegraf/internal" | ||||
| 	"github.com/influxdata/telegraf/metric" | ||||
| 	"github.com/influxdata/telegraf/testutil" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
| 
 | ||||
| func MustMetric(name string, tags map[string]string, fields map[string]interface{}, metricTime time.Time) telegraf.Metric { | ||||
|  | @ -25,6 +28,8 @@ func TestMonthTag(t *testing.T) { | |||
| 		TagKey:     "month", | ||||
| 		DateFormat: "Jan", | ||||
| 	} | ||||
| 	err := dateFormatMonth.Init() | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	currentTime := time.Now() | ||||
| 	month := currentTime.Format("Jan") | ||||
|  | @ -43,6 +48,10 @@ func TestYearTag(t *testing.T) { | |||
| 		TagKey:     "year", | ||||
| 		DateFormat: "2006", | ||||
| 	} | ||||
| 
 | ||||
| 	err := dateFormatYear.Init() | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	currentTime := time.Now() | ||||
| 	year := currentTime.Format("2006") | ||||
| 
 | ||||
|  | @ -61,7 +70,46 @@ func TestOldDateTag(t *testing.T) { | |||
| 		DateFormat: "2006", | ||||
| 	} | ||||
| 
 | ||||
| 	err := dateFormatYear.Init() | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	m7 := MustMetric("foo", nil, nil, time.Date(1993, 05, 27, 0, 0, 0, 0, time.UTC)) | ||||
| 	customDateApply := dateFormatYear.Apply(m7) | ||||
| 	assert.Equal(t, map[string]string{"year": "1993"}, customDateApply[0].Tags(), "should add tag 'year'") | ||||
| } | ||||
| 
 | ||||
| func TestDateOffset(t *testing.T) { | ||||
| 	plugin := &Date{ | ||||
| 		TagKey:     "hour", | ||||
| 		DateFormat: "15", | ||||
| 		DateOffset: internal.Duration{Duration: 2 * time.Hour}, | ||||
| 	} | ||||
| 
 | ||||
| 	err := plugin.Init() | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	metric := testutil.MustMetric( | ||||
| 		"cpu", | ||||
| 		map[string]string{}, | ||||
| 		map[string]interface{}{ | ||||
| 			"time_idle": 42.0, | ||||
| 		}, | ||||
| 		time.Unix(1578603600, 0), | ||||
| 	) | ||||
| 
 | ||||
| 	expected := []telegraf.Metric{ | ||||
| 		testutil.MustMetric( | ||||
| 			"cpu", | ||||
| 			map[string]string{ | ||||
| 				"hour": "23", | ||||
| 			}, | ||||
| 			map[string]interface{}{ | ||||
| 				"time_idle": 42.0, | ||||
| 			}, | ||||
| 			time.Unix(1578603600, 0), | ||||
| 		), | ||||
| 	} | ||||
| 
 | ||||
| 	actual := plugin.Apply(metric) | ||||
| 	testutil.RequireMetricsEqual(t, expected, actual) | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue