Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
418
plugins/inputs/zfs/README.md
Normal file
418
plugins/inputs/zfs/README.md
Normal file
|
@ -0,0 +1,418 @@
|
|||
# ZFS Input Plugin
|
||||
|
||||
This ZFS plugin provides metrics from your ZFS filesystems. It supports ZFS on
|
||||
Linux and FreeBSD. It gets ZFS stat from `/proc/spl/kstat/zfs` on Linux and
|
||||
from `sysctl`, 'zfs' and `zpool` on FreeBSD.
|
||||
|
||||
## 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 metrics of ZFS from arcstats, zfetchstats, vdev_cache_stats, pools and datasets
|
||||
# This plugin ONLY supports Linux & FreeBSD
|
||||
[[inputs.zfs]]
|
||||
## ZFS kstat path. Ignored on FreeBSD
|
||||
## If not specified, then default is:
|
||||
# kstatPath = "/proc/spl/kstat/zfs"
|
||||
|
||||
## By default, telegraf gather all zfs stats
|
||||
## Override the stats list using the kstatMetrics array:
|
||||
## For FreeBSD, the default is:
|
||||
# kstatMetrics = ["arcstats", "zfetchstats", "vdev_cache_stats"]
|
||||
## For Linux, the default is:
|
||||
# kstatMetrics = ["abdstats", "arcstats", "dnodestats", "dbufcachestats",
|
||||
# "dmu_tx", "fm", "vdev_mirror_stats", "zfetchstats", "zil"]
|
||||
|
||||
## By default, don't gather zpool stats
|
||||
# poolMetrics = false
|
||||
|
||||
## By default, don't gather dataset stats
|
||||
# datasetMetrics = false
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
By default this plugin collects metrics about ZFS internals pool and dataset.
|
||||
These metrics are either counters or measure sizes
|
||||
in bytes. These metrics will be in the `zfs` measurement with the field
|
||||
names listed below.
|
||||
|
||||
If `poolMetrics` is enabled then additional metrics will be gathered for
|
||||
each pool.
|
||||
|
||||
If `datasetMetrics` is enabled then additional metrics will be gathered for
|
||||
each dataset.
|
||||
|
||||
- zfs
|
||||
With fields listed below.
|
||||
|
||||
### ARC Stats (FreeBSD and Linux)
|
||||
|
||||
- arcstats_allocated (FreeBSD only)
|
||||
- arcstats_anon_evict_data (Linux only)
|
||||
- arcstats_anon_evict_metadata (Linux only)
|
||||
- arcstats_anon_evictable_data (FreeBSD only)
|
||||
- arcstats_anon_evictable_metadata (FreeBSD only)
|
||||
- arcstats_anon_size
|
||||
- arcstats_arc_loaned_bytes (Linux only)
|
||||
- arcstats_arc_meta_limit
|
||||
- arcstats_arc_meta_max
|
||||
- arcstats_arc_meta_min (FreeBSD only)
|
||||
- arcstats_arc_meta_used
|
||||
- arcstats_arc_no_grow (Linux only)
|
||||
- arcstats_arc_prune (Linux only)
|
||||
- arcstats_arc_tempreserve (Linux only)
|
||||
- arcstats_c
|
||||
- arcstats_c_max
|
||||
- arcstats_c_min
|
||||
- arcstats_data_size
|
||||
- arcstats_deleted
|
||||
- arcstats_demand_data_hits
|
||||
- arcstats_demand_data_misses
|
||||
- arcstats_demand_hit_predictive_prefetch (FreeBSD only)
|
||||
- arcstats_demand_metadata_hits
|
||||
- arcstats_demand_metadata_misses
|
||||
- arcstats_duplicate_buffers
|
||||
- arcstats_duplicate_buffers_size
|
||||
- arcstats_duplicate_reads
|
||||
- arcstats_evict_l2_cached
|
||||
- arcstats_evict_l2_eligible
|
||||
- arcstats_evict_l2_ineligible
|
||||
- arcstats_evict_l2_skip (FreeBSD only)
|
||||
- arcstats_evict_not_enough (FreeBSD only)
|
||||
- arcstats_evict_skip
|
||||
- arcstats_hash_chain_max
|
||||
- arcstats_hash_chains
|
||||
- arcstats_hash_collisions
|
||||
- arcstats_hash_elements
|
||||
- arcstats_hash_elements_max
|
||||
- arcstats_hdr_size
|
||||
- arcstats_hits
|
||||
- arcstats_l2_abort_lowmem
|
||||
- arcstats_l2_asize
|
||||
- arcstats_l2_cdata_free_on_write
|
||||
- arcstats_l2_cksum_bad
|
||||
- arcstats_l2_compress_failures
|
||||
- arcstats_l2_compress_successes
|
||||
- arcstats_l2_compress_zeros
|
||||
- arcstats_l2_evict_l1cached (FreeBSD only)
|
||||
- arcstats_l2_evict_lock_retry
|
||||
- arcstats_l2_evict_reading
|
||||
- arcstats_l2_feeds
|
||||
- arcstats_l2_free_on_write
|
||||
- arcstats_l2_hdr_size
|
||||
- arcstats_l2_hits
|
||||
- arcstats_l2_io_error
|
||||
- arcstats_l2_misses
|
||||
- arcstats_l2_read_bytes
|
||||
- arcstats_l2_rw_clash
|
||||
- arcstats_l2_size
|
||||
- arcstats_l2_write_buffer_bytes_scanned (FreeBSD only)
|
||||
- arcstats_l2_write_buffer_iter (FreeBSD only)
|
||||
- arcstats_l2_write_buffer_list_iter (FreeBSD only)
|
||||
- arcstats_l2_write_buffer_list_null_iter (FreeBSD only)
|
||||
- arcstats_l2_write_bytes
|
||||
- arcstats_l2_write_full (FreeBSD only)
|
||||
- arcstats_l2_write_in_l2 (FreeBSD only)
|
||||
- arcstats_l2_write_io_in_progress (FreeBSD only)
|
||||
- arcstats_l2_write_not_cacheable (FreeBSD only)
|
||||
- arcstats_l2_write_passed_headroom (FreeBSD only)
|
||||
- arcstats_l2_write_pios (FreeBSD only)
|
||||
- arcstats_l2_write_spa_mismatch (FreeBSD only)
|
||||
- arcstats_l2_write_trylock_fail (FreeBSD only)
|
||||
- arcstats_l2_writes_done
|
||||
- arcstats_l2_writes_error
|
||||
- arcstats_l2_writes_hdr_miss (Linux only)
|
||||
- arcstats_l2_writes_lock_retry (FreeBSD only)
|
||||
- arcstats_l2_writes_sent
|
||||
- arcstats_memory_direct_count (Linux only)
|
||||
- arcstats_memory_indirect_count (Linux only)
|
||||
- arcstats_memory_throttle_count
|
||||
- arcstats_meta_size (Linux only)
|
||||
- arcstats_mfu_evict_data (Linux only)
|
||||
- arcstats_mfu_evict_metadata (Linux only)
|
||||
- arcstats_mfu_ghost_evict_data (Linux only)
|
||||
- arcstats_mfu_ghost_evict_metadata (Linux only)
|
||||
- arcstats_metadata_size (FreeBSD only)
|
||||
- arcstats_mfu_evictable_data (FreeBSD only)
|
||||
- arcstats_mfu_evictable_metadata (FreeBSD only)
|
||||
- arcstats_mfu_ghost_evictable_data (FreeBSD only)
|
||||
- arcstats_mfu_ghost_evictable_metadata (FreeBSD only)
|
||||
- arcstats_mfu_ghost_hits
|
||||
- arcstats_mfu_ghost_size
|
||||
- arcstats_mfu_hits
|
||||
- arcstats_mfu_size
|
||||
- arcstats_misses
|
||||
- arcstats_mru_evict_data (Linux only)
|
||||
- arcstats_mru_evict_metadata (Linux only)
|
||||
- arcstats_mru_ghost_evict_data (Linux only)
|
||||
- arcstats_mru_ghost_evict_metadata (Linux only)
|
||||
- arcstats_mru_evictable_data (FreeBSD only)
|
||||
- arcstats_mru_evictable_metadata (FreeBSD only)
|
||||
- arcstats_mru_ghost_evictable_data (FreeBSD only)
|
||||
- arcstats_mru_ghost_evictable_metadata (FreeBSD only)
|
||||
- arcstats_mru_ghost_hits
|
||||
- arcstats_mru_ghost_size
|
||||
- arcstats_mru_hits
|
||||
- arcstats_mru_size
|
||||
- arcstats_mutex_miss
|
||||
- arcstats_other_size
|
||||
- arcstats_p
|
||||
- arcstats_prefetch_data_hits
|
||||
- arcstats_prefetch_data_misses
|
||||
- arcstats_prefetch_metadata_hits
|
||||
- arcstats_prefetch_metadata_misses
|
||||
- arcstats_recycle_miss (Linux only)
|
||||
- arcstats_size
|
||||
- arcstats_sync_wait_for_async (FreeBSD only)
|
||||
|
||||
### Zfetch Stats (FreeBSD and Linux)
|
||||
|
||||
- zfetchstats_bogus_streams (Linux only)
|
||||
- zfetchstats_colinear_hits (Linux only)
|
||||
- zfetchstats_colinear_misses (Linux only)
|
||||
- zfetchstats_hits
|
||||
- zfetchstats_max_streams (FreeBSD only)
|
||||
- zfetchstats_misses
|
||||
- zfetchstats_reclaim_failures (Linux only)
|
||||
- zfetchstats_reclaim_successes (Linux only)
|
||||
- zfetchstats_streams_noresets (Linux only)
|
||||
- zfetchstats_streams_resets (Linux only)
|
||||
- zfetchstats_stride_hits (Linux only)
|
||||
- zfetchstats_stride_misses (Linux only)
|
||||
|
||||
### Vdev Cache Stats (FreeBSD)
|
||||
|
||||
- vdev_cache_stats_delegations
|
||||
- vdev_cache_stats_hits
|
||||
- vdev_cache_stats_misses
|
||||
|
||||
### Pool Metrics (optional)
|
||||
|
||||
On Linux (reference: kstat accumulated time and queue length statistics):
|
||||
|
||||
- zfs_pool
|
||||
- nread (integer, bytes)
|
||||
- nwritten (integer, bytes)
|
||||
- reads (integer, count)
|
||||
- writes (integer, count)
|
||||
- wtime (integer, nanoseconds)
|
||||
- wlentime (integer, queuelength * nanoseconds)
|
||||
- wupdate (integer, timestamp)
|
||||
- rtime (integer, nanoseconds)
|
||||
- rlentime (integer, queuelength * nanoseconds)
|
||||
- rupdate (integer, timestamp)
|
||||
- wcnt (integer, count)
|
||||
- rcnt (integer, count)
|
||||
|
||||
For ZFS >= 2.1.x the format has changed significantly:
|
||||
|
||||
- zfs_pool
|
||||
- writes (integer, count)
|
||||
- nwritten (integer, bytes)
|
||||
- reads (integer, count)
|
||||
- nread (integer, bytes)
|
||||
- nunlinks (integer, count)
|
||||
- nunlinked (integer, count)
|
||||
|
||||
For ZFS >= 2.2.x the following additional fields are available:
|
||||
|
||||
- additional fields for ZFS > 2.2.x
|
||||
- zil_commit_count (integer, count)
|
||||
- zil_commit_writer_count (integer, count)
|
||||
- zil_itx_count (integer, count)
|
||||
- zil_itx_indirect_count (integer, count)
|
||||
- zil_itx_indirect_bytes (integer, bytes)
|
||||
- zil_itx_copied_count (integer, count)
|
||||
- zil_itx_copied_bytes (integer, bytes)
|
||||
- zil_itx_needcopy_count (integer, count)
|
||||
- zil_itx_needcopy_bytes (integer, bytes)
|
||||
- zil_itx_metaslab_normal_count (integer, count)
|
||||
- zil_itx_metaslab_normal_bytes (integer, bytes)
|
||||
- zil_itx_metaslab_normal_write (integer, bytes)
|
||||
- zil_itx_metaslab_normal_alloc (integer, bytes)
|
||||
- zil_itx_metaslab_slog_count (integer, count)
|
||||
- zil_itx_metaslab_slog_bytes (integer, bytes)
|
||||
- zil_itx_metaslab_slog_write (integer, bytes)
|
||||
- zil_itx_metaslab_slog_alloc (integer, bytes)
|
||||
|
||||
On FreeBSD:
|
||||
|
||||
- zfs_pool
|
||||
- allocated (integer, bytes)
|
||||
- capacity (integer, bytes)
|
||||
- dedupratio (float, ratio)
|
||||
- free (integer, bytes)
|
||||
- size (integer, bytes)
|
||||
- fragmentation (integer, percent)
|
||||
|
||||
### Dataset Metrics (optional, only on FreeBSD)
|
||||
|
||||
- zfs_dataset
|
||||
- avail (integer, bytes)
|
||||
- used (integer, bytes)
|
||||
- usedsnap (integer, bytes
|
||||
- usedds (integer, bytes)
|
||||
|
||||
### Tags
|
||||
|
||||
- ZFS stats (`zfs`) will have the following tag:
|
||||
- pools - A `::` concatenated list of all ZFS pools on the machine.
|
||||
- datasets - A `::` concatenated list of all ZFS datasets on the machine.
|
||||
|
||||
- Pool metrics (`zfs_pool`) will have the following tag:
|
||||
- pool - with the name of the pool which the metrics are for.
|
||||
- health - the health status of the pool. (FreeBSD only)
|
||||
- dataset - ZFS >= 2.1.x only. (Linux only)
|
||||
|
||||
- Dataset metrics (`zfs_dataset`) will have the following tag:
|
||||
- dataset - with the name of the dataset which the metrics are for.
|
||||
|
||||
## Example Output
|
||||
|
||||
```text
|
||||
zfs_pool,health=ONLINE,pool=zroot allocated=1578590208i,capacity=2i,dedupratio=1,fragmentation=1i,free=64456531968i,size=66035122176i 1464473103625653908
|
||||
zfs_dataset,dataset=zata avail=10741741326336,used=8564135526400,usedsnap=0,usedds=90112
|
||||
zfs,pools=zroot arcstats_allocated=4167764i,arcstats_anon_evictable_data=0i,arcstats_anon_evictable_metadata=0i,arcstats_anon_size=16896i,arcstats_arc_meta_limit=10485760i,arcstats_arc_meta_max=115269568i,arcstats_arc_meta_min=8388608i,arcstats_arc_meta_used=51977456i,arcstats_c=16777216i,arcstats_c_max=41943040i,arcstats_c_min=16777216i,arcstats_data_size=0i,arcstats_deleted=1699340i,arcstats_demand_data_hits=14836131i,arcstats_demand_data_misses=2842945i,arcstats_demand_hit_predictive_prefetch=0i,arcstats_demand_metadata_hits=1655006i,arcstats_demand_metadata_misses=830074i,arcstats_duplicate_buffers=0i,arcstats_duplicate_buffers_size=0i,arcstats_duplicate_reads=123i,arcstats_evict_l2_cached=0i,arcstats_evict_l2_eligible=332172623872i,arcstats_evict_l2_ineligible=6168576i,arcstats_evict_l2_skip=0i,arcstats_evict_not_enough=12189444i,arcstats_evict_skip=195190764i,arcstats_hash_chain_max=2i,arcstats_hash_chains=10i,arcstats_hash_collisions=43134i,arcstats_hash_elements=2268i,arcstats_hash_elements_max=6136i,arcstats_hdr_size=565632i,arcstats_hits=16515778i,arcstats_l2_abort_lowmem=0i,arcstats_l2_asize=0i,arcstats_l2_cdata_free_on_write=0i,arcstats_l2_cksum_bad=0i,arcstats_l2_compress_failures=0i,arcstats_l2_compress_successes=0i,arcstats_l2_compress_zeros=0i,arcstats_l2_evict_l1cached=0i,arcstats_l2_evict_lock_retry=0i,arcstats_l2_evict_reading=0i,arcstats_l2_feeds=0i,arcstats_l2_free_on_write=0i,arcstats_l2_hdr_size=0i,arcstats_l2_hits=0i,arcstats_l2_io_error=0i,arcstats_l2_misses=0i,arcstats_l2_read_bytes=0i,arcstats_l2_rw_clash=0i,arcstats_l2_size=0i,arcstats_l2_write_buffer_bytes_scanned=0i,arcstats_l2_write_buffer_iter=0i,arcstats_l2_write_buffer_list_iter=0i,arcstats_l2_write_buffer_list_null_iter=0i,arcstats_l2_write_bytes=0i,arcstats_l2_write_full=0i,arcstats_l2_write_in_l2=0i,arcstats_l2_write_io_in_progress=0i,arcstats_l2_write_not_cacheable=380i,arcstats_l2_write_passed_headroom=0i,arcstats_l2_write_pios=0i,arcstats_l2_write_spa_mismatch=0i,arcstats_l2_write_trylock_fail=0i,arcstats_l2_writes_done=0i,arcstats_l2_writes_error=0i,arcstats_l2_writes_lock_retry=0i,arcstats_l2_writes_sent=0i,arcstats_memory_throttle_count=0i,arcstats_metadata_size=17014784i,arcstats_mfu_evictable_data=0i,arcstats_mfu_evictable_metadata=16384i,arcstats_mfu_ghost_evictable_data=5723648i,arcstats_mfu_ghost_evictable_metadata=10709504i,arcstats_mfu_ghost_hits=1315619i,arcstats_mfu_ghost_size=16433152i,arcstats_mfu_hits=7646611i,arcstats_mfu_size=305152i,arcstats_misses=3676993i,arcstats_mru_evictable_data=0i,arcstats_mru_evictable_metadata=0i,arcstats_mru_ghost_evictable_data=0i,arcstats_mru_ghost_evictable_metadata=80896i,arcstats_mru_ghost_hits=324250i,arcstats_mru_ghost_size=80896i,arcstats_mru_hits=8844526i,arcstats_mru_size=16693248i,arcstats_mutex_miss=354023i,arcstats_other_size=34397040i,arcstats_p=4172800i,arcstats_prefetch_data_hits=0i,arcstats_prefetch_data_misses=0i,arcstats_prefetch_metadata_hits=24641i,arcstats_prefetch_metadata_misses=3974i,arcstats_size=51977456i,arcstats_sync_wait_for_async=0i,vdev_cache_stats_delegations=779i,vdev_cache_stats_hits=323123i,vdev_cache_stats_misses=59929i,zfetchstats_hits=0i,zfetchstats_max_streams=0i,zfetchstats_misses=0i 1464473103634124908
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
A short description for some of the metrics.
|
||||
|
||||
### ARC Stats
|
||||
|
||||
`arcstats_hits` Total amount of cache hits in the arc.
|
||||
|
||||
`arcstats_misses` Total amount of cache misses in the arc.
|
||||
|
||||
`arcstats_demand_data_hits` Amount of cache hits for demand data, this is what
|
||||
matters (is good) for your application/share.
|
||||
|
||||
`arcstats_demand_data_misses` Amount of cache misses for demand data, this is
|
||||
what matters (is bad) for your application/share.
|
||||
|
||||
`arcstats_demand_metadata_hits` Amount of cache hits for demand metadata, this
|
||||
matters (is good) for getting filesystem data (ls,find,…)
|
||||
|
||||
`arcstats_demand_metadata_misses` Amount of cache misses for demand metadata,
|
||||
this matters (is bad) for getting filesystem data (ls,find,…)
|
||||
|
||||
`arcstats_prefetch_data_hits` The zfs prefetcher tried to prefetch something,
|
||||
but it was already cached (boring)
|
||||
|
||||
`arcstats_prefetch_data_misses` The zfs prefetcher prefetched something which
|
||||
was not in the cache (good job, could become a demand hit in the future)
|
||||
|
||||
`arcstats_prefetch_metadata_hits` Same as above, but for metadata
|
||||
|
||||
`arcstats_prefetch_metadata_misses` Same as above, but for metadata
|
||||
|
||||
`arcstats_mru_hits` Cache hit in the “most recently used cache”, we move this to
|
||||
the mfu cache.
|
||||
|
||||
`arcstats_mru_ghost_hits` Cache hit in the “most recently used ghost list” we
|
||||
had this item in the cache, but evicted it, maybe we should increase the mru
|
||||
cache size.
|
||||
|
||||
`arcstats_mfu_hits` Cache hit in the “most frequently used cache” we move this
|
||||
to the beginning of the mfu cache.
|
||||
|
||||
`arcstats_mfu_ghost_hits` Cache hit in the “most frequently used ghost list” we
|
||||
had this item in the cache, but evicted it, maybe we should increase the mfu
|
||||
cache size.
|
||||
|
||||
`arcstats_allocated` New data is written to the cache.
|
||||
|
||||
`arcstats_deleted` Old data is evicted (deleted) from the cache.
|
||||
|
||||
`arcstats_evict_l2_cached` We evicted something from the arc, but its still
|
||||
cached in the l2 if we need it.
|
||||
|
||||
`arcstats_evict_l2_eligible` We evicted something from the arc, and it’s not in
|
||||
the l2 this is sad. (maybe we hadn’t had enough time to store it there)
|
||||
|
||||
`arcstats_evict_l2_ineligible` We evicted something which cannot be stored in
|
||||
the l2. Reasons could be:
|
||||
|
||||
- We have multiple pools, we evicted something from a pool without an l2 device.
|
||||
- The zfs property secondary cache.
|
||||
|
||||
`arcstats_c` Arc target size, this is the size the system thinks the arc should
|
||||
have.
|
||||
|
||||
`arcstats_size` Total size of the arc.
|
||||
|
||||
`arcstats_l2_hits` Hits to the L2 cache. (It was not in the arc, but in the l2
|
||||
cache)
|
||||
|
||||
`arcstats_l2_misses` Miss to the L2 cache. (It was not in the arc, and not in
|
||||
the l2 cache)
|
||||
|
||||
`arcstats_l2_size` Size of the l2 cache.
|
||||
|
||||
`arcstats_l2_hdr_size` Size of the metadata in the arc (ram) used to manage
|
||||
(lookup if something is in the l2) the l2 cache.
|
||||
|
||||
### Zfetch Stats
|
||||
|
||||
`zfetchstats_hits` Counts the number of cache hits, to items which are in the
|
||||
cache because of the prefetcher.
|
||||
|
||||
`zfetchstats_misses` Counts the number of prefetch cache misses.
|
||||
|
||||
`zfetchstats_colinear_hits` Counts the number of cache hits, to items which are
|
||||
in the cache because of the prefetcher (prefetched linear reads)
|
||||
|
||||
`zfetchstats_stride_hits` Counts the number of cache hits, to items which are in
|
||||
the cache because of the prefetcher (prefetched stride reads)
|
||||
|
||||
### Vdev Cache Stats (FreeBSD only)
|
||||
|
||||
note: the vdev cache is deprecated in some ZFS implementations
|
||||
|
||||
`vdev_cache_stats_hits` Hits to the vdev (device level) cache.
|
||||
|
||||
`vdev_cache_stats_misses` Misses to the vdev (device level) cache.
|
||||
|
||||
### ABD Stats (Linux Only)
|
||||
|
||||
ABD is a linear/scatter dual typed buffer for ARC
|
||||
|
||||
`abdstats_linear_cnt` number of linear ABDs which are currently allocated
|
||||
|
||||
`abdstats_linear_data_size` amount of data stored in all linear ABDs
|
||||
|
||||
`abdstats_scatter_cnt` number of scatter ABDs which are currently allocated
|
||||
|
||||
`abdstats_scatter_data_size` amount of data stored in all scatter ABDs
|
||||
|
||||
### DMU Stats (Linux Only)
|
||||
|
||||
`dmu_tx_dirty_throttle` counts when writes are throttled due to the amount of
|
||||
dirty data growing too large
|
||||
|
||||
`dmu_tx_memory_reclaim` counts when memory is low and throttling activity
|
||||
|
||||
`dmu_tx_memory_reserve` counts when memory footprint of the txg exceeds the ARC
|
||||
size
|
||||
|
||||
### Fault Management Ereport errors (Linux Only)
|
||||
|
||||
`fm_erpt-dropped` counts when an error report cannot be created (eg available
|
||||
memory is too low)
|
||||
|
||||
### ZIL (Linux Only)
|
||||
|
||||
note: `zil` measurements in `kstatMetrics` are system-wide, in `poolMetrics`
|
||||
they are pool-wide
|
||||
|
||||
`zil_commit_count` counts when ZFS transactions are committed to a ZIL
|
20
plugins/inputs/zfs/sample.conf
Normal file
20
plugins/inputs/zfs/sample.conf
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Read metrics of ZFS from arcstats, zfetchstats, vdev_cache_stats, pools and datasets
|
||||
# This plugin ONLY supports Linux & FreeBSD
|
||||
[[inputs.zfs]]
|
||||
## ZFS kstat path. Ignored on FreeBSD
|
||||
## If not specified, then default is:
|
||||
# kstatPath = "/proc/spl/kstat/zfs"
|
||||
|
||||
## By default, telegraf gather all zfs stats
|
||||
## Override the stats list using the kstatMetrics array:
|
||||
## For FreeBSD, the default is:
|
||||
# kstatMetrics = ["arcstats", "zfetchstats", "vdev_cache_stats"]
|
||||
## For Linux, the default is:
|
||||
# kstatMetrics = ["abdstats", "arcstats", "dnodestats", "dbufcachestats",
|
||||
# "dmu_tx", "fm", "vdev_mirror_stats", "zfetchstats", "zil"]
|
||||
|
||||
## By default, don't gather zpool stats
|
||||
# poolMetrics = false
|
||||
|
||||
## By default, don't gather dataset stats
|
||||
# datasetMetrics = false
|
1
plugins/inputs/zfs/testcases/freebsd/cache/expected.out
vendored
Normal file
1
plugins/inputs/zfs/testcases/freebsd/cache/expected.out
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
zfs,pools=freenas-boot::red1::temp1::temp2 vdev_cache_stats_delegations=6952i,vdev_cache_stats_hits=465583i,vdev_cache_stats_misses=87789i 1698097327984312950
|
12
plugins/inputs/zfs/testcases/freebsd/cache/sysctl.json
vendored
Normal file
12
plugins/inputs/zfs/testcases/freebsd/cache/sysctl.json
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"vdev_cache_stats": [
|
||||
"kstat.zfs.misc.vdev_cache_stats.misses: 87789",
|
||||
"kstat.zfs.misc.vdev_cache_stats.hits: 465583",
|
||||
"kstat.zfs.misc.vdev_cache_stats.delegations: 6952"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 0",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 0",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 0"
|
||||
]
|
||||
}
|
2
plugins/inputs/zfs/testcases/freebsd/cache/telegraf.conf
vendored
Normal file
2
plugins/inputs/zfs/testcases/freebsd/cache/telegraf.conf
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["vdev_cache_stats"]
|
0
plugins/inputs/zfs/testcases/freebsd/cache/zdataset.txt
vendored
Normal file
0
plugins/inputs/zfs/testcases/freebsd/cache/zdataset.txt
vendored
Normal file
4
plugins/inputs/zfs/testcases/freebsd/cache/zpool.txt
vendored
Normal file
4
plugins/inputs/zfs/testcases/freebsd/cache/zpool.txt
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
freenas-boot ONLINE 30601641984 2022177280 28579464704 - 6 1.00x
|
||||
red1 ONLINE 8933531975680 1126164848640 7807367127040 8% 12 1.83x
|
||||
temp1 ONLINE 2989297238016 1626309320704 1362987917312 38% 54 1.28x
|
||||
temp2 ONLINE 2989297238016 626958278656 2362338959360 12% 20 1.00x
|
|
@ -0,0 +1,5 @@
|
|||
zfs_pool,health=ONLINE,pool=freenas-boot allocated=2022177280i,capacity=6i,dedupratio=1,fragmentation=0i,free=28579464704i,size=30601641984i 1698097244832121819
|
||||
zfs_pool,health=ONLINE,pool=red1 allocated=1126164848640i,capacity=12i,dedupratio=1.8300000429153442,fragmentation=8i,free=7807367127040i,size=8933531975680i 1698097244832126568
|
||||
zfs_pool,health=ONLINE,pool=temp1 allocated=1626309320704i,capacity=54i,dedupratio=1.2799999713897705,fragmentation=38i,free=1362987917312i,size=2989297238016i 1698097244832130759
|
||||
zfs_pool,health=ONLINE,pool=temp2 allocated=626958278656i,capacity=20i,dedupratio=1,fragmentation=12i,free=2362338959360i,size=2989297238016i 1698097244832134111
|
||||
zfs,pools=freenas-boot::red1::temp1::temp2 vdev_cache_stats_delegations=6952i,vdev_cache_stats_hits=465583i,vdev_cache_stats_misses=87789i 1698097244832209819
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"vdev_cache_stats": [
|
||||
"kstat.zfs.misc.vdev_cache_stats.misses: 87789",
|
||||
"kstat.zfs.misc.vdev_cache_stats.hits: 465583",
|
||||
"kstat.zfs.misc.vdev_cache_stats.delegations: 6952"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 0",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 0",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 0"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["vdev_cache_stats"]
|
||||
poolMetrics = true
|
|
@ -0,0 +1,4 @@
|
|||
freenas-boot ONLINE 30601641984 2022177280 28579464704 - 6 1.00x
|
||||
red1 ONLINE 8933531975680 1126164848640 7807367127040 8% 12 1.83x
|
||||
temp1 ONLINE 2989297238016 1626309320704 1362987917312 38% 54 1.28x
|
||||
temp2 ONLINE 2989297238016 626958278656 2362338959360 12% 20 1.00x
|
|
@ -0,0 +1 @@
|
|||
zfs,datasets=zata::zata/home::zata/import::zata/storage vdev_cache_stats_delegations=6952i,vdev_cache_stats_hits=465583i,vdev_cache_stats_misses=87789i 1698161813995801840
|
12
plugins/inputs/zfs/testcases/freebsd/dataset/sysctl.json
Normal file
12
plugins/inputs/zfs/testcases/freebsd/dataset/sysctl.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"vdev_cache_stats": [
|
||||
"kstat.zfs.misc.vdev_cache_stats.misses: 87789",
|
||||
"kstat.zfs.misc.vdev_cache_stats.hits: 465583",
|
||||
"kstat.zfs.misc.vdev_cache_stats.delegations: 6952"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 0",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 0",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 0"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["vdev_cache_stats"]
|
|
@ -0,0 +1,4 @@
|
|||
zata 10741741326336 8564135526400 0 90112
|
||||
zata/home 10741741326336 2498560 212992 2285568
|
||||
zata/import 10741741326336 196608 81920 114688
|
||||
zata/storage 10741741326336 8556084379648 3601138999296 4954945380352
|
0
plugins/inputs/zfs/testcases/freebsd/dataset/zpool.txt
Normal file
0
plugins/inputs/zfs/testcases/freebsd/dataset/zpool.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
zfs_dataset,dataset=zata avail=10741741326336i,used=8564135526400i,usedds=90112i,usedsnap=0i 1698161697336342048
|
||||
zfs_dataset,dataset=zata/home avail=10741741326336i,used=2498560i,usedds=2285568i,usedsnap=212992i 1698161697336345401
|
||||
zfs_dataset,dataset=zata/import avail=10741741326336i,used=196608i,usedds=114688i,usedsnap=81920i 1698161697336348474
|
||||
zfs_dataset,dataset=zata/storage avail=10741741326336i,used=8556084379648i,usedds=4954945380352i,usedsnap=3601138999296i 1698161697336352944
|
||||
zfs,datasets=zata::zata/home::zata/import::zata/storage vdev_cache_stats_delegations=6952i,vdev_cache_stats_hits=465583i,vdev_cache_stats_misses=87789i 1698161697336357134
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"vdev_cache_stats": [
|
||||
"kstat.zfs.misc.vdev_cache_stats.misses: 87789",
|
||||
"kstat.zfs.misc.vdev_cache_stats.hits: 465583",
|
||||
"kstat.zfs.misc.vdev_cache_stats.delegations: 6952"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 0",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 0",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 0"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["vdev_cache_stats"]
|
||||
datasetMetrics = true
|
|
@ -0,0 +1,4 @@
|
|||
zata 10741741326336 8564135526400 0 90112
|
||||
zata/home 10741741326336 2498560 212992 2285568
|
||||
zata/import 10741741326336 196608 81920 114688
|
||||
zata/storage 10741741326336 8556084379648 3601138999296 4954945380352
|
16
plugins/inputs/zfs/testcases/freebsd/freebsd14/expected.out
Normal file
16
plugins/inputs/zfs/testcases/freebsd/freebsd14/expected.out
Normal file
|
@ -0,0 +1,16 @@
|
|||
zfs_pool,health=ONLINE,pool=zroot allocated=11959578624i,capacity=17i,dedupratio=1,fragmentation=4i,free=55149285376i,size=67108864000i 1698172931876196974
|
||||
zfs_dataset,dataset=zroot avail=53069045760i,used=11959443456i,usedds=0i,usedsnap=0i 1698172931876204237
|
||||
zfs_dataset,dataset=zroot/ROOT avail=53069045760i,used=4685123584i,usedds=0i,usedsnap=0i 1698172931876207310
|
||||
zfs_dataset,dataset=zroot/ROOT/default avail=53069045760i,used=4684689408i,usedds=0i,usedsnap=0i 1698172931876213735
|
||||
zfs_dataset,dataset=zroot/home avail=53069045760i,used=7263580160i,usedds=0i,usedsnap=0i 1698172931876217926
|
||||
zfs_dataset,dataset=zroot/tmp avail=53069045760i,used=684032i,usedds=0i,usedsnap=0i 1698172931876220720
|
||||
zfs_dataset,dataset=zroot/usr avail=53069045760i,used=1724416i,usedds=0i,usedsnap=0i 1698172931876224631
|
||||
zfs_dataset,dataset=zroot/usr/obj avail=53069045760i,used=430080i,usedds=0i,usedsnap=0i 1698172931876227424
|
||||
zfs_dataset,dataset=zroot/usr/ports avail=53069045760i,used=430080i,usedds=0i,usedsnap=0i 1698172931876230218
|
||||
zfs_dataset,dataset=zroot/usr/src avail=53069045760i,used=430080i,usedds=0i,usedsnap=0i 1698172931876233291
|
||||
zfs_dataset,dataset=zroot/var avail=53069045760i,used=2269184i,usedds=0i,usedsnap=0i 1698172931876237481
|
||||
zfs_dataset,dataset=zroot/var/audit avail=53069045760i,used=438272i,usedds=0i,usedsnap=0i 1698172931876240554
|
||||
zfs_dataset,dataset=zroot/var/log avail=53069045760i,used=544768i,usedds=0i,usedsnap=0i 1698172931876243348
|
||||
zfs_dataset,dataset=zroot/var/mail avail=53069045760i,used=425984i,usedds=0i,usedsnap=0i 1698172931876246980
|
||||
zfs_dataset,dataset=zroot/var/tmp avail=53069045760i,used=425984i,usedds=0i,usedsnap=0i 1698172931876249774
|
||||
zfs,datasets=zroot::zroot/ROOT::zroot/ROOT/default::zroot/home::zroot/tmp::zroot/usr::zroot/usr/obj::zroot/usr/ports::zroot/usr/src::zroot/var::zroot/var/audit::zroot/var/log::zroot/var/mail::zroot/var/tmp,pools=zroot zfetchstats_hits=6439i,zfetchstats_io_active=0i,zfetchstats_io_issued=2197i,zfetchstats_max_streams=9411i,zfetchstats_misses=14538i 1698172931876287767
|
159
plugins/inputs/zfs/testcases/freebsd/freebsd14/sysctl.json
Normal file
159
plugins/inputs/zfs/testcases/freebsd/freebsd14/sysctl.json
Normal file
|
@ -0,0 +1,159 @@
|
|||
{
|
||||
"archstats": [
|
||||
"kstat.zfs.misc.arcstats.abd_chunk_waste_size: 626176",
|
||||
"kstat.zfs.misc.arcstats.cached_only_in_progress: 0",
|
||||
"kstat.zfs.misc.arcstats.arc_raw_size: 0",
|
||||
"kstat.zfs.misc.arcstats.arc_sys_free: 0",
|
||||
"kstat.zfs.misc.arcstats.arc_need_free: 0",
|
||||
"kstat.zfs.misc.arcstats.demand_iohit_prescient_prefetch: 1",
|
||||
"kstat.zfs.misc.arcstats.demand_hit_prescient_prefetch: 14",
|
||||
"kstat.zfs.misc.arcstats.prescient_prefetch: 15",
|
||||
"kstat.zfs.misc.arcstats.demand_iohit_predictive_prefetch: 218",
|
||||
"kstat.zfs.misc.arcstats.demand_hit_predictive_prefetch: 1778",
|
||||
"kstat.zfs.misc.arcstats.predictive_prefetch: 5099",
|
||||
"kstat.zfs.misc.arcstats.async_upgrade_sync: 135",
|
||||
"kstat.zfs.misc.arcstats.arc_dnode_limit: 317881139",
|
||||
"kstat.zfs.misc.arcstats.arc_meta_used: 80185232",
|
||||
"kstat.zfs.misc.arcstats.arc_prune: 25",
|
||||
"kstat.zfs.misc.arcstats.arc_loaned_bytes: 0",
|
||||
"kstat.zfs.misc.arcstats.arc_tempreserve: 0",
|
||||
"kstat.zfs.misc.arcstats.arc_no_grow: 0",
|
||||
"kstat.zfs.misc.arcstats.memory_available_bytes: 3663839232",
|
||||
"kstat.zfs.misc.arcstats.memory_free_bytes: 3752042496",
|
||||
"kstat.zfs.misc.arcstats.memory_all_bytes: 4252553216",
|
||||
"kstat.zfs.misc.arcstats.memory_indirect_count: 0",
|
||||
"kstat.zfs.misc.arcstats.memory_direct_count: 0",
|
||||
"kstat.zfs.misc.arcstats.memory_throttle_count: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_log_blks: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_bufs_precached: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_bufs: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_size: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_lowmem: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_cksum_lb_errors: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_dh_errors: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_io_errors: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_unsupported: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rebuild_success: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_data_to_meta_ratio: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_log_blk_count: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_log_blk_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_log_blk_avg_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_log_blk_writes: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_hdr_size: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_size: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_io_error: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_cksum_bad: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_abort_lowmem: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_free_on_write: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_evict_l1cached: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_evict_reading: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_evict_lock_retry: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_writes_lock_retry: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_writes_error: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_writes_done: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_writes_sent: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_write_bytes: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_read_bytes: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_rw_clash: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_feeds: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_bufc_metadata_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_bufc_data_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_mfu_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_mru_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_prefetch_asize: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_misses: 0",
|
||||
"kstat.zfs.misc.arcstats.l2_hits: 0",
|
||||
"kstat.zfs.misc.arcstats.uncached_evictable_metadata: 0",
|
||||
"kstat.zfs.misc.arcstats.uncached_evictable_data: 0",
|
||||
"kstat.zfs.misc.arcstats.uncached_metadata: 0",
|
||||
"kstat.zfs.misc.arcstats.uncached_data: 0",
|
||||
"kstat.zfs.misc.arcstats.uncached_size: 0",
|
||||
"kstat.zfs.misc.arcstats.mfu_ghost_evictable_metadata: 35231232",
|
||||
"kstat.zfs.misc.arcstats.mfu_ghost_evictable_data: 31780352",
|
||||
"kstat.zfs.misc.arcstats.mfu_ghost_metadata: 35231232",
|
||||
"kstat.zfs.misc.arcstats.mfu_ghost_data: 31780352",
|
||||
"kstat.zfs.misc.arcstats.mfu_ghost_size: 67011584",
|
||||
"kstat.zfs.misc.arcstats.mfu_evictable_metadata: 648192",
|
||||
"kstat.zfs.misc.arcstats.mfu_evictable_data: 29985280",
|
||||
"kstat.zfs.misc.arcstats.mfu_metadata: 9697280",
|
||||
"kstat.zfs.misc.arcstats.mfu_data: 31448576",
|
||||
"kstat.zfs.misc.arcstats.mfu_size: 41145856",
|
||||
"kstat.zfs.misc.arcstats.mru_ghost_evictable_metadata: 27670528",
|
||||
"kstat.zfs.misc.arcstats.mru_ghost_evictable_data: 39195136",
|
||||
"kstat.zfs.misc.arcstats.mru_ghost_metadata: 27670528",
|
||||
"kstat.zfs.misc.arcstats.mru_ghost_data: 39195136",
|
||||
"kstat.zfs.misc.arcstats.mru_ghost_size: 66865664",
|
||||
"kstat.zfs.misc.arcstats.mru_evictable_metadata: 4007424",
|
||||
"kstat.zfs.misc.arcstats.mru_evictable_data: 21310976",
|
||||
"kstat.zfs.misc.arcstats.mru_metadata: 32238592",
|
||||
"kstat.zfs.misc.arcstats.mru_data: 25252864",
|
||||
"kstat.zfs.misc.arcstats.mru_size: 57491456",
|
||||
"kstat.zfs.misc.arcstats.anon_evictable_metadata: 0",
|
||||
"kstat.zfs.misc.arcstats.anon_evictable_data: 0",
|
||||
"kstat.zfs.misc.arcstats.anon_metadata: 0",
|
||||
"kstat.zfs.misc.arcstats.anon_data: 0",
|
||||
"kstat.zfs.misc.arcstats.anon_size: 0",
|
||||
"kstat.zfs.misc.arcstats.other_size: 36376512",
|
||||
"kstat.zfs.misc.arcstats.bonus_size: 7930560",
|
||||
"kstat.zfs.misc.arcstats.dnode_size: 20521584",
|
||||
"kstat.zfs.misc.arcstats.dbuf_size: 7924368",
|
||||
"kstat.zfs.misc.arcstats.metadata_size: 41935872",
|
||||
"kstat.zfs.misc.arcstats.data_size: 56701440",
|
||||
"kstat.zfs.misc.arcstats.hdr_size: 1872848",
|
||||
"kstat.zfs.misc.arcstats.overhead_size: 29338112",
|
||||
"kstat.zfs.misc.arcstats.uncompressed_size: 121843712",
|
||||
"kstat.zfs.misc.arcstats.compressed_size: 69299200",
|
||||
"kstat.zfs.misc.arcstats.size: 137512848",
|
||||
"kstat.zfs.misc.arcstats.c_max: 3178811392",
|
||||
"kstat.zfs.misc.arcstats.c_min: 132892288",
|
||||
"kstat.zfs.misc.arcstats.c: 176014976",
|
||||
"kstat.zfs.misc.arcstats.pm: 2306048980",
|
||||
"kstat.zfs.misc.arcstats.pd: 1302662522",
|
||||
"kstat.zfs.misc.arcstats.meta: 1110189320",
|
||||
"kstat.zfs.misc.arcstats.hash_chain_max: 4",
|
||||
"kstat.zfs.misc.arcstats.hash_chains: 68",
|
||||
"kstat.zfs.misc.arcstats.hash_collisions: 15034",
|
||||
"kstat.zfs.misc.arcstats.hash_elements_max: 91215",
|
||||
"kstat.zfs.misc.arcstats.hash_elements: 7890",
|
||||
"kstat.zfs.misc.arcstats.evict_l2_skip: 0",
|
||||
"kstat.zfs.misc.arcstats.evict_l2_ineligible: 65306624",
|
||||
"kstat.zfs.misc.arcstats.evict_l2_eligible_mru: 1369077760",
|
||||
"kstat.zfs.misc.arcstats.evict_l2_eligible_mfu: 940835840",
|
||||
"kstat.zfs.misc.arcstats.evict_l2_eligible: 2309913600",
|
||||
"kstat.zfs.misc.arcstats.evict_l2_cached: 0",
|
||||
"kstat.zfs.misc.arcstats.evict_not_enough: 12",
|
||||
"kstat.zfs.misc.arcstats.evict_skip: 445",
|
||||
"kstat.zfs.misc.arcstats.access_skip: 0",
|
||||
"kstat.zfs.misc.arcstats.mutex_miss: 0",
|
||||
"kstat.zfs.misc.arcstats.deleted: 90151",
|
||||
"kstat.zfs.misc.arcstats.uncached_hits: 0",
|
||||
"kstat.zfs.misc.arcstats.mfu_ghost_hits: 6108",
|
||||
"kstat.zfs.misc.arcstats.mfu_hits: 1240173",
|
||||
"kstat.zfs.misc.arcstats.mru_ghost_hits: 2692",
|
||||
"kstat.zfs.misc.arcstats.mru_hits: 233633",
|
||||
"kstat.zfs.misc.arcstats.prefetch_metadata_misses: 406",
|
||||
"kstat.zfs.misc.arcstats.prefetch_metadata_iohits: 2315",
|
||||
"kstat.zfs.misc.arcstats.prefetch_metadata_hits: 196",
|
||||
"kstat.zfs.misc.arcstats.prefetch_data_misses: 2092",
|
||||
"kstat.zfs.misc.arcstats.prefetch_data_iohits: 0",
|
||||
"kstat.zfs.misc.arcstats.prefetch_data_hits: 105",
|
||||
"kstat.zfs.misc.arcstats.demand_metadata_misses: 12021",
|
||||
"kstat.zfs.misc.arcstats.demand_metadata_iohits: 87",
|
||||
"kstat.zfs.misc.arcstats.demand_metadata_hits: 906938",
|
||||
"kstat.zfs.misc.arcstats.demand_data_misses: 48482",
|
||||
"kstat.zfs.misc.arcstats.demand_data_iohits: 128",
|
||||
"kstat.zfs.misc.arcstats.demand_data_hits: 566567",
|
||||
"kstat.zfs.misc.arcstats.misses: 63001",
|
||||
"kstat.zfs.misc.arcstats.iohits: 2530",
|
||||
"kstat.zfs.misc.arcstats.hits: 1473806"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.io_active: 0",
|
||||
"kstat.zfs.misc.zfetchstats.io_issued: 2197",
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 9411",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 14538",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 6439"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["arcstats", "zfetchstats", "vdev_cache_stats"]
|
||||
poolMetrics = true
|
||||
datasetMetrics = true
|
1
plugins/inputs/zfs/testcases/freebsd/freebsd14/uname.txt
Normal file
1
plugins/inputs/zfs/testcases/freebsd/freebsd14/uname.txt
Normal file
|
@ -0,0 +1 @@
|
|||
14.0-RC2
|
14
plugins/inputs/zfs/testcases/freebsd/freebsd14/zdataset.txt
Normal file
14
plugins/inputs/zfs/testcases/freebsd/freebsd14/zdataset.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
zroot 53069045760 11959443456 - -
|
||||
zroot/ROOT 53069045760 4685123584 - -
|
||||
zroot/ROOT/default 53069045760 4684689408 - -
|
||||
zroot/home 53069045760 7263580160 - -
|
||||
zroot/tmp 53069045760 684032 - -
|
||||
zroot/usr 53069045760 1724416 - -
|
||||
zroot/usr/obj 53069045760 430080 - -
|
||||
zroot/usr/ports 53069045760 430080 - -
|
||||
zroot/usr/src 53069045760 430080 - -
|
||||
zroot/var 53069045760 2269184 - -
|
||||
zroot/var/audit 53069045760 438272 - -
|
||||
zroot/var/log 53069045760 544768 - -
|
||||
zroot/var/mail 53069045760 425984 - -
|
||||
zroot/var/tmp 53069045760 425984 - -
|
1
plugins/inputs/zfs/testcases/freebsd/freebsd14/zpool.txt
Normal file
1
plugins/inputs/zfs/testcases/freebsd/freebsd14/zpool.txt
Normal file
|
@ -0,0 +1 @@
|
|||
zroot ONLINE 67108864000 11959578624 55149285376 4 17 1.00
|
|
@ -0,0 +1 @@
|
|||
zfs,pools=freenas-boot::red1::temp1::temp2 vdev_cache_stats_delegations=6952i,vdev_cache_stats_hits=465583i,vdev_cache_stats_misses=87789i 1698157432411179772
|
12
plugins/inputs/zfs/testcases/freebsd/freenas/sysctl.json
Normal file
12
plugins/inputs/zfs/testcases/freebsd/freenas/sysctl.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"vdev_cache_stats": [
|
||||
"kstat.zfs.misc.vdev_cache_stats.misses: 87789",
|
||||
"kstat.zfs.misc.vdev_cache_stats.hits: 465583",
|
||||
"kstat.zfs.misc.vdev_cache_stats.delegations: 6952"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 0",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 0",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 0"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["vdev_cache_stats"]
|
4
plugins/inputs/zfs/testcases/freebsd/freenas/zpool.txt
Normal file
4
plugins/inputs/zfs/testcases/freebsd/freenas/zpool.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
freenas-boot ONLINE 30601641984 2022177280 28579464704 - 6 1.00x
|
||||
red1 ONLINE 8933531975680 1126164848640 7807367127040 8% 12 1.83x
|
||||
temp1 ONLINE 2989297238016 1626309320704 1362987917312 38% 54 1.28x
|
||||
temp2 ONLINE 2989297238016 626958278656 2362338959360 12% 20 1.00x
|
|
@ -0,0 +1 @@
|
|||
zfs,pools=freenas-boot::red1::temp1::temp2 vdev_cache_stats_delegations=6952i,vdev_cache_stats_hits=465583i,vdev_cache_stats_misses=87789i,zfetchstats_hits=0i,zfetchstats_max_streams=0i,zfetchstats_misses=0i 1698157264111374629
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"vdev_cache_stats": [
|
||||
"kstat.zfs.misc.vdev_cache_stats.misses: 87789",
|
||||
"kstat.zfs.misc.vdev_cache_stats.hits: 465583",
|
||||
"kstat.zfs.misc.vdev_cache_stats.delegations: 6952"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 0",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 0",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 0"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["zfetchstats", "vdev_cache_stats"]
|
|
@ -0,0 +1,4 @@
|
|||
freenas-boot ONLINE 30601641984 2022177280 28579464704 - 6 1.00x
|
||||
red1 ONLINE 8933531975680 1126164848640 7807367127040 8% 12 1.83x
|
||||
temp1 ONLINE 2989297238016 1626309320704 1362987917312 38% 54 1.28x
|
||||
temp2 ONLINE 2989297238016 626958278656 2362338959360 12% 20 1.00x
|
|
@ -0,0 +1 @@
|
|||
zfs,pools=temp2 vdev_cache_stats_delegations=6952i,vdev_cache_stats_hits=465583i,vdev_cache_stats_misses=87789i 1698098260907108724
|
12
plugins/inputs/zfs/testcases/freebsd/unavailable/sysctl.json
Normal file
12
plugins/inputs/zfs/testcases/freebsd/unavailable/sysctl.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"vdev_cache_stats": [
|
||||
"kstat.zfs.misc.vdev_cache_stats.misses: 87789",
|
||||
"kstat.zfs.misc.vdev_cache_stats.hits: 465583",
|
||||
"kstat.zfs.misc.vdev_cache_stats.delegations: 6952"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 0",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 0",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 0"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["vdev_cache_stats"]
|
|
@ -0,0 +1 @@
|
|||
temp2 UNAVAIL - - - - - -
|
|
@ -0,0 +1,2 @@
|
|||
zfs_pool,health=UNAVAIL,pool=temp2 size=0i 1698098260907383061
|
||||
zfs,pools=temp2 vdev_cache_stats_delegations=6952i,vdev_cache_stats_hits=465583i,vdev_cache_stats_misses=87789i 1698098260907393118
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"vdev_cache_stats": [
|
||||
"kstat.zfs.misc.vdev_cache_stats.misses: 87789",
|
||||
"kstat.zfs.misc.vdev_cache_stats.hits: 465583",
|
||||
"kstat.zfs.misc.vdev_cache_stats.delegations: 6952"
|
||||
],
|
||||
"zfetchstats": [
|
||||
"kstat.zfs.misc.zfetchstats.max_streams: 0",
|
||||
"kstat.zfs.misc.zfetchstats.misses: 0",
|
||||
"kstat.zfs.misc.zfetchstats.hits: 0"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
[[inputs.zfs]]
|
||||
kstatMetrics = ["vdev_cache_stats"]
|
||||
poolMetrics = true
|
|
@ -0,0 +1 @@
|
|||
temp2 UNAVAIL - - - - - -
|
25
plugins/inputs/zfs/zfs.go
Normal file
25
plugins/inputs/zfs/zfs.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
package zfs
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type Zfs struct {
|
||||
KstatPath string `toml:"kstatPath"`
|
||||
KstatMetrics []string `toml:"kstatMetrics"`
|
||||
PoolMetrics bool `toml:"poolMetrics"`
|
||||
DatasetMetrics bool `toml:"datasetMetrics"`
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
|
||||
helper //nolint:unused // for OS-specific usage
|
||||
}
|
||||
|
||||
func (*Zfs) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
274
plugins/inputs/zfs/zfs_freebsd.go
Normal file
274
plugins/inputs/zfs/zfs_freebsd.go
Normal file
|
@ -0,0 +1,274 @@
|
|||
//go:build freebsd
|
||||
|
||||
package zfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
type helper struct {
|
||||
sysctl sysctlF
|
||||
zpool zpoolF
|
||||
zdataset zdatasetF
|
||||
uname unameF
|
||||
}
|
||||
|
||||
type sysctlF func(metric string) ([]string, error)
|
||||
type zpoolF func() ([]string, error)
|
||||
type zdatasetF func(properties []string) ([]string, error)
|
||||
type unameF func() (string, error)
|
||||
|
||||
func (z *Zfs) Init() error {
|
||||
// Determine the kernel version to adapt parsing
|
||||
release, err := z.uname()
|
||||
if err != nil {
|
||||
return fmt.Errorf("determining uname failed: %w", err)
|
||||
}
|
||||
parts := strings.SplitN(release, ".", 2)
|
||||
version, err := strconv.ParseInt(parts[0], 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("determining version from %q failed: %w", release, err)
|
||||
}
|
||||
|
||||
// Setup default metrics if they are not specified.
|
||||
// Please note that starting from FreeBSD 14 the 'vdev_cache_stats' are
|
||||
// no longer available.
|
||||
if len(z.KstatMetrics) == 0 {
|
||||
if version < 14 {
|
||||
z.KstatMetrics = []string{"arcstats", "zfetchstats", "vdev_cache_stats"}
|
||||
} else {
|
||||
z.KstatMetrics = []string{"arcstats", "zfetchstats"}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (z *Zfs) Gather(acc telegraf.Accumulator) error {
|
||||
tags := map[string]string{}
|
||||
|
||||
poolNames, err := z.gatherPoolStats(acc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if poolNames != "" {
|
||||
tags["pools"] = poolNames
|
||||
}
|
||||
|
||||
datasetNames, err := z.gatherDatasetStats(acc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if datasetNames != "" {
|
||||
tags["datasets"] = datasetNames
|
||||
}
|
||||
|
||||
// Gather information form the kernel using sysctl
|
||||
fields := make(map[string]interface{})
|
||||
var removeIndices []int
|
||||
for i, metric := range z.KstatMetrics {
|
||||
stdout, err := z.sysctl(metric)
|
||||
if err != nil {
|
||||
z.Log.Warnf("sysctl for 'kstat.zfs.misc.%s' failed: %v; removing metric", metric, err)
|
||||
removeIndices = append(removeIndices, i)
|
||||
continue
|
||||
}
|
||||
for _, line := range stdout {
|
||||
rawData := strings.Split(line, ": ")
|
||||
key := metric + "_" + strings.Split(rawData[0], ".")[4]
|
||||
value, _ := strconv.ParseInt(rawData[1], 10, 64)
|
||||
fields[key] = value
|
||||
}
|
||||
}
|
||||
acc.AddFields("zfs", fields, tags)
|
||||
|
||||
// Remove the invalid kstat metrics
|
||||
if len(removeIndices) > 0 {
|
||||
for i := len(removeIndices) - 1; i >= 0; i-- {
|
||||
idx := removeIndices[i]
|
||||
z.KstatMetrics = append(z.KstatMetrics[:idx], z.KstatMetrics[idx+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (z *Zfs) gatherPoolStats(acc telegraf.Accumulator) (string, error) {
|
||||
lines, err := z.zpool()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pools := []string{}
|
||||
for _, line := range lines {
|
||||
col := strings.Split(line, "\t")
|
||||
pools = append(pools, col[0])
|
||||
}
|
||||
|
||||
if !z.PoolMetrics {
|
||||
return strings.Join(pools, "::"), nil
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
col := strings.Split(line, "\t")
|
||||
if len(col) != 8 {
|
||||
continue
|
||||
}
|
||||
|
||||
tags := map[string]string{"pool": col[0], "health": col[1]}
|
||||
fields := map[string]interface{}{}
|
||||
|
||||
if tags["health"] == "UNAVAIL" {
|
||||
fields["size"] = int64(0)
|
||||
} else {
|
||||
size, err := strconv.ParseInt(col[2], 10, 64)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error parsing size: %s", err)
|
||||
}
|
||||
fields["size"] = size
|
||||
|
||||
alloc, err := strconv.ParseInt(col[3], 10, 64)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error parsing allocation: %s", err)
|
||||
}
|
||||
fields["allocated"] = alloc
|
||||
|
||||
free, err := strconv.ParseInt(col[4], 10, 64)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error parsing free: %s", err)
|
||||
}
|
||||
fields["free"] = free
|
||||
|
||||
frag, err := strconv.ParseInt(strings.TrimSuffix(col[5], "%"), 10, 0)
|
||||
if err != nil { // This might be - for RO devs
|
||||
frag = 0
|
||||
}
|
||||
fields["fragmentation"] = frag
|
||||
|
||||
capval, err := strconv.ParseInt(col[6], 10, 0)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error parsing capacity: %s", err)
|
||||
}
|
||||
fields["capacity"] = capval
|
||||
|
||||
dedup, err := strconv.ParseFloat(strings.TrimSuffix(col[7], "x"), 32)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error parsing dedupratio: %s", err)
|
||||
}
|
||||
fields["dedupratio"] = dedup
|
||||
}
|
||||
|
||||
acc.AddFields("zfs_pool", fields, tags)
|
||||
}
|
||||
|
||||
return strings.Join(pools, "::"), nil
|
||||
}
|
||||
|
||||
func (z *Zfs) gatherDatasetStats(acc telegraf.Accumulator) (string, error) {
|
||||
properties := []string{"name", "avail", "used", "usedsnap", "usedds"}
|
||||
|
||||
lines, err := z.zdataset(properties)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
datasets := []string{}
|
||||
for _, line := range lines {
|
||||
col := strings.Split(line, "\t")
|
||||
datasets = append(datasets, col[0])
|
||||
}
|
||||
|
||||
if !z.DatasetMetrics {
|
||||
return strings.Join(datasets, "::"), nil
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
col := strings.Split(line, "\t")
|
||||
if len(col) != len(properties) {
|
||||
z.Log.Warnf("Invalid number of columns for line: %s", line)
|
||||
continue
|
||||
}
|
||||
|
||||
tags := map[string]string{"dataset": col[0]}
|
||||
fields := map[string]interface{}{}
|
||||
|
||||
for i, key := range properties[1:] {
|
||||
// Treat '-' entries as zero
|
||||
if col[i+1] == "-" {
|
||||
fields[key] = int64(0)
|
||||
continue
|
||||
}
|
||||
value, err := strconv.ParseInt(col[i+1], 10, 64)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error parsing %s %q: %s", key, col[i+1], err)
|
||||
}
|
||||
fields[key] = value
|
||||
}
|
||||
|
||||
acc.AddFields("zfs_dataset", fields, tags)
|
||||
}
|
||||
|
||||
return strings.Join(datasets, "::"), nil
|
||||
}
|
||||
|
||||
func run(command string, args ...string) ([]string, error) {
|
||||
cmd := exec.Command(command, args...)
|
||||
var outbuf, errbuf bytes.Buffer
|
||||
cmd.Stdout = &outbuf
|
||||
cmd.Stderr = &errbuf
|
||||
err := cmd.Run()
|
||||
|
||||
stdout := strings.TrimSpace(outbuf.String())
|
||||
stderr := strings.TrimSpace(errbuf.String())
|
||||
|
||||
if err != nil {
|
||||
if _, ok := err.(*exec.ExitError); ok {
|
||||
return nil, fmt.Errorf("%s error: %s", command, stderr)
|
||||
}
|
||||
return nil, fmt.Errorf("%s error: %s", command, err)
|
||||
}
|
||||
return strings.Split(stdout, "\n"), nil
|
||||
}
|
||||
|
||||
func zpool() ([]string, error) {
|
||||
return run("zpool", []string{"list", "-Hp", "-o", "name,health,size,alloc,free,fragmentation,capacity,dedupratio"}...)
|
||||
}
|
||||
|
||||
func zdataset(properties []string) ([]string, error) {
|
||||
return run("zfs", []string{"list", "-Hp", "-t", "filesystem,volume", "-o", strings.Join(properties, ",")}...)
|
||||
}
|
||||
|
||||
func sysctl(metric string) ([]string, error) {
|
||||
return run("sysctl", []string{"-q", fmt.Sprintf("kstat.zfs.misc.%s", metric)}...)
|
||||
}
|
||||
|
||||
func uname() (string, error) {
|
||||
var info unix.Utsname
|
||||
if err := unix.Uname(&info); err != nil {
|
||||
return "", err
|
||||
}
|
||||
release := unix.ByteSliceToString(info.Release[:])
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("zfs", func() telegraf.Input {
|
||||
return &Zfs{
|
||||
helper: helper{
|
||||
sysctl: sysctl,
|
||||
zpool: zpool,
|
||||
zdataset: zdataset,
|
||||
uname: uname,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
104
plugins/inputs/zfs/zfs_freebsd_test.go
Normal file
104
plugins/inputs/zfs/zfs_freebsd_test.go
Normal file
|
@ -0,0 +1,104 @@
|
|||
//go:build freebsd
|
||||
|
||||
package zfs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
"github.com/influxdata/telegraf/plugins/parsers/influx"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
// Generate testcase-data via
|
||||
//
|
||||
// zpool.txt: $ zpool list -Hp -o name,health,size,alloc,free,fragmentation,capacity,dedupratio
|
||||
// zdataset.txt: $ zfs list -Hp -o name,avail,used,usedsnap,usedds
|
||||
// sysctl.json: $ sysctl -q kstat.zfs.misc.<kstat metrics>
|
||||
func TestCases(t *testing.T) {
|
||||
// Get all testcase directories
|
||||
testpath := filepath.Join("testcases", "freebsd")
|
||||
folders, err := os.ReadDir(testpath)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Register the plugin
|
||||
inputs.Add("zfs", func() telegraf.Input { return &Zfs{} })
|
||||
|
||||
for _, f := range folders {
|
||||
// Only handle folders
|
||||
if !f.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
t.Run(f.Name(), func(t *testing.T) {
|
||||
testcasePath := filepath.Join(testpath, f.Name())
|
||||
configFilename := filepath.Join(testcasePath, "telegraf.conf")
|
||||
inputSysctlFilename := filepath.Join(testcasePath, "sysctl.json")
|
||||
inputZPoolFilename := filepath.Join(testcasePath, "zpool.txt")
|
||||
inputZDatasetFilename := filepath.Join(testcasePath, "zdataset.txt")
|
||||
inputUnameFilename := filepath.Join(testcasePath, "uname.txt")
|
||||
expectedFilename := filepath.Join(testcasePath, "expected.out")
|
||||
|
||||
// Load the input data
|
||||
buf, err := os.ReadFile(inputSysctlFilename)
|
||||
require.NoError(t, err)
|
||||
var sysctl map[string][]string
|
||||
require.NoError(t, json.Unmarshal(buf, &sysctl))
|
||||
|
||||
zpool, err := testutil.ParseLinesFromFile(inputZPoolFilename)
|
||||
require.NoError(t, err)
|
||||
|
||||
zdataset, err := testutil.ParseLinesFromFile(inputZDatasetFilename)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Try to read release from file and default to FreeBSD 13 if
|
||||
// an error occurs.
|
||||
uname := "13.2-STABLE"
|
||||
if buf, err := os.ReadFile(inputUnameFilename); err == nil {
|
||||
uname = string(buf)
|
||||
}
|
||||
|
||||
// Prepare the influx parser for expectations
|
||||
parser := &influx.Parser{}
|
||||
require.NoError(t, parser.Init())
|
||||
|
||||
// Read the expected output
|
||||
expected, err := testutil.ParseMetricsFromFile(expectedFilename, parser)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Configure the plugin
|
||||
cfg := config.NewConfig()
|
||||
require.NoError(t, cfg.LoadConfig(configFilename))
|
||||
require.Len(t, cfg.Inputs, 1)
|
||||
|
||||
// Setup the plugin
|
||||
plugin := cfg.Inputs[0].Input.(*Zfs)
|
||||
plugin.sysctl = func(metric string) ([]string, error) {
|
||||
if r, found := sysctl[metric]; found {
|
||||
return r, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid argument")
|
||||
}
|
||||
plugin.zpool = func() ([]string, error) { return zpool, nil }
|
||||
plugin.zdataset = func(_ []string) ([]string, error) { return zdataset, nil }
|
||||
plugin.uname = func() (string, error) { return uname, nil }
|
||||
plugin.Log = testutil.Logger{}
|
||||
require.NoError(t, plugin.Init())
|
||||
|
||||
// Gather and test
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, plugin.Gather(&acc))
|
||||
|
||||
actual := acc.GetTelegrafMetrics()
|
||||
testutil.RequireMetricsEqual(t, expected, actual, testutil.IgnoreTime())
|
||||
})
|
||||
}
|
||||
}
|
245
plugins/inputs/zfs/zfs_linux.go
Normal file
245
plugins/inputs/zfs/zfs_linux.go
Normal file
|
@ -0,0 +1,245 @@
|
|||
//go:build linux
|
||||
|
||||
package zfs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
const (
|
||||
unknown metricsVersion = iota
|
||||
v1
|
||||
v2
|
||||
)
|
||||
|
||||
type metricsVersion uint8
|
||||
|
||||
type poolInfo struct {
|
||||
name string
|
||||
ioFilename string
|
||||
version metricsVersion
|
||||
}
|
||||
|
||||
type helper struct{} //nolint:unused // not used for "linux" OS, needed for Zfs struct
|
||||
|
||||
func (z *Zfs) Gather(acc telegraf.Accumulator) error {
|
||||
kstatMetrics := z.KstatMetrics
|
||||
if len(kstatMetrics) == 0 {
|
||||
// vdev_cache_stats is deprecated
|
||||
// xuio_stats are ignored because as of Sep-2016, no known
|
||||
// consumers of xuio exist on Linux
|
||||
kstatMetrics = []string{"abdstats", "arcstats", "dnodestats", "dbufcachestats",
|
||||
"dmu_tx", "fm", "vdev_mirror_stats", "zfetchstats", "zil"}
|
||||
}
|
||||
|
||||
kstatPath := z.KstatPath
|
||||
if len(kstatPath) == 0 {
|
||||
kstatPath = "/proc/spl/kstat/zfs"
|
||||
}
|
||||
|
||||
pools, err := getPools(kstatPath)
|
||||
tags := getTags(pools)
|
||||
|
||||
if z.PoolMetrics && err == nil {
|
||||
for _, pool := range pools {
|
||||
err := gatherPoolStats(pool, acc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fields := make(map[string]interface{})
|
||||
for _, metric := range kstatMetrics {
|
||||
lines, err := internal.ReadLines(kstatPath + "/" + metric)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for i, line := range lines {
|
||||
if i == 0 || i == 1 {
|
||||
continue
|
||||
}
|
||||
if len(line) < 1 {
|
||||
continue
|
||||
}
|
||||
rawData := strings.Split(line, " ")
|
||||
key := metric + "_" + rawData[0]
|
||||
if metric == "zil" || metric == "dmu_tx" || metric == "dnodestats" {
|
||||
key = rawData[0]
|
||||
}
|
||||
rawValue := rawData[len(rawData)-1]
|
||||
value, err := strconv.ParseInt(rawValue, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fields[key] = value
|
||||
}
|
||||
}
|
||||
acc.AddFields("zfs", fields, tags)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPools(kstatPath string) ([]poolInfo, error) {
|
||||
pools := make([]poolInfo, 0)
|
||||
version, poolsDirs, err := probeVersion(kstatPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, poolDir := range poolsDirs {
|
||||
poolDirSplit := strings.Split(poolDir, "/")
|
||||
pool := poolDirSplit[len(poolDirSplit)-2]
|
||||
pools = append(pools, poolInfo{name: pool, ioFilename: poolDir, version: version})
|
||||
}
|
||||
|
||||
return pools, nil
|
||||
}
|
||||
|
||||
func probeVersion(kstatPath string) (metricsVersion, []string, error) {
|
||||
poolsDirs, err := filepath.Glob(kstatPath + "/*/objset-*")
|
||||
|
||||
// From the docs: the only possible returned error is ErrBadPattern, when pattern is malformed.
|
||||
// Because of this we need to determine how to fallback differently.
|
||||
if err != nil {
|
||||
return unknown, poolsDirs, err
|
||||
}
|
||||
|
||||
if len(poolsDirs) > 0 {
|
||||
return v2, poolsDirs, nil
|
||||
}
|
||||
|
||||
// Fallback to the old kstat in case of an older ZFS version.
|
||||
poolsDirs, err = filepath.Glob(kstatPath + "/*/io")
|
||||
if err != nil {
|
||||
return unknown, poolsDirs, err
|
||||
}
|
||||
|
||||
return v1, poolsDirs, nil
|
||||
}
|
||||
|
||||
func getTags(pools []poolInfo) map[string]string {
|
||||
poolNames := ""
|
||||
knownPools := make(map[string]struct{})
|
||||
for _, entry := range pools {
|
||||
name := entry.name
|
||||
if _, ok := knownPools[name]; !ok {
|
||||
knownPools[name] = struct{}{}
|
||||
if poolNames != "" {
|
||||
poolNames += "::"
|
||||
}
|
||||
poolNames += name
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]string{"pools": poolNames}
|
||||
}
|
||||
|
||||
func gatherPoolStats(pool poolInfo, acc telegraf.Accumulator) error {
|
||||
lines, err := internal.ReadLines(pool.ioFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var fields map[string]interface{}
|
||||
var gatherErr error
|
||||
tags := map[string]string{"pool": pool.name}
|
||||
switch pool.version {
|
||||
case v1:
|
||||
fields, gatherErr = gatherV1(lines)
|
||||
case v2:
|
||||
fields, gatherErr = gatherV2(lines, tags)
|
||||
case unknown:
|
||||
return errors.New("unknown metrics version detected")
|
||||
}
|
||||
|
||||
if gatherErr != nil {
|
||||
return gatherErr
|
||||
}
|
||||
|
||||
acc.AddFields("zfs_pool", fields, tags)
|
||||
return nil
|
||||
}
|
||||
|
||||
func gatherV1(lines []string) (map[string]interface{}, error) {
|
||||
fileLines := 3
|
||||
keys, values, err := gather(lines, fileLines)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fields := make(map[string]interface{})
|
||||
for i := 0; i < len(keys); i++ {
|
||||
value, err := strconv.ParseInt(values[i], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fields[keys[i]] = value
|
||||
}
|
||||
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
func gather(lines []string, fileLines int) (keys, values []string, err error) {
|
||||
if len(lines) < fileLines {
|
||||
return nil, nil, errors.New("expected lines in kstat does not match")
|
||||
}
|
||||
|
||||
keys = strings.Fields(lines[1])
|
||||
values = strings.Fields(lines[2])
|
||||
if len(keys) != len(values) {
|
||||
return nil, nil, fmt.Errorf("key and value count don't match Keys:%v Values:%v", keys, values)
|
||||
}
|
||||
|
||||
return keys, values, nil
|
||||
}
|
||||
|
||||
// New way of collection. Each objset-* file in ZFS >= 2.1.x has a format looking like this:
|
||||
// 36 1 0x01 7 2160 5214787391 73405258558961
|
||||
// name type data
|
||||
// dataset_name 7 rpool/ROOT/pve-1
|
||||
// writes 4 409570
|
||||
// nwritten 4 2063419969
|
||||
// reads 4 22108699
|
||||
// nread 4 63067280992
|
||||
// nunlinks 4 13849
|
||||
// nunlinked 4 13848
|
||||
//
|
||||
// For explanation of the first line's values see https://github.com/openzfs/zfs/blob/master/module/os/linux/spl/spl-kstat.c#L61
|
||||
func gatherV2(lines []string, tags map[string]string) (map[string]interface{}, error) {
|
||||
fileLines := 9
|
||||
_, _, err := gather(lines, fileLines)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tags["dataset"] = strings.Fields(lines[2])[2]
|
||||
fields := make(map[string]interface{})
|
||||
for i := 3; i < len(lines); i++ {
|
||||
lineFields := strings.Fields(lines[i])
|
||||
fieldName := lineFields[0]
|
||||
fieldData := lineFields[2]
|
||||
value, err := strconv.ParseInt(fieldData, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fields[fieldName] = value
|
||||
}
|
||||
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("zfs", func() telegraf.Input {
|
||||
return &Zfs{}
|
||||
})
|
||||
}
|
609
plugins/inputs/zfs/zfs_linux_test.go
Normal file
609
plugins/inputs/zfs/zfs_linux_test.go
Normal file
|
@ -0,0 +1,609 @@
|
|||
//go:build linux
|
||||
|
||||
package zfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
const arcstatsContents = `5 1 0x01 86 4128 23617128247 12081618582809582
|
||||
name type data
|
||||
hits 4 5968846374
|
||||
misses 4 1659178751
|
||||
demand_data_hits 4 4860247322
|
||||
demand_data_misses 4 501499535
|
||||
demand_metadata_hits 4 708608325
|
||||
demand_metadata_misses 4 156591375
|
||||
prefetch_data_hits 4 367047144
|
||||
prefetch_data_misses 4 974529898
|
||||
prefetch_metadata_hits 4 32943583
|
||||
prefetch_metadata_misses 4 26557943
|
||||
mru_hits 4 301176811
|
||||
mru_ghost_hits 4 47066067
|
||||
mfu_hits 4 5520612438
|
||||
mfu_ghost_hits 4 45784009
|
||||
deleted 4 1718937704
|
||||
recycle_miss 4 481222994
|
||||
mutex_miss 4 20575623
|
||||
evict_skip 4 14655903906543
|
||||
evict_l2_cached 4 145310202998272
|
||||
evict_l2_eligible 4 16345402777088
|
||||
evict_l2_ineligible 4 7437226893312
|
||||
hash_elements 4 36617980
|
||||
hash_elements_max 4 36618318
|
||||
hash_collisions 4 554145157
|
||||
hash_chains 4 4187651
|
||||
hash_chain_max 4 26
|
||||
p 4 13963222064
|
||||
c 4 16381258376
|
||||
c_min 4 4194304
|
||||
c_max 4 16884125696
|
||||
size 4 16319887096
|
||||
hdr_size 4 42567864
|
||||
data_size 4 60066304
|
||||
meta_size 4 1701534208
|
||||
other_size 4 1661543168
|
||||
anon_size 4 94720
|
||||
anon_evict_data 4 0
|
||||
anon_evict_metadata 4 0
|
||||
mru_size 4 973099008
|
||||
mru_evict_data 4 9175040
|
||||
mru_evict_metadata 4 32768
|
||||
mru_ghost_size 4 32768
|
||||
mru_ghost_evict_data 4 0
|
||||
mru_ghost_evict_metadata 4 32768
|
||||
mfu_size 4 788406784
|
||||
mfu_evict_data 4 50881024
|
||||
mfu_evict_metadata 4 81920
|
||||
mfu_ghost_size 4 0
|
||||
mfu_ghost_evict_data 4 0
|
||||
mfu_ghost_evict_metadata 4 0
|
||||
l2_hits 4 573868618
|
||||
l2_misses 4 1085309718
|
||||
l2_feeds 4 12182087
|
||||
l2_rw_clash 4 9610
|
||||
l2_read_bytes 4 32695938336768
|
||||
l2_write_bytes 4 2826774778880
|
||||
l2_writes_sent 4 4267687
|
||||
l2_writes_done 4 4267687
|
||||
l2_writes_error 4 0
|
||||
l2_writes_hdr_miss 4 164
|
||||
l2_evict_lock_retry 4 5
|
||||
l2_evict_reading 4 0
|
||||
l2_free_on_write 4 1606914
|
||||
l2_cdata_free_on_write 4 1775
|
||||
l2_abort_lowmem 4 83462
|
||||
l2_cksum_bad 4 393860640
|
||||
l2_io_error 4 53881460
|
||||
l2_size 4 2471466648576
|
||||
l2_asize 4 2461690072064
|
||||
l2_hdr_size 4 12854175552
|
||||
l2_compress_successes 4 12184849
|
||||
l2_compress_zeros 4 0
|
||||
l2_compress_failures 4 0
|
||||
memory_throttle_count 4 0
|
||||
duplicate_buffers 4 0
|
||||
duplicate_buffers_size 4 0
|
||||
duplicate_reads 4 0
|
||||
memory_direct_count 4 5159942
|
||||
memory_indirect_count 4 3034640
|
||||
arc_no_grow 4 0
|
||||
arc_tempreserve 4 0
|
||||
arc_loaned_bytes 4 0
|
||||
arc_prune 4 114554259559
|
||||
arc_meta_used 4 16259820792
|
||||
arc_meta_limit 4 12663094272
|
||||
arc_meta_max 4 18327165696
|
||||
`
|
||||
|
||||
const zfetchstatsContents = `3 1 0x01 11 528 23607270446 12081656848148208
|
||||
name type data
|
||||
hits 4 7812959060
|
||||
misses 4 4154484207
|
||||
colinear_hits 4 1366368
|
||||
colinear_misses 4 4153117839
|
||||
stride_hits 4 7309776732
|
||||
stride_misses 4 222766182
|
||||
reclaim_successes 4 107788388
|
||||
reclaim_failures 4 4045329451
|
||||
streams_resets 4 20989756
|
||||
streams_noresets 4 503182328
|
||||
bogus_streams 4 0
|
||||
`
|
||||
const poolIoContents = `11 3 0x00 1 80 2225326830828 32953476980628
|
||||
nread nwritten reads writes wtime wlentime wupdate rtime rlentime rupdate wcnt rcnt
|
||||
1884160 6450688 22 978 272187126 2850519036 2263669418655 424226814 2850519036 2263669871823 0 0
|
||||
`
|
||||
const objsetContents = `36 1 0x01 7 2160 5214787391 74985931356512
|
||||
name type data
|
||||
dataset_name 7 HOME
|
||||
writes 4 978
|
||||
nwritten 4 6450688
|
||||
reads 4 22
|
||||
nread 4 1884160
|
||||
nunlinks 4 14148
|
||||
nunlinked 4 14147
|
||||
`
|
||||
const objsetV22Contents = `36 1 0x01 7 2160 5214787391 74985931356512
|
||||
name type data
|
||||
dataset_name 7 HOMEV22
|
||||
writes 4 978
|
||||
nwritten 4 6450688
|
||||
reads 4 22
|
||||
nread 4 1884160
|
||||
nunlinks 4 14148
|
||||
nunlinked 4 14147
|
||||
zil_commit_count 4 1
|
||||
zil_commit_writer_count 4 2
|
||||
zil_itx_count 4 3
|
||||
zil_itx_indirect_count 4 4
|
||||
zil_itx_indirect_bytes 4 5
|
||||
zil_itx_copied_count 4 6
|
||||
zil_itx_copied_bytes 4 7
|
||||
zil_itx_needcopy_count 4 8
|
||||
zil_itx_needcopy_bytes 4 9
|
||||
zil_itx_metaslab_normal_count 4 10
|
||||
zil_itx_metaslab_normal_bytes 4 11
|
||||
zil_itx_metaslab_normal_write 4 12
|
||||
zil_itx_metaslab_normal_alloc 4 13
|
||||
zil_itx_metaslab_slog_count 4 14
|
||||
zil_itx_metaslab_slog_bytes 4 15
|
||||
zil_itx_metaslab_slog_write 4 16
|
||||
zil_itx_metaslab_slog_alloc 4 17
|
||||
`
|
||||
const zilContents = `7 1 0x01 14 672 34118481334 437444452158445
|
||||
name type data
|
||||
zil_commit_count 4 77
|
||||
zil_commit_writer_count 4 77
|
||||
zil_itx_count 4 1
|
||||
zil_itx_indirect_count 4 2
|
||||
zil_itx_indirect_bytes 4 3
|
||||
zil_itx_copied_count 4 4
|
||||
zil_itx_copied_bytes 4 5
|
||||
zil_itx_needcopy_count 4 6
|
||||
zil_itx_needcopy_bytes 4 7
|
||||
zil_itx_metaslab_normal_count 4 8
|
||||
zil_itx_metaslab_normal_bytes 4 9
|
||||
zil_itx_metaslab_slog_count 4 10
|
||||
zil_itx_metaslab_slog_bytes 4 11
|
||||
`
|
||||
const fmContents = `0 1 0x01 4 192 34087340971 437562103532892
|
||||
name type data
|
||||
erpt-dropped 4 101
|
||||
erpt-set-failed 4 202
|
||||
fmri-set-failed 4 303
|
||||
payload-set-failed 4 404
|
||||
`
|
||||
const dmuTxContents = `5 1 0x01 11 528 34103260832 437683925071438
|
||||
name type data
|
||||
dmu_tx_assigned 4 39321636
|
||||
dmu_tx_delay 4 111
|
||||
dmu_tx_error 4 222
|
||||
dmu_tx_suspended 4 333
|
||||
dmu_tx_group 4 444
|
||||
dmu_tx_memory_reserve 4 555
|
||||
dmu_tx_memory_reclaim 4 666
|
||||
dmu_tx_dirty_throttle 4 777
|
||||
dmu_tx_dirty_delay 4 888
|
||||
dmu_tx_dirty_over_max 4 999
|
||||
dmu_tx_quota 4 101010
|
||||
`
|
||||
|
||||
const abdstatsContents = `7 1 0x01 21 1008 25476602923533 29223577332204
|
||||
name type data
|
||||
struct_size 4 33840
|
||||
linear_cnt 4 834
|
||||
linear_data_size 4 989696
|
||||
scatter_cnt 4 12
|
||||
scatter_data_size 4 187904
|
||||
scatter_chunk_waste 4 4608
|
||||
scatter_order_0 4 1
|
||||
scatter_order_1 4 21
|
||||
scatter_order_2 4 11
|
||||
scatter_order_3 4 33
|
||||
scatter_order_4 4 44
|
||||
scatter_order_5 4 76
|
||||
scatter_order_6 4 489
|
||||
scatter_order_7 4 237483
|
||||
scatter_order_8 4 233
|
||||
scatter_order_9 4 4411
|
||||
scatter_order_10 4 1023
|
||||
scatter_page_multi_chunk 4 32122
|
||||
scatter_page_multi_zone 4 9930
|
||||
scatter_page_alloc_retry 4 99311
|
||||
scatter_sg_table_retry 4 99221
|
||||
`
|
||||
|
||||
func TestZfsPoolMetrics(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
testKstatPath := tmpDir + "/telegraf/proc/spl/kstat/zfs"
|
||||
err := os.MkdirAll(testKstatPath, 0750)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.MkdirAll(testKstatPath+"/HOME", 0750)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/HOME/io", []byte(poolIoContents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/arcstats", []byte(arcstatsContents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
poolMetrics := getPoolMetrics()
|
||||
|
||||
var acc testutil.Accumulator
|
||||
|
||||
z := &Zfs{KstatPath: testKstatPath, KstatMetrics: []string{"arcstats"}}
|
||||
err = z.Gather(&acc)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.False(t, acc.HasMeasurement("zfs_pool"))
|
||||
acc.Metrics = nil
|
||||
|
||||
z = &Zfs{KstatPath: testKstatPath, KstatMetrics: []string{"arcstats"}, PoolMetrics: true}
|
||||
err = z.Gather(&acc)
|
||||
require.NoError(t, err)
|
||||
|
||||
// one pool, all metrics
|
||||
tags := map[string]string{
|
||||
"pool": "HOME",
|
||||
}
|
||||
|
||||
acc.AssertContainsTaggedFields(t, "zfs_pool", poolMetrics, tags)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/HOME/objset-0x20a", []byte(objsetContents), 0640)
|
||||
require.NoError(t, err)
|
||||
err = os.WriteFile(testKstatPath+"/HOME/objset-0x20b", []byte(objsetV22Contents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
acc.Metrics = nil
|
||||
|
||||
err = z.Gather(&acc)
|
||||
require.NoError(t, err)
|
||||
|
||||
tags["dataset"] = "HOME"
|
||||
poolMetrics = getPoolMetricsNewFormat()
|
||||
acc.AssertContainsTaggedFields(t, "zfs_pool", poolMetrics, tags)
|
||||
|
||||
tags["dataset"] = "HOMEV22"
|
||||
poolMetrics = getPoolMetricsNewFormatV22()
|
||||
acc.AssertContainsTaggedFields(t, "zfs_pool", poolMetrics, tags)
|
||||
}
|
||||
|
||||
func TestZfsGeneratesMetrics(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
testKstatPath := tmpDir + "/telegraf/proc/spl/kstat/zfs"
|
||||
err := os.MkdirAll(testKstatPath, 0750)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.MkdirAll(testKstatPath, 0750)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.MkdirAll(testKstatPath+"/HOME", 0750)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/HOME/io", []byte(""), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/arcstats", []byte(arcstatsContents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/zfetchstats", []byte(zfetchstatsContents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/zil", []byte(zilContents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/fm", []byte(fmContents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/dmu_tx", []byte(dmuTxContents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/abdstats", []byte(abdstatsContents), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
intMetrics := getKstatMetricsAll()
|
||||
|
||||
var acc testutil.Accumulator
|
||||
|
||||
// one pool, all metrics
|
||||
tags := map[string]string{
|
||||
"pools": "HOME",
|
||||
}
|
||||
|
||||
z := &Zfs{KstatPath: testKstatPath}
|
||||
err = z.Gather(&acc)
|
||||
require.NoError(t, err)
|
||||
|
||||
acc.AssertContainsTaggedFields(t, "zfs", intMetrics, tags)
|
||||
acc.Metrics = nil
|
||||
|
||||
// two pools, all metrics
|
||||
err = os.MkdirAll(testKstatPath+"/STORAGE", 0750)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(testKstatPath+"/STORAGE/io", []byte(""), 0640)
|
||||
require.NoError(t, err)
|
||||
|
||||
tags = map[string]string{
|
||||
"pools": "HOME::STORAGE",
|
||||
}
|
||||
|
||||
z = &Zfs{KstatPath: testKstatPath}
|
||||
acc2 := testutil.Accumulator{}
|
||||
err = z.Gather(&acc2)
|
||||
require.NoError(t, err)
|
||||
|
||||
acc2.AssertContainsTaggedFields(t, "zfs", intMetrics, tags)
|
||||
acc2.Metrics = nil
|
||||
|
||||
intMetrics = getKstatMetricsArcOnly()
|
||||
|
||||
// two pools, one metric
|
||||
z = &Zfs{KstatPath: testKstatPath, KstatMetrics: []string{"arcstats"}}
|
||||
acc3 := testutil.Accumulator{}
|
||||
err = z.Gather(&acc3)
|
||||
require.NoError(t, err)
|
||||
|
||||
acc3.AssertContainsTaggedFields(t, "zfs", intMetrics, tags)
|
||||
}
|
||||
|
||||
func TestGetTags(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pools []poolInfo
|
||||
expected map[string]string
|
||||
}{
|
||||
{
|
||||
name: "no pools",
|
||||
expected: map[string]string{"pools": ""},
|
||||
},
|
||||
{
|
||||
name: "single pool",
|
||||
pools: []poolInfo{
|
||||
{"data", "/proc/spl/kstat/zfs/data/objset-0x9288", v2},
|
||||
},
|
||||
expected: map[string]string{"pools": "data"},
|
||||
},
|
||||
{
|
||||
name: "duplicate pool names",
|
||||
pools: []poolInfo{
|
||||
{"pool", "/proc/spl/kstat/zfs/pool/objset-0x23ce1", v2},
|
||||
{"pool", "/proc/spl/kstat/zfs/pool/objset-0x2e", v2},
|
||||
{"data", "/proc/spl/kstat/zfs/data/objset-0x9288", v2},
|
||||
},
|
||||
expected: map[string]string{"pools": "pool::data"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tags := getTags(tc.pools)
|
||||
require.Equal(t, tc.expected, tags)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getKstatMetricsArcOnly() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"arcstats_hits": int64(5968846374),
|
||||
"arcstats_misses": int64(1659178751),
|
||||
"arcstats_demand_data_hits": int64(4860247322),
|
||||
"arcstats_demand_data_misses": int64(501499535),
|
||||
"arcstats_demand_metadata_hits": int64(708608325),
|
||||
"arcstats_demand_metadata_misses": int64(156591375),
|
||||
"arcstats_prefetch_data_hits": int64(367047144),
|
||||
"arcstats_prefetch_data_misses": int64(974529898),
|
||||
"arcstats_prefetch_metadata_hits": int64(32943583),
|
||||
"arcstats_prefetch_metadata_misses": int64(26557943),
|
||||
"arcstats_mru_hits": int64(301176811),
|
||||
"arcstats_mru_ghost_hits": int64(47066067),
|
||||
"arcstats_mfu_hits": int64(5520612438),
|
||||
"arcstats_mfu_ghost_hits": int64(45784009),
|
||||
"arcstats_deleted": int64(1718937704),
|
||||
"arcstats_recycle_miss": int64(481222994),
|
||||
"arcstats_mutex_miss": int64(20575623),
|
||||
"arcstats_evict_skip": int64(14655903906543),
|
||||
"arcstats_evict_l2_cached": int64(145310202998272),
|
||||
"arcstats_evict_l2_eligible": int64(16345402777088),
|
||||
"arcstats_evict_l2_ineligible": int64(7437226893312),
|
||||
"arcstats_hash_elements": int64(36617980),
|
||||
"arcstats_hash_elements_max": int64(36618318),
|
||||
"arcstats_hash_collisions": int64(554145157),
|
||||
"arcstats_hash_chains": int64(4187651),
|
||||
"arcstats_hash_chain_max": int64(26),
|
||||
"arcstats_p": int64(13963222064),
|
||||
"arcstats_c": int64(16381258376),
|
||||
"arcstats_c_min": int64(4194304),
|
||||
"arcstats_c_max": int64(16884125696),
|
||||
"arcstats_size": int64(16319887096),
|
||||
"arcstats_hdr_size": int64(42567864),
|
||||
"arcstats_data_size": int64(60066304),
|
||||
"arcstats_meta_size": int64(1701534208),
|
||||
"arcstats_other_size": int64(1661543168),
|
||||
"arcstats_anon_size": int64(94720),
|
||||
"arcstats_anon_evict_data": int64(0),
|
||||
"arcstats_anon_evict_metadata": int64(0),
|
||||
"arcstats_mru_size": int64(973099008),
|
||||
"arcstats_mru_evict_data": int64(9175040),
|
||||
"arcstats_mru_evict_metadata": int64(32768),
|
||||
"arcstats_mru_ghost_size": int64(32768),
|
||||
"arcstats_mru_ghost_evict_data": int64(0),
|
||||
"arcstats_mru_ghost_evict_metadata": int64(32768),
|
||||
"arcstats_mfu_size": int64(788406784),
|
||||
"arcstats_mfu_evict_data": int64(50881024),
|
||||
"arcstats_mfu_evict_metadata": int64(81920),
|
||||
"arcstats_mfu_ghost_size": int64(0),
|
||||
"arcstats_mfu_ghost_evict_data": int64(0),
|
||||
"arcstats_mfu_ghost_evict_metadata": int64(0),
|
||||
"arcstats_l2_hits": int64(573868618),
|
||||
"arcstats_l2_misses": int64(1085309718),
|
||||
"arcstats_l2_feeds": int64(12182087),
|
||||
"arcstats_l2_rw_clash": int64(9610),
|
||||
"arcstats_l2_read_bytes": int64(32695938336768),
|
||||
"arcstats_l2_write_bytes": int64(2826774778880),
|
||||
"arcstats_l2_writes_sent": int64(4267687),
|
||||
"arcstats_l2_writes_done": int64(4267687),
|
||||
"arcstats_l2_writes_error": int64(0),
|
||||
"arcstats_l2_writes_hdr_miss": int64(164),
|
||||
"arcstats_l2_evict_lock_retry": int64(5),
|
||||
"arcstats_l2_evict_reading": int64(0),
|
||||
"arcstats_l2_free_on_write": int64(1606914),
|
||||
"arcstats_l2_cdata_free_on_write": int64(1775),
|
||||
"arcstats_l2_abort_lowmem": int64(83462),
|
||||
"arcstats_l2_cksum_bad": int64(393860640),
|
||||
"arcstats_l2_io_error": int64(53881460),
|
||||
"arcstats_l2_size": int64(2471466648576),
|
||||
"arcstats_l2_asize": int64(2461690072064),
|
||||
"arcstats_l2_hdr_size": int64(12854175552),
|
||||
"arcstats_l2_compress_successes": int64(12184849),
|
||||
"arcstats_l2_compress_zeros": int64(0),
|
||||
"arcstats_l2_compress_failures": int64(0),
|
||||
"arcstats_memory_throttle_count": int64(0),
|
||||
"arcstats_duplicate_buffers": int64(0),
|
||||
"arcstats_duplicate_buffers_size": int64(0),
|
||||
"arcstats_duplicate_reads": int64(0),
|
||||
"arcstats_memory_direct_count": int64(5159942),
|
||||
"arcstats_memory_indirect_count": int64(3034640),
|
||||
"arcstats_arc_no_grow": int64(0),
|
||||
"arcstats_arc_tempreserve": int64(0),
|
||||
"arcstats_arc_loaned_bytes": int64(0),
|
||||
"arcstats_arc_prune": int64(114554259559),
|
||||
"arcstats_arc_meta_used": int64(16259820792),
|
||||
"arcstats_arc_meta_limit": int64(12663094272),
|
||||
"arcstats_arc_meta_max": int64(18327165696),
|
||||
}
|
||||
}
|
||||
|
||||
func getKstatMetricsAll() map[string]interface{} {
|
||||
otherMetrics := map[string]interface{}{
|
||||
"zfetchstats_hits": int64(7812959060),
|
||||
"zfetchstats_misses": int64(4154484207),
|
||||
"zfetchstats_colinear_hits": int64(1366368),
|
||||
"zfetchstats_colinear_misses": int64(4153117839),
|
||||
"zfetchstats_stride_hits": int64(7309776732),
|
||||
"zfetchstats_stride_misses": int64(222766182),
|
||||
"zfetchstats_reclaim_successes": int64(107788388),
|
||||
"zfetchstats_reclaim_failures": int64(4045329451),
|
||||
"zfetchstats_streams_resets": int64(20989756),
|
||||
"zfetchstats_streams_noresets": int64(503182328),
|
||||
"zfetchstats_bogus_streams": int64(0),
|
||||
"zil_commit_count": int64(77),
|
||||
"zil_commit_writer_count": int64(77),
|
||||
"zil_itx_count": int64(1),
|
||||
"zil_itx_indirect_count": int64(2),
|
||||
"zil_itx_indirect_bytes": int64(3),
|
||||
"zil_itx_copied_count": int64(4),
|
||||
"zil_itx_copied_bytes": int64(5),
|
||||
"zil_itx_needcopy_count": int64(6),
|
||||
"zil_itx_needcopy_bytes": int64(7),
|
||||
"zil_itx_metaslab_normal_count": int64(8),
|
||||
"zil_itx_metaslab_normal_bytes": int64(9),
|
||||
"zil_itx_metaslab_slog_count": int64(10),
|
||||
"zil_itx_metaslab_slog_bytes": int64(11),
|
||||
"fm_erpt-dropped": int64(101),
|
||||
"fm_erpt-set-failed": int64(202),
|
||||
"fm_fmri-set-failed": int64(303),
|
||||
"fm_payload-set-failed": int64(404),
|
||||
"dmu_tx_assigned": int64(39321636),
|
||||
"dmu_tx_delay": int64(111),
|
||||
"dmu_tx_error": int64(222),
|
||||
"dmu_tx_suspended": int64(333),
|
||||
"dmu_tx_group": int64(444),
|
||||
"dmu_tx_memory_reserve": int64(555),
|
||||
"dmu_tx_memory_reclaim": int64(666),
|
||||
"dmu_tx_dirty_throttle": int64(777),
|
||||
"dmu_tx_dirty_delay": int64(888),
|
||||
"dmu_tx_dirty_over_max": int64(999),
|
||||
"dmu_tx_quota": int64(101010),
|
||||
"abdstats_struct_size": int64(33840),
|
||||
"abdstats_linear_cnt": int64(834),
|
||||
"abdstats_linear_data_size": int64(989696),
|
||||
"abdstats_scatter_cnt": int64(12),
|
||||
"abdstats_scatter_data_size": int64(187904),
|
||||
"abdstats_scatter_chunk_waste": int64(4608),
|
||||
"abdstats_scatter_order_0": int64(1),
|
||||
"abdstats_scatter_order_1": int64(21),
|
||||
"abdstats_scatter_order_2": int64(11),
|
||||
"abdstats_scatter_order_3": int64(33),
|
||||
"abdstats_scatter_order_4": int64(44),
|
||||
"abdstats_scatter_order_5": int64(76),
|
||||
"abdstats_scatter_order_6": int64(489),
|
||||
"abdstats_scatter_order_7": int64(237483),
|
||||
"abdstats_scatter_order_8": int64(233),
|
||||
"abdstats_scatter_order_9": int64(4411),
|
||||
"abdstats_scatter_order_10": int64(1023),
|
||||
"abdstats_scatter_page_multi_chunk": int64(32122),
|
||||
"abdstats_scatter_page_multi_zone": int64(9930),
|
||||
"abdstats_scatter_page_alloc_retry": int64(99311),
|
||||
"abdstats_scatter_sg_table_retry": int64(99221),
|
||||
}
|
||||
arcMetrics := getKstatMetricsArcOnly()
|
||||
for k, v := range otherMetrics {
|
||||
arcMetrics[k] = v
|
||||
}
|
||||
return arcMetrics
|
||||
}
|
||||
|
||||
func getPoolMetrics() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"nread": int64(1884160),
|
||||
"nwritten": int64(6450688),
|
||||
"reads": int64(22),
|
||||
"writes": int64(978),
|
||||
"wtime": int64(272187126),
|
||||
"wlentime": int64(2850519036),
|
||||
"wupdate": int64(2263669418655),
|
||||
"rtime": int64(424226814),
|
||||
"rlentime": int64(2850519036),
|
||||
"rupdate": int64(2263669871823),
|
||||
"wcnt": int64(0),
|
||||
"rcnt": int64(0),
|
||||
}
|
||||
}
|
||||
|
||||
func getPoolMetricsNewFormat() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"nread": int64(1884160),
|
||||
"nunlinked": int64(14147),
|
||||
"nunlinks": int64(14148),
|
||||
"nwritten": int64(6450688),
|
||||
"reads": int64(22),
|
||||
"writes": int64(978),
|
||||
}
|
||||
}
|
||||
|
||||
func getPoolMetricsNewFormatV22() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"nread": int64(1884160),
|
||||
"nunlinked": int64(14147),
|
||||
"nunlinks": int64(14148),
|
||||
"nwritten": int64(6450688),
|
||||
"reads": int64(22),
|
||||
"writes": int64(978),
|
||||
"zil_commit_count": int64(1),
|
||||
"zil_commit_writer_count": int64(2),
|
||||
"zil_itx_count": int64(3),
|
||||
"zil_itx_indirect_count": int64(4),
|
||||
"zil_itx_indirect_bytes": int64(5),
|
||||
"zil_itx_copied_count": int64(6),
|
||||
"zil_itx_copied_bytes": int64(7),
|
||||
"zil_itx_needcopy_count": int64(8),
|
||||
"zil_itx_needcopy_bytes": int64(9),
|
||||
"zil_itx_metaslab_normal_count": int64(10),
|
||||
"zil_itx_metaslab_normal_bytes": int64(11),
|
||||
"zil_itx_metaslab_normal_write": int64(12),
|
||||
"zil_itx_metaslab_normal_alloc": int64(13),
|
||||
"zil_itx_metaslab_slog_count": int64(14),
|
||||
"zil_itx_metaslab_slog_bytes": int64(15),
|
||||
"zil_itx_metaslab_slog_write": int64(16),
|
||||
"zil_itx_metaslab_slog_alloc": int64(17),
|
||||
}
|
||||
}
|
25
plugins/inputs/zfs/zfs_other.go
Normal file
25
plugins/inputs/zfs/zfs_other.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
//go:build !linux && !freebsd
|
||||
|
||||
package zfs
|
||||
|
||||
import (
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
type helper struct{} //nolint:unused // not used for "other" OSes, needed for Zfs struct
|
||||
|
||||
func (z *Zfs) Init() error {
|
||||
z.Log.Warn("Current platform is not supported")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*Zfs) Gather(telegraf.Accumulator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("zfs", func() telegraf.Input {
|
||||
return &Zfs{}
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue