diff options
Diffstat (limited to '')
-rw-r--r-- | src/go/collectors/go.d.plugin/modules/chrony/charts.go | 148 | ||||
-rw-r--r-- | src/go/collectors/go.d.plugin/modules/chrony/client.go | 61 | ||||
-rw-r--r-- | src/go/collectors/go.d.plugin/modules/chrony/collect.go | 97 | ||||
l--------- | src/go/plugin/go.d/modules/chrony/README.md (renamed from src/go/collectors/go.d.plugin/modules/chrony/README.md) | 0 | ||||
-rw-r--r-- | src/go/plugin/go.d/modules/chrony/chrony.go (renamed from src/go/collectors/go.d.plugin/modules/chrony/chrony.go) | 15 | ||||
-rw-r--r-- | src/go/plugin/go.d/modules/chrony/chrony_test.go (renamed from src/go/collectors/go.d.plugin/modules/chrony/chrony_test.go) | 33 | ||||
-rw-r--r-- | src/go/plugin/go.d/modules/chrony/config_schema.json (renamed from src/go/collectors/go.d.plugin/modules/chrony/config_schema.json) | 0 | ||||
-rw-r--r-- | src/go/plugin/go.d/modules/chrony/init.go (renamed from src/go/collectors/go.d.plugin/modules/chrony/init.go) | 0 | ||||
-rw-r--r-- | src/go/plugin/go.d/modules/chrony/integrations/chrony.md (renamed from src/go/collectors/go.d.plugin/modules/chrony/integrations/chrony.md) | 39 | ||||
-rw-r--r-- | src/go/plugin/go.d/modules/chrony/metadata.yaml (renamed from src/go/collectors/go.d.plugin/modules/chrony/metadata.yaml) | 0 | ||||
-rw-r--r-- | src/go/plugin/go.d/modules/chrony/testdata/config.json (renamed from src/go/collectors/go.d.plugin/modules/chrony/testdata/config.json) | 0 | ||||
-rw-r--r-- | src/go/plugin/go.d/modules/chrony/testdata/config.yaml (renamed from src/go/collectors/go.d.plugin/modules/chrony/testdata/config.yaml) | 0 |
12 files changed, 76 insertions, 317 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/chrony/charts.go b/src/go/collectors/go.d.plugin/modules/chrony/charts.go deleted file mode 100644 index 6b8f42897..000000000 --- a/src/go/collectors/go.d.plugin/modules/chrony/charts.go +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -package chrony - -import ( - "github.com/netdata/netdata/go/go.d.plugin/agent/module" -) - -var charts = module.Charts{ - { - ID: "stratum", - Title: "Distance to the reference clock", - Units: "level", - Fam: "stratum", - Ctx: "chrony.stratum", - Dims: module.Dims{ - {ID: "stratum", Name: "stratum"}, - }, - }, - { - ID: "current_correction", - Title: "Current correction", - Units: "seconds", - Fam: "correction", - Ctx: "chrony.current_correction", - Dims: module.Dims{ - {ID: "current_correction", Div: scaleFactor}, - }, - }, - { - ID: "root_delay", - Title: "Network path delay to stratum-1", - Units: "seconds", - Fam: "root", - Ctx: "chrony.root_delay", - Dims: module.Dims{ - {ID: "root_delay", Div: scaleFactor}, - }, - }, - { - ID: "root_dispersion", - Title: "Dispersion accumulated back to stratum-1", - Units: "seconds", - Fam: "root", - Ctx: "chrony.root_dispersion", - Dims: module.Dims{ - {ID: "root_dispersion", Div: scaleFactor}, - }, - }, - { - ID: "last_offset", - Title: "Offset on the last clock update", - Units: "seconds", - Fam: "offset", - Ctx: "chrony.last_offset", - Dims: module.Dims{ - {ID: "last_offset", Name: "offset", Div: scaleFactor}, - }, - }, - { - ID: "rms_offset", - Title: "Long-term average of the offset value", - Units: "seconds", - Fam: "offset", - Ctx: "chrony.rms_offset", - Dims: module.Dims{ - {ID: "rms_offset", Name: "offset", Div: scaleFactor}, - }, - }, - { - ID: "frequency", - Title: "Frequency", - Units: "ppm", - Fam: "frequency", - Ctx: "chrony.frequency", - Dims: module.Dims{ - {ID: "frequency", Div: scaleFactor}, - }, - }, - { - ID: "residual_frequency", - Title: "Residual frequency", - Units: "ppm", - Fam: "frequency", - Ctx: "chrony.residual_frequency", - Dims: module.Dims{ - {ID: "residual_frequency", Div: scaleFactor}, - }, - }, - { - ID: "skew", - Title: "Skew", - Units: "ppm", - Fam: "frequency", - Ctx: "chrony.skew", - Dims: module.Dims{ - {ID: "skew", Div: scaleFactor}, - }, - }, - { - ID: "update_interval", - Title: "Interval between the last two clock updates", - Units: "seconds", - Fam: "updates", - Ctx: "chrony.update_interval", - Dims: module.Dims{ - {ID: "update_interval", Div: scaleFactor}, - }, - }, - { - ID: "ref_measurement_time", - Title: "Time since the last measurement", - Units: "seconds", - Fam: "updates", - Ctx: "chrony.ref_measurement_time", - Dims: module.Dims{ - {ID: "ref_measurement_time"}, - }, - }, - { - ID: "leap_status", - Title: "Leap status", - Units: "status", - Fam: "leap status", - Ctx: "chrony.leap_status", - Dims: module.Dims{ - {ID: "leap_status_normal", Name: "normal"}, - {ID: "leap_status_insert_second", Name: "insert_second"}, - {ID: "leap_status_delete_second", Name: "delete_second"}, - {ID: "leap_status_unsynchronised", Name: "unsynchronised"}, - }, - }, - { - ID: "activity", - Title: "Peers activity", - Units: "sources", - Fam: "activity", - Ctx: "chrony.activity", - Type: module.Stacked, - Dims: module.Dims{ - {ID: "online_sources", Name: "online"}, - {ID: "offline_sources", Name: "offline"}, - {ID: "burst_online_sources", Name: "burst_online"}, - {ID: "burst_offline_sources", Name: "burst_offline"}, - {ID: "unresolved_sources", Name: "unresolved"}, - }, - }, -} diff --git a/src/go/collectors/go.d.plugin/modules/chrony/client.go b/src/go/collectors/go.d.plugin/modules/chrony/client.go deleted file mode 100644 index e850ff239..000000000 --- a/src/go/collectors/go.d.plugin/modules/chrony/client.go +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -package chrony - -import ( - "fmt" - "net" - - "github.com/facebook/time/ntp/chrony" -) - -func newChronyClient(c Config) (chronyClient, error) { - conn, err := net.DialTimeout("udp", c.Address, c.Timeout.Duration()) - if err != nil { - return nil, err - } - - client := &simpleClient{ - conn: conn, - client: &chrony.Client{Connection: conn}, - } - return client, nil -} - -type simpleClient struct { - conn net.Conn - client *chrony.Client -} - -func (sc *simpleClient) Tracking() (*chrony.ReplyTracking, error) { - reply, err := sc.client.Communicate(chrony.NewTrackingPacket()) - if err != nil { - return nil, err - } - - tracking, ok := reply.(*chrony.ReplyTracking) - if !ok { - return nil, fmt.Errorf("unexpected reply type, want=%T, got=%T", &chrony.ReplyTracking{}, reply) - } - return tracking, nil -} - -func (sc *simpleClient) Activity() (*chrony.ReplyActivity, error) { - reply, err := sc.client.Communicate(chrony.NewActivityPacket()) - if err != nil { - return nil, err - } - - activity, ok := reply.(*chrony.ReplyActivity) - if !ok { - return nil, fmt.Errorf("unexpected reply type, want=%T, got=%T", &chrony.ReplyActivity{}, reply) - } - return activity, nil -} - -func (sc *simpleClient) Close() { - if sc.conn != nil { - _ = sc.conn.Close() - sc.conn = nil - } -} diff --git a/src/go/collectors/go.d.plugin/modules/chrony/collect.go b/src/go/collectors/go.d.plugin/modules/chrony/collect.go deleted file mode 100644 index 06a9ecc79..000000000 --- a/src/go/collectors/go.d.plugin/modules/chrony/collect.go +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -package chrony - -import ( - "fmt" - "time" -) - -const scaleFactor = 1000000000 - -func (c *Chrony) collect() (map[string]int64, error) { - if c.client == nil { - client, err := c.newClient(c.Config) - if err != nil { - return nil, err - } - c.client = client - } - - mx := make(map[string]int64) - - if err := c.collectTracking(mx); err != nil { - return nil, err - } - if err := c.collectActivity(mx); err != nil { - return mx, err - } - - return mx, nil -} - -const ( - // https://github.com/mlichvar/chrony/blob/7daf34675a5a2487895c74d1578241ca91a4eb70/ntp.h#L70-L75 - leapStatusNormal = 0 - leapStatusInsertSecond = 1 - leapStatusDeleteSecond = 2 - leapStatusUnsynchronised = 3 -) - -func (c *Chrony) collectTracking(mx map[string]int64) error { - reply, err := c.client.Tracking() - if err != nil { - return fmt.Errorf("error on collecting tracking: %v", err) - } - - mx["stratum"] = int64(reply.Stratum) - mx["leap_status_normal"] = boolToInt(reply.LeapStatus == leapStatusNormal) - mx["leap_status_insert_second"] = boolToInt(reply.LeapStatus == leapStatusInsertSecond) - mx["leap_status_delete_second"] = boolToInt(reply.LeapStatus == leapStatusDeleteSecond) - mx["leap_status_unsynchronised"] = boolToInt(reply.LeapStatus == leapStatusUnsynchronised) - mx["root_delay"] = int64(reply.RootDelay * scaleFactor) - mx["root_dispersion"] = int64(reply.RootDispersion * scaleFactor) - mx["skew"] = int64(reply.SkewPPM * scaleFactor) - mx["last_offset"] = int64(reply.LastOffset * scaleFactor) - mx["rms_offset"] = int64(reply.RMSOffset * scaleFactor) - mx["update_interval"] = int64(reply.LastUpdateInterval * scaleFactor) - // handle chrony restarts - if reply.RefTime.Year() != 1970 { - mx["ref_measurement_time"] = time.Now().Unix() - reply.RefTime.Unix() - } - mx["residual_frequency"] = int64(reply.ResidFreqPPM * scaleFactor) - // https://github.com/mlichvar/chrony/blob/5b04f3ca902e5d10aa5948fb7587d30b43941049/client.c#L1706 - mx["current_correction"] = abs(int64(reply.CurrentCorrection * scaleFactor)) - mx["frequency"] = abs(int64(reply.FreqPPM * scaleFactor)) - - return nil -} - -func (c *Chrony) collectActivity(mx map[string]int64) error { - reply, err := c.client.Activity() - if err != nil { - return fmt.Errorf("error on collecting activity: %v", err) - } - - mx["online_sources"] = int64(reply.Online) - mx["offline_sources"] = int64(reply.Offline) - mx["burst_online_sources"] = int64(reply.BurstOnline) - mx["burst_offline_sources"] = int64(reply.BurstOffline) - mx["unresolved_sources"] = int64(reply.Unresolved) - - return nil -} - -func boolToInt(v bool) int64 { - if v { - return 1 - } - return 0 -} - -func abs(v int64) int64 { - if v < 0 { - return -v - } - return v -} diff --git a/src/go/collectors/go.d.plugin/modules/chrony/README.md b/src/go/plugin/go.d/modules/chrony/README.md index 4a58f3733..4a58f3733 120000 --- a/src/go/collectors/go.d.plugin/modules/chrony/README.md +++ b/src/go/plugin/go.d/modules/chrony/README.md diff --git a/src/go/collectors/go.d.plugin/modules/chrony/chrony.go b/src/go/plugin/go.d/modules/chrony/chrony.go index eb51c4105..0bdd3183c 100644 --- a/src/go/collectors/go.d.plugin/modules/chrony/chrony.go +++ b/src/go/plugin/go.d/modules/chrony/chrony.go @@ -5,11 +5,13 @@ package chrony import ( _ "embed" "errors" + "sync" "time" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module" + "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web" + "github.com/facebook/time/ntp/chrony" - "github.com/netdata/netdata/go/go.d.plugin/agent/module" - "github.com/netdata/netdata/go/go.d.plugin/pkg/web" ) //go:embed "config_schema.json" @@ -29,8 +31,9 @@ func New() *Chrony { Address: "127.0.0.1:323", Timeout: web.Duration(time.Second), }, - charts: charts.Copy(), - newClient: newChronyClient, + charts: charts.Copy(), + addStatsChartsOnce: &sync.Once{}, + newClient: newChronyClient, } } @@ -45,7 +48,8 @@ type ( module.Base Config `yaml:",inline" json:""` - charts *module.Charts + charts *module.Charts + addStatsChartsOnce *sync.Once client chronyClient newClient func(c Config) (chronyClient, error) @@ -53,6 +57,7 @@ type ( chronyClient interface { Tracking() (*chrony.ReplyTracking, error) Activity() (*chrony.ReplyActivity, error) + ServerStats() (*serverStats, error) Close() } ) diff --git a/src/go/collectors/go.d.plugin/modules/chrony/chrony_test.go b/src/go/plugin/go.d/modules/chrony/chrony_test.go index 03e7dd52e..407724e75 100644 --- a/src/go/collectors/go.d.plugin/modules/chrony/chrony_test.go +++ b/src/go/plugin/go.d/modules/chrony/chrony_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/netdata/netdata/go/go.d.plugin/agent/module" + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module" "github.com/facebook/time/ntp/chrony" "github.com/stretchr/testify/assert" @@ -240,9 +240,10 @@ func prepareChronyWithMock(m *mockClient) *Chrony { } type mockClient struct { - errOnTracking bool - errOnActivity bool - closeCalled bool + errOnTracking bool + errOnActivity bool + errOnServerStats bool + closeCalled bool } func (m *mockClient) Tracking() (*chrony.ReplyTracking, error) { @@ -286,6 +287,30 @@ func (m *mockClient) Activity() (*chrony.ReplyActivity, error) { return &reply, nil } +func (m *mockClient) ServerStats() (*serverStats, error) { + if m.errOnServerStats { + return nil, errors.New("mockClient.ServerStats call error") + } + + reply := serverStats{ + v3: &chrony.ServerStats3{ + NTPHits: 10, + NKEHits: 10, + CMDHits: 10, + NTPDrops: 1, + NKEDrops: 1, + CMDDrops: 1, + LogDrops: 1, + NTPAuthHits: 10, + NTPInterleavedHits: 10, + NTPTimestamps: 0, + NTPSpanSeconds: 0, + }, + } + + return &reply, nil +} + func (m *mockClient) Close() { m.closeCalled = true } diff --git a/src/go/collectors/go.d.plugin/modules/chrony/config_schema.json b/src/go/plugin/go.d/modules/chrony/config_schema.json index 5de10a822..5de10a822 100644 --- a/src/go/collectors/go.d.plugin/modules/chrony/config_schema.json +++ b/src/go/plugin/go.d/modules/chrony/config_schema.json diff --git a/src/go/collectors/go.d.plugin/modules/chrony/init.go b/src/go/plugin/go.d/modules/chrony/init.go index 828112c9d..828112c9d 100644 --- a/src/go/collectors/go.d.plugin/modules/chrony/init.go +++ b/src/go/plugin/go.d/modules/chrony/init.go diff --git a/src/go/collectors/go.d.plugin/modules/chrony/integrations/chrony.md b/src/go/plugin/go.d/modules/chrony/integrations/chrony.md index f6c80549f..e9b9454d9 100644 --- a/src/go/collectors/go.d.plugin/modules/chrony/integrations/chrony.md +++ b/src/go/plugin/go.d/modules/chrony/integrations/chrony.md @@ -1,6 +1,6 @@ <!--startmeta -custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/go/collectors/go.d.plugin/modules/chrony/README.md" -meta_yaml: "https://github.com/netdata/netdata/edit/master/src/go/collectors/go.d.plugin/modules/chrony/metadata.yaml" +custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/go/plugin/go.d/modules/chrony/README.md" +meta_yaml: "https://github.com/netdata/netdata/edit/master/src/go/plugin/go.d/modules/chrony/metadata.yaml" sidebar_label: "Chrony" learn_status: "Published" learn_rel_path: "Collecting Metrics/System Clock and NTP" @@ -162,6 +162,8 @@ jobs: ### Debug Mode +**Important**: Debug mode is not supported for data collection jobs created via the UI using the Dyncfg feature. + To troubleshoot issues with the `chrony` collector, run the `go.d.plugin` with the debug option enabled. The output should give you clues as to why the collector isn't working. @@ -184,4 +186,37 @@ should give you clues as to why the collector isn't working. ./go.d.plugin -d -m chrony ``` +### Getting Logs + +If you're encountering problems with the `chrony` collector, follow these steps to retrieve logs and identify potential issues: + +- **Run the command** specific to your system (systemd, non-systemd, or Docker container). +- **Examine the output** for any warnings or error messages that might indicate issues. These messages should provide clues about the root cause of the problem. + +#### System with systemd + +Use the following command to view logs generated since the last Netdata service restart: + +```bash +journalctl _SYSTEMD_INVOCATION_ID="$(systemctl show --value --property=InvocationID netdata)" --namespace=netdata --grep chrony +``` + +#### System without systemd + +Locate the collector log file, typically at `/var/log/netdata/collector.log`, and use `grep` to filter for collector's name: + +```bash +grep chrony /var/log/netdata/collector.log +``` + +**Note**: This method shows logs from all restarts. Focus on the **latest entries** for troubleshooting current issues. + +#### Docker Container + +If your Netdata runs in a Docker container named "netdata" (replace if different), use this command: + +```bash +docker logs netdata 2>&1 | grep chrony +``` + diff --git a/src/go/collectors/go.d.plugin/modules/chrony/metadata.yaml b/src/go/plugin/go.d/modules/chrony/metadata.yaml index 18f9152e6..18f9152e6 100644 --- a/src/go/collectors/go.d.plugin/modules/chrony/metadata.yaml +++ b/src/go/plugin/go.d/modules/chrony/metadata.yaml diff --git a/src/go/collectors/go.d.plugin/modules/chrony/testdata/config.json b/src/go/plugin/go.d/modules/chrony/testdata/config.json index e86834720..e86834720 100644 --- a/src/go/collectors/go.d.plugin/modules/chrony/testdata/config.json +++ b/src/go/plugin/go.d/modules/chrony/testdata/config.json diff --git a/src/go/collectors/go.d.plugin/modules/chrony/testdata/config.yaml b/src/go/plugin/go.d/modules/chrony/testdata/config.yaml index 1b81d09eb..1b81d09eb 100644 --- a/src/go/collectors/go.d.plugin/modules/chrony/testdata/config.yaml +++ b/src/go/plugin/go.d/modules/chrony/testdata/config.yaml |