-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(processors.timestamp): Introduce timestamp processor (#15094)
- Loading branch information
Showing
5 changed files
with
410 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
//go:build !custom || processors || processors.timestamp | ||
|
||
package all | ||
|
||
import _ "github.com/influxdata/telegraf/plugins/processors/timestamp" // register plugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# Timestamp Processor Plugin | ||
|
||
Use the timestamp processor to parse fields containing timestamps into | ||
timestamps of other formats. | ||
|
||
## Global configuration options <!-- @/docs/includes/plugin_config.md --> | ||
|
||
In addition to the plugin-specific configuration settings, plugins support | ||
additional global and plugin configuration settings. These settings are used to | ||
modify metrics, tags, and field or create aliases and configure ordering, etc. | ||
See the [CONFIGURATION.md][CONFIGURATION.md] for more details. | ||
|
||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins | ||
|
||
## Configuration | ||
|
||
```toml @sample.conf | ||
# Convert a timestamp field to other timestamp format | ||
[[processors.timestamp]] | ||
## Timestamp key to convert | ||
## Specify the field name that contains the timestamp to convert. The result | ||
## will replace the current field value. | ||
field = "" | ||
|
||
## Timestamp Format | ||
## This defines the time layout used to interpret the source timestamp field. | ||
## The time must be `unix`, `unix_ms`, `unix_us`, `unix_ns`, or a time in Go | ||
## "reference time". For more information on Go "reference time". For more | ||
## see: https://golang.org/pkg/time/#Time.Format | ||
source_timestamp_format = "" | ||
|
||
## Timestamp Timezone | ||
## Source timestamp timezone. If not set, assumed to be in UTC. | ||
## Options are as follows: | ||
## 1. UTC -- or unspecified will return timestamp in UTC | ||
## 2. Local -- interpret based on machine localtime | ||
## 3. "America/New_York" -- Unix TZ values like those found in | ||
## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones | ||
# source_timestamp_timezone = "" | ||
|
||
## Target timestamp format | ||
## This defines the destination timestmap format. It also can accept either | ||
## `unix`, `unix_ms`, `unix_us`, `unix_ns`, or a time in Go "reference time". | ||
destination_timestamp_format = "" | ||
|
||
## Target Timestamp Timezone | ||
## Source timestamp timezone. If not set, assumed to be in UTC. | ||
## Options are as follows: | ||
## 1. UTC -- or unspecified will return timestamp in UTC | ||
## 2. Local -- interpret based on machine localtime | ||
## 3. "America/New_York" -- Unix TZ values like those found in | ||
## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones | ||
# destination_timestamp_timezone = "" | ||
``` | ||
|
||
## Example | ||
|
||
Convert a timestamp to unix timestamp: | ||
|
||
```toml | ||
[[processors.timestamp]] | ||
source_timestamp_field = "timestamp" | ||
source_timestamp_format = "2006-01-02T15:04:05.999999999Z" | ||
destination_timestamp_format = "unix" | ||
``` | ||
|
||
```diff | ||
- metric value=42i,timestamp="2024-03-04T10:10:32.123456Z" 1560540094000000000 | ||
+ metric value=42i,timestamp=1709547032 1560540094000000000 | ||
``` | ||
|
||
Convert the same timestamp to a nanosecond unix timestamp: | ||
|
||
```toml | ||
[[processors.timestamp]] | ||
source_timestamp_field = "timestamp" | ||
source_timestamp_format = "2006-01-02T15:04:05.999999999Z" | ||
destination_timestamp_format = "unix_ns" | ||
``` | ||
|
||
```diff | ||
- metric value=42i,timestamp="2024-03-04T10:10:32.123456789Z" 1560540094000000000 | ||
+ metric value=42i,timestamp=1709547032123456789 1560540094000000000 | ||
``` | ||
|
||
Convert the timestamp to another timestamp format: | ||
|
||
```toml | ||
[[processors.timestamp]] | ||
source_timestamp_field = "timestamp" | ||
source_timestamp_format = "2006-01-02T15:04:05.999999999Z" | ||
destination_timestamp_format = "2006-01-02T15:04" | ||
``` | ||
|
||
```diff | ||
- metric value=42i,timestamp="2024-03-04T10:10:32.123456Z" 1560540094000000000 | ||
+ metric value=42i,timestamp="2024-03-04T10:10" 1560540094000000000 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Convert a timestamp field to other timestamp format | ||
[[processors.timestamp]] | ||
## Timestamp key to convert | ||
## Specify the field name that contains the timestamp to convert. The result | ||
## will replace the current field value. | ||
field = "" | ||
|
||
## Timestamp Format | ||
## This defines the time layout used to interpret the source timestamp field. | ||
## The time must be `unix`, `unix_ms`, `unix_us`, `unix_ns`, or a time in Go | ||
## "reference time". For more information on Go "reference time". For more | ||
## see: https://golang.org/pkg/time/#Time.Format | ||
source_timestamp_format = "" | ||
|
||
## Timestamp Timezone | ||
## Source timestamp timezone. If not set, assumed to be in UTC. | ||
## Options are as follows: | ||
## 1. UTC -- or unspecified will return timestamp in UTC | ||
## 2. Local -- interpret based on machine localtime | ||
## 3. "America/New_York" -- Unix TZ values like those found in | ||
## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones | ||
# source_timestamp_timezone = "" | ||
|
||
## Target timestamp format | ||
## This defines the destination timestmap format. It also can accept either | ||
## `unix`, `unix_ms`, `unix_us`, `unix_ns`, or a time in Go "reference time". | ||
destination_timestamp_format = "" | ||
|
||
## Target Timestamp Timezone | ||
## Source timestamp timezone. If not set, assumed to be in UTC. | ||
## Options are as follows: | ||
## 1. UTC -- or unspecified will return timestamp in UTC | ||
## 2. Local -- interpret based on machine localtime | ||
## 3. "America/New_York" -- Unix TZ values like those found in | ||
## https://en.wikipedia.org/wiki/List_of_tz_database_time_zones | ||
# destination_timestamp_timezone = "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//go:generate ../../../tools/readme_config_includer/generator | ||
package timestamp | ||
|
||
import ( | ||
_ "embed" | ||
"errors" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/influxdata/telegraf" | ||
"github.com/influxdata/telegraf/internal" | ||
"github.com/influxdata/telegraf/plugins/processors" | ||
) | ||
|
||
//go:embed sample.conf | ||
var sampleConfig string | ||
|
||
type Timestamp struct { | ||
Field string `toml:"field"` | ||
SourceFormat string `toml:"source_timestamp_format"` | ||
SourceTimezone string `toml:"source_timestamp_timezone"` | ||
DestinationFormat string `toml:"destination_timestamp_format"` | ||
DestinationTimezone string `toml:"destination_timestamp_timezone"` | ||
|
||
sourceLocation *time.Location | ||
destinationLocation *time.Location | ||
} | ||
|
||
func (*Timestamp) SampleConfig() string { | ||
return sampleConfig | ||
} | ||
|
||
func (t *Timestamp) Init() error { | ||
switch t.SourceFormat { | ||
case "": | ||
return errors.New("source_timestamp_format is required") | ||
case "unix", "unix_ms", "unix_us", "unix_ns": | ||
default: | ||
if time.Now().Format(t.SourceFormat) == t.SourceFormat { | ||
return fmt.Errorf("invalid timestamp format %q", t.SourceFormat) | ||
} | ||
} | ||
|
||
switch t.DestinationFormat { | ||
case "": | ||
return errors.New("source_timestamp_format is required") | ||
case "unix", "unix_ms", "unix_us", "unix_ns": | ||
default: | ||
if time.Now().Format(t.DestinationFormat) == t.DestinationFormat { | ||
return fmt.Errorf("invalid timestamp format %q", t.DestinationFormat) | ||
} | ||
} | ||
|
||
if t.SourceTimezone == "" { | ||
t.SourceTimezone = "UTC" | ||
} | ||
|
||
// LoadLocation returns UTC if timezone is the empty string. | ||
var err error | ||
t.sourceLocation, err = time.LoadLocation(t.SourceTimezone) | ||
if err != nil { | ||
return fmt.Errorf("invalid source_timestamp_timezone %q: %w", t.SourceTimezone, err) | ||
} | ||
|
||
if t.DestinationTimezone == "" { | ||
t.DestinationTimezone = "UTC" | ||
} | ||
t.destinationLocation, err = time.LoadLocation(t.DestinationTimezone) | ||
if err != nil { | ||
return fmt.Errorf("invalid source_timestamp_timezone %q: %w", t.DestinationTimezone, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (t *Timestamp) Apply(in ...telegraf.Metric) []telegraf.Metric { | ||
for _, point := range in { | ||
if field, ok := point.GetField(t.Field); ok { | ||
timestamp, err := internal.ParseTimestamp(t.SourceFormat, field, t.sourceLocation) | ||
if err != nil { | ||
continue | ||
} | ||
|
||
switch t.DestinationFormat { | ||
case "unix": | ||
point.AddField(t.Field, timestamp.Unix()) | ||
case "unix_ms": | ||
point.AddField(t.Field, timestamp.UnixNano()/1000000) | ||
case "unix_us": | ||
point.AddField(t.Field, timestamp.UnixNano()/1000) | ||
case "unix_ns": | ||
point.AddField(t.Field, timestamp.UnixNano()) | ||
default: | ||
inLocation := timestamp.In(t.destinationLocation) | ||
point.AddField(t.Field, inLocation.Format(t.DestinationFormat)) | ||
} | ||
} | ||
} | ||
|
||
return in | ||
} | ||
|
||
func init() { | ||
processors.Add("timestamp", func() telegraf.Processor { | ||
return &Timestamp{} | ||
}) | ||
} |
Oops, something went wrong.