diff --git a/README.md b/README.md index b656be4738..7d64c8643d 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ timex | Exposes selected adjtimex(2) system call stats. | Linux udp_queues | Exposes UDP total lengths of the rx_queue and tx_queue from `/proc/net/udp` and `/proc/net/udp6`. | Linux uname | Exposes system information as provided by the uname system call. | Darwin, FreeBSD, Linux, OpenBSD vmstat | Exposes statistics from `/proc/vmstat`. | Linux +xfrm | Exposes statistics from `/proc/net/xfrm_stat` | Linux xfs | Exposes XFS runtime statistics. | Linux (kernel 4.4+) zfs | Exposes [ZFS](http://open-zfs.org/) performance statistics. | FreeBSD, [Linux](http://zfsonlinux.org/), Solaris diff --git a/collector/fixtures/e2e-64k-page-output.txt b/collector/fixtures/e2e-64k-page-output.txt index 866db45f6f..a6cb1082db 100644 --- a/collector/fixtures/e2e-64k-page-output.txt +++ b/collector/fixtures/e2e-64k-page-output.txt @@ -2944,6 +2944,7 @@ node_scrape_collector_success{collector="time"} 1 node_scrape_collector_success{collector="udp_queues"} 1 node_scrape_collector_success{collector="vmstat"} 1 node_scrape_collector_success{collector="wifi"} 1 +node_scrape_collector_success{collector="xfrm"} 1 node_scrape_collector_success{collector="xfs"} 1 node_scrape_collector_success{collector="zfs"} 1 node_scrape_collector_success{collector="zoneinfo"} 1 @@ -3265,6 +3266,90 @@ node_wifi_station_transmit_failed_total{device="wlan0",mac_address="aa:bb:cc:dd: # TYPE node_wifi_station_transmit_retries_total counter node_wifi_station_transmit_retries_total{device="wlan0",mac_address="01:02:03:04:05:06"} 20 node_wifi_station_transmit_retries_total{device="wlan0",mac_address="aa:bb:cc:dd:ee:ff"} 10 +# HELP node_xfrm_acquire_error_total State hasn’t been fully acquired before use +# TYPE node_xfrm_acquire_error_total counter +node_xfrm_acquire_error_total 24532 +# HELP node_xfrm_fwd_hdr_error_total Forward routing of a packet is not allowed +# TYPE node_xfrm_fwd_hdr_error_total counter +node_xfrm_fwd_hdr_error_total 6654 +# HELP node_xfrm_in_buffer_error_total No buffer is left +# TYPE node_xfrm_in_buffer_error_total counter +node_xfrm_in_buffer_error_total 2 +# HELP node_xfrm_in_error_total All errors not matched by other +# TYPE node_xfrm_in_error_total counter +node_xfrm_in_error_total 1 +# HELP node_xfrm_in_hdr_error_total Header error +# TYPE node_xfrm_in_hdr_error_total counter +node_xfrm_in_hdr_error_total 4 +# HELP node_xfrm_in_no_pols_total No policy is found for states e.g. Inbound SAs are correct but no SP is found +# TYPE node_xfrm_in_no_pols_total counter +node_xfrm_in_no_pols_total 65432 +# HELP node_xfrm_in_no_states_total No state is found i.e. Either inbound SPI, address, or IPsec protocol at SA is wrong +# TYPE node_xfrm_in_no_states_total counter +node_xfrm_in_no_states_total 3 +# HELP node_xfrm_in_pol_block_total Policy discards +# TYPE node_xfrm_in_pol_block_total counter +node_xfrm_in_pol_block_total 100 +# HELP node_xfrm_in_pol_error_total Policy error +# TYPE node_xfrm_in_pol_error_total counter +node_xfrm_in_pol_error_total 10000 +# HELP node_xfrm_in_state_expired_total State is expired +# TYPE node_xfrm_in_state_expired_total counter +node_xfrm_in_state_expired_total 7 +# HELP node_xfrm_in_state_invalid_total State is invalid +# TYPE node_xfrm_in_state_invalid_total counter +node_xfrm_in_state_invalid_total 55555 +# HELP node_xfrm_in_state_mismatch_total State has mismatch option e.g. UDP encapsulation type is mismatch +# TYPE node_xfrm_in_state_mismatch_total counter +node_xfrm_in_state_mismatch_total 23451 +# HELP node_xfrm_in_state_mode_error_total Transformation mode specific error +# TYPE node_xfrm_in_state_mode_error_total counter +node_xfrm_in_state_mode_error_total 100 +# HELP node_xfrm_in_state_proto_error_total Transformation protocol specific error e.g. SA key is wrong +# TYPE node_xfrm_in_state_proto_error_total counter +node_xfrm_in_state_proto_error_total 40 +# HELP node_xfrm_in_state_seq_error_total Sequence error i.e. Sequence number is out of window +# TYPE node_xfrm_in_state_seq_error_total counter +node_xfrm_in_state_seq_error_total 6000 +# HELP node_xfrm_in_tmpl_mismatch_total No matching template for states e.g. Inbound SAs are correct but SP rule is wrong +# TYPE node_xfrm_in_tmpl_mismatch_total counter +node_xfrm_in_tmpl_mismatch_total 51 +# HELP node_xfrm_out_bundle_check_error_total Bundle check error +# TYPE node_xfrm_out_bundle_check_error_total counter +node_xfrm_out_bundle_check_error_total 555 +# HELP node_xfrm_out_bundle_gen_error_total Bundle generation error +# TYPE node_xfrm_out_bundle_gen_error_total counter +node_xfrm_out_bundle_gen_error_total 43321 +# HELP node_xfrm_out_error_total All errors which is not matched others +# TYPE node_xfrm_out_error_total counter +node_xfrm_out_error_total 1e+06 +# HELP node_xfrm_out_no_states_total No state is found +# TYPE node_xfrm_out_no_states_total counter +node_xfrm_out_no_states_total 869 +# HELP node_xfrm_out_pol_block_total Policy discards +# TYPE node_xfrm_out_pol_block_total counter +node_xfrm_out_pol_block_total 43456 +# HELP node_xfrm_out_pol_dead_total Policy is dead +# TYPE node_xfrm_out_pol_dead_total counter +node_xfrm_out_pol_dead_total 7656 +# HELP node_xfrm_out_pol_error_total Policy error +# TYPE node_xfrm_out_pol_error_total counter +node_xfrm_out_pol_error_total 1454 +# HELP node_xfrm_out_state_expired_total State is expired +# TYPE node_xfrm_out_state_expired_total counter +node_xfrm_out_state_expired_total 565 +# HELP node_xfrm_out_state_invalid_total State is invalid, perhaps expired +# TYPE node_xfrm_out_state_invalid_total counter +node_xfrm_out_state_invalid_total 28765 +# HELP node_xfrm_out_state_mode_error_total Transformation mode specific error +# TYPE node_xfrm_out_state_mode_error_total counter +node_xfrm_out_state_mode_error_total 8 +# HELP node_xfrm_out_state_proto_error_total Transformation protocol specific error +# TYPE node_xfrm_out_state_proto_error_total counter +node_xfrm_out_state_proto_error_total 4542 +# HELP node_xfrm_out_state_seq_error_total Sequence error i.e. Sequence number overflow +# TYPE node_xfrm_out_state_seq_error_total counter +node_xfrm_out_state_seq_error_total 543 # HELP node_xfs_allocation_btree_compares_total Number of allocation B-tree compares for a filesystem. # TYPE node_xfs_allocation_btree_compares_total counter node_xfs_allocation_btree_compares_total{device="sda1"} 0 diff --git a/collector/fixtures/e2e-output.txt b/collector/fixtures/e2e-output.txt index 0c5356d4fb..45a33d1018 100644 --- a/collector/fixtures/e2e-output.txt +++ b/collector/fixtures/e2e-output.txt @@ -2966,6 +2966,7 @@ node_scrape_collector_success{collector="time"} 1 node_scrape_collector_success{collector="udp_queues"} 1 node_scrape_collector_success{collector="vmstat"} 1 node_scrape_collector_success{collector="wifi"} 1 +node_scrape_collector_success{collector="xfrm"} 1 node_scrape_collector_success{collector="xfs"} 1 node_scrape_collector_success{collector="zfs"} 1 node_scrape_collector_success{collector="zoneinfo"} 1 @@ -3287,6 +3288,90 @@ node_wifi_station_transmit_failed_total{device="wlan0",mac_address="aa:bb:cc:dd: # TYPE node_wifi_station_transmit_retries_total counter node_wifi_station_transmit_retries_total{device="wlan0",mac_address="01:02:03:04:05:06"} 20 node_wifi_station_transmit_retries_total{device="wlan0",mac_address="aa:bb:cc:dd:ee:ff"} 10 +# HELP node_xfrm_acquire_error_total State hasn’t been fully acquired before use +# TYPE node_xfrm_acquire_error_total counter +node_xfrm_acquire_error_total 24532 +# HELP node_xfrm_fwd_hdr_error_total Forward routing of a packet is not allowed +# TYPE node_xfrm_fwd_hdr_error_total counter +node_xfrm_fwd_hdr_error_total 6654 +# HELP node_xfrm_in_buffer_error_total No buffer is left +# TYPE node_xfrm_in_buffer_error_total counter +node_xfrm_in_buffer_error_total 2 +# HELP node_xfrm_in_error_total All errors not matched by other +# TYPE node_xfrm_in_error_total counter +node_xfrm_in_error_total 1 +# HELP node_xfrm_in_hdr_error_total Header error +# TYPE node_xfrm_in_hdr_error_total counter +node_xfrm_in_hdr_error_total 4 +# HELP node_xfrm_in_no_pols_total No policy is found for states e.g. Inbound SAs are correct but no SP is found +# TYPE node_xfrm_in_no_pols_total counter +node_xfrm_in_no_pols_total 65432 +# HELP node_xfrm_in_no_states_total No state is found i.e. Either inbound SPI, address, or IPsec protocol at SA is wrong +# TYPE node_xfrm_in_no_states_total counter +node_xfrm_in_no_states_total 3 +# HELP node_xfrm_in_pol_block_total Policy discards +# TYPE node_xfrm_in_pol_block_total counter +node_xfrm_in_pol_block_total 100 +# HELP node_xfrm_in_pol_error_total Policy error +# TYPE node_xfrm_in_pol_error_total counter +node_xfrm_in_pol_error_total 10000 +# HELP node_xfrm_in_state_expired_total State is expired +# TYPE node_xfrm_in_state_expired_total counter +node_xfrm_in_state_expired_total 7 +# HELP node_xfrm_in_state_invalid_total State is invalid +# TYPE node_xfrm_in_state_invalid_total counter +node_xfrm_in_state_invalid_total 55555 +# HELP node_xfrm_in_state_mismatch_total State has mismatch option e.g. UDP encapsulation type is mismatch +# TYPE node_xfrm_in_state_mismatch_total counter +node_xfrm_in_state_mismatch_total 23451 +# HELP node_xfrm_in_state_mode_error_total Transformation mode specific error +# TYPE node_xfrm_in_state_mode_error_total counter +node_xfrm_in_state_mode_error_total 100 +# HELP node_xfrm_in_state_proto_error_total Transformation protocol specific error e.g. SA key is wrong +# TYPE node_xfrm_in_state_proto_error_total counter +node_xfrm_in_state_proto_error_total 40 +# HELP node_xfrm_in_state_seq_error_total Sequence error i.e. Sequence number is out of window +# TYPE node_xfrm_in_state_seq_error_total counter +node_xfrm_in_state_seq_error_total 6000 +# HELP node_xfrm_in_tmpl_mismatch_total No matching template for states e.g. Inbound SAs are correct but SP rule is wrong +# TYPE node_xfrm_in_tmpl_mismatch_total counter +node_xfrm_in_tmpl_mismatch_total 51 +# HELP node_xfrm_out_bundle_check_error_total Bundle check error +# TYPE node_xfrm_out_bundle_check_error_total counter +node_xfrm_out_bundle_check_error_total 555 +# HELP node_xfrm_out_bundle_gen_error_total Bundle generation error +# TYPE node_xfrm_out_bundle_gen_error_total counter +node_xfrm_out_bundle_gen_error_total 43321 +# HELP node_xfrm_out_error_total All errors which is not matched others +# TYPE node_xfrm_out_error_total counter +node_xfrm_out_error_total 1e+06 +# HELP node_xfrm_out_no_states_total No state is found +# TYPE node_xfrm_out_no_states_total counter +node_xfrm_out_no_states_total 869 +# HELP node_xfrm_out_pol_block_total Policy discards +# TYPE node_xfrm_out_pol_block_total counter +node_xfrm_out_pol_block_total 43456 +# HELP node_xfrm_out_pol_dead_total Policy is dead +# TYPE node_xfrm_out_pol_dead_total counter +node_xfrm_out_pol_dead_total 7656 +# HELP node_xfrm_out_pol_error_total Policy error +# TYPE node_xfrm_out_pol_error_total counter +node_xfrm_out_pol_error_total 1454 +# HELP node_xfrm_out_state_expired_total State is expired +# TYPE node_xfrm_out_state_expired_total counter +node_xfrm_out_state_expired_total 565 +# HELP node_xfrm_out_state_invalid_total State is invalid, perhaps expired +# TYPE node_xfrm_out_state_invalid_total counter +node_xfrm_out_state_invalid_total 28765 +# HELP node_xfrm_out_state_mode_error_total Transformation mode specific error +# TYPE node_xfrm_out_state_mode_error_total counter +node_xfrm_out_state_mode_error_total 8 +# HELP node_xfrm_out_state_proto_error_total Transformation protocol specific error +# TYPE node_xfrm_out_state_proto_error_total counter +node_xfrm_out_state_proto_error_total 4542 +# HELP node_xfrm_out_state_seq_error_total Sequence error i.e. Sequence number overflow +# TYPE node_xfrm_out_state_seq_error_total counter +node_xfrm_out_state_seq_error_total 543 # HELP node_xfs_allocation_btree_compares_total Number of allocation B-tree compares for a filesystem. # TYPE node_xfs_allocation_btree_compares_total counter node_xfs_allocation_btree_compares_total{device="sda1"} 0 diff --git a/collector/fixtures/proc/net/xfrm_stat b/collector/fixtures/proc/net/xfrm_stat new file mode 100644 index 0000000000..970c3e4ded --- /dev/null +++ b/collector/fixtures/proc/net/xfrm_stat @@ -0,0 +1,28 @@ +XfrmInError 1 +XfrmInBufferError 2 +XfrmInHdrError 4 +XfrmInNoStates 3 +XfrmInStateProtoError 40 +XfrmInStateModeError 100 +XfrmInStateSeqError 6000 +XfrmInStateExpired 7 +XfrmInStateMismatch 23451 +XfrmInStateInvalid 55555 +XfrmInTmplMismatch 51 +XfrmInNoPols 65432 +XfrmInPolBlock 100 +XfrmInPolError 10000 +XfrmOutError 1000000 +XfrmOutBundleGenError 43321 +XfrmOutBundleCheckError 555 +XfrmOutNoStates 869 +XfrmOutStateProtoError 4542 +XfrmOutStateModeError 8 +XfrmOutStateSeqError 543 +XfrmOutStateExpired 565 +XfrmOutPolBlock 43456 +XfrmOutPolDead 7656 +XfrmOutPolError 1454 +XfrmFwdHdrError 6654 +XfrmOutStateInvalid 28765 +XfrmAcquireError 24532 \ No newline at end of file diff --git a/collector/xfrm.go b/collector/xfrm.go new file mode 100644 index 0000000000..db6c37d7e5 --- /dev/null +++ b/collector/xfrm.go @@ -0,0 +1,253 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !noxfrm +// +build !noxfrm + +package collector + +import ( + "fmt" + + "github.com/go-kit/log" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/procfs" +) + +type xfrmCollector struct { + fs procfs.FS + inError *prometheus.Desc + inBufferError *prometheus.Desc + inHdrError *prometheus.Desc + inNoStates *prometheus.Desc + inStateProtoError *prometheus.Desc + inStateModeError *prometheus.Desc + inStateSeqError *prometheus.Desc + inStateExpired *prometheus.Desc + inStateMismatch *prometheus.Desc + inStateInvalid *prometheus.Desc + inTmplMismatch *prometheus.Desc + inNoPols *prometheus.Desc + inPolBlock *prometheus.Desc + inPolError *prometheus.Desc + outError *prometheus.Desc + outBundleGenError *prometheus.Desc + outBundleCheckError *prometheus.Desc + outNoStates *prometheus.Desc + outStateProtoError *prometheus.Desc + outStateModeError *prometheus.Desc + outStateSeqError *prometheus.Desc + outStateExpired *prometheus.Desc + outPolBlock *prometheus.Desc + outPolDead *prometheus.Desc + outPolError *prometheus.Desc + fwdHdrError *prometheus.Desc + outStateInvalid *prometheus.Desc + acquireError *prometheus.Desc + logger log.Logger +} + +func init() { + registerCollector("xfrm", defaultEnabled, NewXfrmCollector) +} + +// NewXfrmCollector returns a new Collector exposing XFRM stats. +func NewXfrmCollector(logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*procPath) + if err != nil { + return nil, fmt.Errorf("failed to open procfs: %w", err) + } + + return &xfrmCollector{ + fs: fs, + logger: logger, + inError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_error_total"), + "All errors not matched by other", + nil, nil, + ), + inBufferError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_buffer_error_total"), + "No buffer is left", + nil, nil, + ), + inHdrError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_hdr_error_total"), + "Header error", + nil, nil, + ), + inNoStates: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_no_states_total"), + "No state is found i.e. Either inbound SPI, address, or IPsec protocol at SA is wrong", + nil, nil, + ), + inStateProtoError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_state_proto_error_total"), + "Transformation protocol specific error e.g. SA key is wrong", + nil, nil, + ), + inStateModeError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_state_mode_error_total"), + "Transformation mode specific error", + nil, nil, + ), + inStateSeqError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_state_seq_error_total"), + "Sequence error i.e. Sequence number is out of window", + nil, nil, + ), + inStateExpired: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_state_expired_total"), + "State is expired", + nil, nil, + ), + inStateMismatch: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_state_mismatch_total"), + "State has mismatch option e.g. UDP encapsulation type is mismatch", + nil, nil, + ), + inStateInvalid: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_state_invalid_total"), + "State is invalid", + nil, nil, + ), + inTmplMismatch: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_tmpl_mismatch_total"), + "No matching template for states e.g. Inbound SAs are correct but SP rule is wrong", + nil, nil, + ), + inNoPols: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_no_pols_total"), + "No policy is found for states e.g. Inbound SAs are correct but no SP is found", + nil, nil, + ), + inPolBlock: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_pol_block_total"), + "Policy discards", + nil, nil, + ), + inPolError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "in_pol_error_total"), + "Policy error", + nil, nil, + ), + outError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_error_total"), + "All errors which is not matched others", + nil, nil, + ), + outBundleGenError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_bundle_gen_error_total"), + "Bundle generation error", + nil, nil, + ), + outBundleCheckError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_bundle_check_error_total"), + "Bundle check error", + nil, nil, + ), + outNoStates: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_no_states_total"), + "No state is found", + nil, nil, + ), + outStateProtoError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_state_proto_error_total"), + "Transformation protocol specific error", + nil, nil, + ), + outStateModeError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_state_mode_error_total"), + "Transformation mode specific error", + nil, nil, + ), + outStateSeqError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_state_seq_error_total"), + "Sequence error i.e. Sequence number overflow", + nil, nil, + ), + outStateExpired: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_state_expired_total"), + "State is expired", + nil, nil, + ), + outPolBlock: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_pol_block_total"), + "Policy discards", + nil, nil, + ), + outPolDead: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_pol_dead_total"), + "Policy is dead", + nil, nil, + ), + outPolError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_pol_error_total"), + "Policy error", + nil, nil, + ), + fwdHdrError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "fwd_hdr_error_total"), + "Forward routing of a packet is not allowed", + nil, nil, + ), + outStateInvalid: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "out_state_invalid_total"), + "State is invalid, perhaps expired", + nil, nil, + ), + acquireError: prometheus.NewDesc( + prometheus.BuildFQName(namespace, "xfrm", "acquire_error_total"), + "State hasn’t been fully acquired before use", + nil, nil, + ), + }, nil +} + +func (c *xfrmCollector) Update(ch chan<- prometheus.Metric) error { + stat, err := c.fs.NewXfrmStat() + if err != nil { + return err + } + + ch <- prometheus.MustNewConstMetric(c.inError, prometheus.CounterValue, float64(stat.XfrmInError)) + ch <- prometheus.MustNewConstMetric(c.inBufferError, prometheus.CounterValue, float64(stat.XfrmInBufferError)) + ch <- prometheus.MustNewConstMetric(c.inHdrError, prometheus.CounterValue, float64(stat.XfrmInHdrError)) + ch <- prometheus.MustNewConstMetric(c.inNoStates, prometheus.CounterValue, float64(stat.XfrmInNoStates)) + ch <- prometheus.MustNewConstMetric(c.inStateProtoError, prometheus.CounterValue, float64(stat.XfrmInStateProtoError)) + ch <- prometheus.MustNewConstMetric(c.inStateModeError, prometheus.CounterValue, float64(stat.XfrmInStateModeError)) + ch <- prometheus.MustNewConstMetric(c.inStateSeqError, prometheus.CounterValue, float64(stat.XfrmInStateSeqError)) + ch <- prometheus.MustNewConstMetric(c.inStateExpired, prometheus.CounterValue, float64(stat.XfrmInStateExpired)) + ch <- prometheus.MustNewConstMetric(c.inStateMismatch, prometheus.CounterValue, float64(stat.XfrmInStateMismatch)) + ch <- prometheus.MustNewConstMetric(c.inStateInvalid, prometheus.CounterValue, float64(stat.XfrmInStateInvalid)) + ch <- prometheus.MustNewConstMetric(c.inTmplMismatch, prometheus.CounterValue, float64(stat.XfrmInTmplMismatch)) + ch <- prometheus.MustNewConstMetric(c.inNoPols, prometheus.CounterValue, float64(stat.XfrmInNoPols)) + ch <- prometheus.MustNewConstMetric(c.inPolBlock, prometheus.CounterValue, float64(stat.XfrmInPolBlock)) + ch <- prometheus.MustNewConstMetric(c.inPolError, prometheus.CounterValue, float64(stat.XfrmInPolError)) + ch <- prometheus.MustNewConstMetric(c.outError, prometheus.CounterValue, float64(stat.XfrmOutError)) + ch <- prometheus.MustNewConstMetric(c.outBundleGenError, prometheus.CounterValue, float64(stat.XfrmOutBundleGenError)) + ch <- prometheus.MustNewConstMetric(c.outBundleCheckError, prometheus.CounterValue, float64(stat.XfrmOutBundleCheckError)) + ch <- prometheus.MustNewConstMetric(c.outNoStates, prometheus.CounterValue, float64(stat.XfrmOutNoStates)) + ch <- prometheus.MustNewConstMetric(c.outStateProtoError, prometheus.CounterValue, float64(stat.XfrmOutStateProtoError)) + ch <- prometheus.MustNewConstMetric(c.outStateModeError, prometheus.CounterValue, float64(stat.XfrmOutStateModeError)) + ch <- prometheus.MustNewConstMetric(c.outStateSeqError, prometheus.CounterValue, float64(stat.XfrmOutStateSeqError)) + ch <- prometheus.MustNewConstMetric(c.outStateExpired, prometheus.CounterValue, float64(stat.XfrmOutStateExpired)) + ch <- prometheus.MustNewConstMetric(c.outPolBlock, prometheus.CounterValue, float64(stat.XfrmOutPolBlock)) + ch <- prometheus.MustNewConstMetric(c.outPolDead, prometheus.CounterValue, float64(stat.XfrmOutPolDead)) + ch <- prometheus.MustNewConstMetric(c.outPolError, prometheus.CounterValue, float64(stat.XfrmOutPolError)) + ch <- prometheus.MustNewConstMetric(c.fwdHdrError, prometheus.CounterValue, float64(stat.XfrmFwdHdrError)) + ch <- prometheus.MustNewConstMetric(c.outStateInvalid, prometheus.CounterValue, float64(stat.XfrmOutStateInvalid)) + ch <- prometheus.MustNewConstMetric(c.acquireError, prometheus.CounterValue, float64(stat.XfrmAcquireError)) + + return err +} diff --git a/collector/xfrm_test.go b/collector/xfrm_test.go new file mode 100644 index 0000000000..744a8c3405 --- /dev/null +++ b/collector/xfrm_test.go @@ -0,0 +1,151 @@ +// Copyright 2023 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !noxfrm +// +build !noxfrm + +package collector + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/go-kit/log" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil" +) + +type testXfrmCollector struct { + xc Collector +} + +func (c testXfrmCollector) Collect(ch chan<- prometheus.Metric) { + c.xc.Update(ch) +} + +func (c testXfrmCollector) Describe(ch chan<- *prometheus.Desc) { + prometheus.DescribeByCollect(c, ch) +} + +func TestXfrmStats(t *testing.T) { + testcase := `# HELP node_xfrm_acquire_error_total State hasn’t been fully acquired before use + # TYPE node_xfrm_acquire_error_total counter + node_xfrm_acquire_error_total 24532 + # HELP node_xfrm_fwd_hdr_error_total Forward routing of a packet is not allowed + # TYPE node_xfrm_fwd_hdr_error_total counter + node_xfrm_fwd_hdr_error_total 6654 + # HELP node_xfrm_in_buffer_error_total No buffer is left + # TYPE node_xfrm_in_buffer_error_total counter + node_xfrm_in_buffer_error_total 2 + # HELP node_xfrm_in_error_total All errors not matched by other + # TYPE node_xfrm_in_error_total counter + node_xfrm_in_error_total 1 + # HELP node_xfrm_in_hdr_error_total Header error + # TYPE node_xfrm_in_hdr_error_total counter + node_xfrm_in_hdr_error_total 4 + # HELP node_xfrm_in_no_pols_total No policy is found for states e.g. Inbound SAs are correct but no SP is found + # TYPE node_xfrm_in_no_pols_total counter + node_xfrm_in_no_pols_total 65432 + # HELP node_xfrm_in_no_states_total No state is found i.e. Either inbound SPI, address, or IPsec protocol at SA is wrong + # TYPE node_xfrm_in_no_states_total counter + node_xfrm_in_no_states_total 3 + # HELP node_xfrm_in_pol_block_total Policy discards + # TYPE node_xfrm_in_pol_block_total counter + node_xfrm_in_pol_block_total 100 + # HELP node_xfrm_in_pol_error_total Policy error + # TYPE node_xfrm_in_pol_error_total counter + node_xfrm_in_pol_error_total 10000 + # HELP node_xfrm_in_state_expired_total State is expired + # TYPE node_xfrm_in_state_expired_total counter + node_xfrm_in_state_expired_total 7 + # HELP node_xfrm_in_state_invalid_total State is invalid + # TYPE node_xfrm_in_state_invalid_total counter + node_xfrm_in_state_invalid_total 55555 + # HELP node_xfrm_in_state_mismatch_total State has mismatch option e.g. UDP encapsulation type is mismatch + # TYPE node_xfrm_in_state_mismatch_total counter + node_xfrm_in_state_mismatch_total 23451 + # HELP node_xfrm_in_state_mode_error_total Transformation mode specific error + # TYPE node_xfrm_in_state_mode_error_total counter + node_xfrm_in_state_mode_error_total 100 + # HELP node_xfrm_in_state_proto_error_total Transformation protocol specific error e.g. SA key is wrong + # TYPE node_xfrm_in_state_proto_error_total counter + node_xfrm_in_state_proto_error_total 40 + # HELP node_xfrm_in_state_seq_error_total Sequence error i.e. Sequence number is out of window + # TYPE node_xfrm_in_state_seq_error_total counter + node_xfrm_in_state_seq_error_total 6000 + # HELP node_xfrm_in_tmpl_mismatch_total No matching template for states e.g. Inbound SAs are correct but SP rule is wrong + # TYPE node_xfrm_in_tmpl_mismatch_total counter + node_xfrm_in_tmpl_mismatch_total 51 + # HELP node_xfrm_out_bundle_check_error_total Bundle check error + # TYPE node_xfrm_out_bundle_check_error_total counter + node_xfrm_out_bundle_check_error_total 555 + # HELP node_xfrm_out_bundle_gen_error_total Bundle generation error + # TYPE node_xfrm_out_bundle_gen_error_total counter + node_xfrm_out_bundle_gen_error_total 43321 + # HELP node_xfrm_out_error_total All errors which is not matched others + # TYPE node_xfrm_out_error_total counter + node_xfrm_out_error_total 1e+06 + # HELP node_xfrm_out_no_states_total No state is found + # TYPE node_xfrm_out_no_states_total counter + node_xfrm_out_no_states_total 869 + # HELP node_xfrm_out_pol_block_total Policy discards + # TYPE node_xfrm_out_pol_block_total counter + node_xfrm_out_pol_block_total 43456 + # HELP node_xfrm_out_pol_dead_total Policy is dead + # TYPE node_xfrm_out_pol_dead_total counter + node_xfrm_out_pol_dead_total 7656 + # HELP node_xfrm_out_pol_error_total Policy error + # TYPE node_xfrm_out_pol_error_total counter + node_xfrm_out_pol_error_total 1454 + # HELP node_xfrm_out_state_expired_total State is expired + # TYPE node_xfrm_out_state_expired_total counter + node_xfrm_out_state_expired_total 565 + # HELP node_xfrm_out_state_invalid_total State is invalid, perhaps expired + # TYPE node_xfrm_out_state_invalid_total counter + node_xfrm_out_state_invalid_total 28765 + # HELP node_xfrm_out_state_mode_error_total Transformation mode specific error + # TYPE node_xfrm_out_state_mode_error_total counter + node_xfrm_out_state_mode_error_total 8 + # HELP node_xfrm_out_state_proto_error_total Transformation protocol specific error + # TYPE node_xfrm_out_state_proto_error_total counter + node_xfrm_out_state_proto_error_total 4542 + # HELP node_xfrm_out_state_seq_error_total Sequence error i.e. Sequence number overflow + # TYPE node_xfrm_out_state_seq_error_total counter + node_xfrm_out_state_seq_error_total 543 + ` + *procPath = "fixtures/proc" + + logger := log.NewLogfmtLogger(os.Stderr) + c, err := NewXfrmCollector(logger) + if err != nil { + t.Fatal(err) + } + reg := prometheus.NewRegistry() + reg.MustRegister(&testXfrmCollector{xc: c}) + + sink := make(chan prometheus.Metric) + go func() { + err = c.Update(sink) + if err != nil { + panic(fmt.Errorf("failed to update collector: %s", err)) + } + close(sink) + }() + + err = testutil.GatherAndCompare(reg, strings.NewReader(testcase)) + if err != nil { + t.Fatal(err) + } +} diff --git a/end-to-end-test.sh b/end-to-end-test.sh index c0b9d67af2..46d52603e7 100755 --- a/end-to-end-test.sh +++ b/end-to-end-test.sh @@ -51,6 +51,7 @@ enabled_collectors=$(cat << COLLECTORS udp_queues vmstat wifi + xfrm xfs zfs zoneinfo