-
Notifications
You must be signed in to change notification settings - Fork 5.7k
feat(inputs.timex): Add plugin #17831
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 7 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
275e802
Add new input plugin timex
HappyTobi c309c3d
Add comments and feedback
HappyTobi f085ca2
Update plugins/inputs/timex/README.md
HappyTobi 3dd9370
Add feedback
HappyTobi f4ff0dd
Add feedback and ci-issues
HappyTobi 723bcf1
Update test
HappyTobi 456441f
Update nonlinux test
HappyTobi 8c8a741
Add feedback
HappyTobi e02a237
Update test
HappyTobi 517191c
Add feedback
HappyTobi cb7dc0a
Update readme text
HappyTobi ad5a91e
Add feedback
HappyTobi 98fb163
Add feedback
HappyTobi 7339f5f
Add feedback
HappyTobi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or 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 || inputs || inputs.timex | ||
|
|
||
| package all | ||
|
|
||
| import _ "github.com/influxdata/telegraf/plugins/inputs/timex" // register plugin |
This file contains hidden or 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,63 @@ | ||
| # Timex Input Plugin | ||
|
|
||
| This plugin gathers metrics on system time using the Linux Kernel [adjtimex syscall][timex]. | ||
|
|
||
| The call gets the information of the kernel time variables that are controlled | ||
| by the ntpd, systemd-timesyncd, chrony or other time synchronization services. | ||
|
|
||
| ⭐ Telegraf v1.37.0 | ||
| 🏷️ hardware, system | ||
| 💻 linux | ||
|
|
||
| [timex]: https://man7.org/linux/man-pages/man2/adjtimex.2.html | ||
|
|
||
| ## 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 | ||
| # Read time metrics from linux timex interface. | ||
| [[inputs.timex]] | ||
| ## No input configuration | ||
| ``` | ||
|
|
||
| ## Metrics | ||
|
|
||
| - timex | ||
| - tags: | ||
| - status (string) - Clock command/status. | ||
| - fields: | ||
| - offset_seconds (int64) - The offset from local and reference clock. | ||
| - frequency (int64) - Local clock frequency offset. | ||
| - maxerror_ns (int64) - The maximum error in nanoseconds. | ||
| - estimated_error_ns (int64) - The estimated error in nanoseconds. | ||
| - loop_time_constant (int64) - Phase-locked loop time constant. | ||
| - tick_ns (int64) - Nanoseconds between clock ticks. | ||
| - pps_frequency_hertz (float) - Pulse-per-second frequency in hertz. | ||
| - pps_jitter_ns (int64) - Pulse-per-second jitter in nanoseconds. | ||
| - pps_shift_seconds (int64) - Pulse-per-second interval duration in | ||
| seconds. | ||
| - pps_stability_hertz (float) - Pulse-per-second stability, average of | ||
| relative. | ||
| - pps_jitter_total (int64) - Pulse-per-second per second count of jitter | ||
| limit. | ||
| - pps_calibration_total (int64) - Pulse-per-second count of calibration | ||
| intervals. | ||
| - pps_error_total (int64) - Pulse-per-second count of calibration errors. | ||
| - pps_stability_exceeded_total (int64) - Pulse-per-second total stability. | ||
| - tai_offset_seconds (int64) - TAI offset in seconds. | ||
| - sync_status (boolean) - Is clock synchronized with a server. | ||
| - status (int) - Clock command/status. | ||
|
|
||
| ## Example Output | ||
|
|
||
| ```text | ||
| timex,host=testvm,status=ok maxerror_ns=1516000i,estimated_error_ns=4000i,tick_ns=10000000i,loop_time_constant=2i,pps_jitter_total=0i,sync_status=true,offset_ns=0i,frequency=885043i,pps_shift_seconds=0i,pps_stability_hertz=0,tai_offset_seconds=37i,status=0i,pps_frequency_hertz=0,pps_jitter_ns=0i,pps_calibration_total=0i,pps_error_total=0i,pps_stability_exceeded_total=0i 1761121800000000000 | ||
| ``` | ||
This file contains hidden or 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,3 @@ | ||
| # Read time metrics from linux timex interface. | ||
| [[inputs.timex]] | ||
| ## No input configuration | ||
HappyTobi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
This file contains hidden or 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,101 @@ | ||
| //go:generate ../../../tools/readme_config_includer/generator | ||
| //go:build linux | ||
|
|
||
| package timex | ||
|
|
||
| import ( | ||
| _ "embed" | ||
| "fmt" | ||
| "time" | ||
|
|
||
| "golang.org/x/sys/unix" | ||
|
|
||
| "github.com/influxdata/telegraf" | ||
| "github.com/influxdata/telegraf/plugins/inputs" | ||
| ) | ||
|
|
||
| //go:embed sample.conf | ||
| var sampleConfig string | ||
|
|
||
| type Timex struct { | ||
| Log telegraf.Logger `toml:"-"` | ||
HappyTobi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| func (*Timex) SampleConfig() string { | ||
| return sampleConfig | ||
| } | ||
|
|
||
| func (*Timex) Gather(acc telegraf.Accumulator) error { | ||
| var timex unix.Timex | ||
| status, err := unix.Adjtimex(&timex) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to get time adjtimex stats: %w", err) | ||
| } | ||
|
|
||
| // Check the return status for clock state | ||
| // https://github.com/torvalds/linux/blob/master/include/uapi/linux/timex.h | ||
| synced := status != unix.TIME_ERROR | ||
srebhan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // https://man7.org/linux/man-pages/man2/adjtimex.2.html | ||
| // Notes for frequency adjustment ppm | ||
| ppm16 := float64(65536 * time.Second / time.Microsecond) | ||
|
|
||
| // https://man7.org/linux/man-pages/man2/adjtimex.2.html | ||
| // validate the status to determine if the time is in nanoseconds or microseconds | ||
| // STA_NANO (0x2000): time is in nanoseconds | ||
| // STA_MICRO (0x4000): time is in microseconds | ||
| multiplier := int64(1000) | ||
| if (timex.Status & unix.STA_NANO) != 0 { | ||
| multiplier = int64(1) | ||
| } | ||
|
|
||
| statusOutput := "" | ||
HappyTobi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| switch status { | ||
| case unix.TIME_OK: | ||
| statusOutput = "ok" | ||
| case unix.TIME_INS: | ||
| statusOutput = "insert" | ||
| case unix.TIME_DEL: | ||
| statusOutput = "delete" | ||
| case unix.TIME_OOP: | ||
| statusOutput = "progress" | ||
| case unix.TIME_WAIT: | ||
| statusOutput = "wait" | ||
| case unix.TIME_ERROR: | ||
| statusOutput = "error" | ||
HappyTobi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| tags := map[string]string{ | ||
| "status": statusOutput, | ||
| } | ||
|
|
||
| fields := map[string]interface{}{ | ||
| "offset_ns": int64(timex.Offset) * multiplier, //nolint:unconvert // Conversion needed for some architectures | ||
| "frequency": timex.Freq, | ||
HappyTobi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| "maxerror_ns": timex.Maxerror * 1000, | ||
| "estimated_error_ns": timex.Esterror * 1000, | ||
| "status": timex.Status, | ||
| "loop_time_constant": timex.Constant, | ||
| "tick_ns": timex.Tick * 1000, | ||
| "pps_frequency_hertz": float64(timex.Ppsfreq) / ppm16, | ||
| "pps_jitter_ns": int64(timex.Jitter) * multiplier, //nolint:unconvert // Conversion needed for some architectures | ||
| "pps_shift_seconds": timex.Shift, | ||
| "pps_stability_hertz": float64(timex.Stabil) / ppm16, | ||
| "pps_jitter_total": timex.Jitcnt, | ||
| "pps_calibration_total": timex.Calcnt, | ||
| "pps_error_total": timex.Errcnt, | ||
| "pps_stability_exceeded_total": timex.Stbcnt, | ||
| "tai_offset_seconds": timex.Tai, | ||
| "sync_status": synced, | ||
HappyTobi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| acc.AddGauge("timex", fields, tags) | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func init() { | ||
| inputs.Add("timex", func() telegraf.Input { | ||
| return &Timex{} | ||
| }) | ||
| } | ||
This file contains hidden or 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,35 @@ | ||
| //go:generate ../../../tools/readme_config_includer/generator | ||
| //go:build !linux | ||
|
|
||
| package timex | ||
|
|
||
| import ( | ||
| _ "embed" | ||
|
|
||
| "github.com/influxdata/telegraf" | ||
| "github.com/influxdata/telegraf/plugins/inputs" | ||
| ) | ||
|
|
||
| //go:embed sample.conf | ||
| var sampleConfig string | ||
|
|
||
| type Timex struct { | ||
| Log telegraf.Logger `toml:"-"` | ||
| } | ||
|
|
||
| func (*Timex) SampleConfig() string { | ||
| return sampleConfig | ||
| } | ||
|
|
||
| func (tx *Timex) Init() error { | ||
| tx.Log.Warn("Current platform is not supported") | ||
| return nil | ||
| } | ||
|
|
||
| func (*Timex) Gather(_ telegraf.Accumulator) error { return nil } | ||
HappyTobi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| func init() { | ||
| inputs.Add("timex", func() telegraf.Input { | ||
| return &Timex{} | ||
| }) | ||
| } | ||
This file contains hidden or 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,59 @@ | ||
| //go:build linux | ||
|
|
||
| package timex | ||
|
|
||
| import ( | ||
| "testing" | ||
| "time" | ||
|
|
||
| "github.com/stretchr/testify/require" | ||
|
|
||
| "github.com/influxdata/telegraf" | ||
| "github.com/influxdata/telegraf/metric" | ||
| "github.com/influxdata/telegraf/testutil" | ||
| ) | ||
|
|
||
| func TestMetricStructure(t *testing.T) { | ||
| plugin := &Timex{ | ||
| Log: &testutil.Logger{}, | ||
| } | ||
|
|
||
| expected := []telegraf.Metric{ | ||
| metric.New( | ||
| "timex", | ||
| map[string]string{ | ||
| "status": "error", | ||
| }, | ||
| map[string]interface{}{ | ||
| "offset_ns": int64(0), | ||
| "frequency": int64(0), | ||
| "maxerror_ns": int64(0), | ||
| "estimated_error_ns": int64(0), | ||
| "status": int32(0), | ||
| "loop_time_constant": int64(0), | ||
| "tick_ns": int64(0), | ||
| "pps_frequency_hertz": float64(0), | ||
| "pps_jitter_ns": int64(0), | ||
| "pps_shift_seconds": int32(0), | ||
| "pps_stability_hertz": float64(0), | ||
| "pps_jitter_total": int64(0), | ||
| "pps_calibration_total": int64(0), | ||
| "pps_error_total": int64(0), | ||
| "pps_stability_exceeded_total": int64(0), | ||
| "tai_offset_seconds": int32(0), | ||
| "sync_status": bool(false), | ||
| }, | ||
| time.Unix(0, 0), | ||
| telegraf.Gauge, | ||
| ), | ||
| } | ||
|
|
||
| var acc testutil.Accumulator | ||
| require.NoError(t, plugin.Gather(&acc)) | ||
| actual := acc.GetTelegrafMetrics() | ||
|
|
||
| testutil.RequireMetricsStructureEqual(t, expected, actual, testutil.IgnoreTime(), testutil.IgnoreTags("status")) | ||
|
|
||
| // validate the status tag separately bacause the value could be different based on the system. | ||
| require.NotEmpty(t, actual[0].Tags()["status"]) | ||
HappyTobi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.