diff --git a/collector/fixtures/e2e-64k-page-output.txt b/collector/fixtures/e2e-64k-page-output.txt index c0f5acb2..f1fa240a 100644 --- a/collector/fixtures/e2e-64k-page-output.txt +++ b/collector/fixtures/e2e-64k-page-output.txt @@ -1403,179 +1403,248 @@ node_memory_numa_other_node_total{node="1"} 5.986052692e+10 node_memory_numa_other_node_total{node="2"} 9.86052692e+09 # HELP node_mountstats_nfs_age_seconds_total The age of the NFS mount in seconds. # TYPE node_mountstats_nfs_age_seconds_total counter -node_mountstats_nfs_age_seconds_total{export="192.168.1.1:/srv/test"} 13968 +node_mountstats_nfs_age_seconds_total{export="192.168.1.1:/srv/test",protocol="tcp"} 13968 +node_mountstats_nfs_age_seconds_total{export="192.168.1.1:/srv/test",protocol="udp"} 13968 # HELP node_mountstats_nfs_direct_read_bytes_total Number of bytes read using the read() syscall in O_DIRECT mode. # TYPE node_mountstats_nfs_direct_read_bytes_total counter -node_mountstats_nfs_direct_read_bytes_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_direct_read_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_direct_read_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_direct_write_bytes_total Number of bytes written using the write() syscall in O_DIRECT mode. # TYPE node_mountstats_nfs_direct_write_bytes_total counter -node_mountstats_nfs_direct_write_bytes_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_direct_write_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_direct_write_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_attribute_invalidate_total Number of times cached inode attributes are invalidated. # TYPE node_mountstats_nfs_event_attribute_invalidate_total counter -node_mountstats_nfs_event_attribute_invalidate_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_attribute_invalidate_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_attribute_invalidate_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_data_invalidate_total Number of times an inode cache is cleared. # TYPE node_mountstats_nfs_event_data_invalidate_total counter -node_mountstats_nfs_event_data_invalidate_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_data_invalidate_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_data_invalidate_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_dnode_revalidate_total Number of times cached dentry nodes are re-validated from the server. # TYPE node_mountstats_nfs_event_dnode_revalidate_total counter -node_mountstats_nfs_event_dnode_revalidate_total{export="192.168.1.1:/srv/test"} 226 +node_mountstats_nfs_event_dnode_revalidate_total{export="192.168.1.1:/srv/test",protocol="tcp"} 226 +node_mountstats_nfs_event_dnode_revalidate_total{export="192.168.1.1:/srv/test",protocol="udp"} 226 # HELP node_mountstats_nfs_event_inode_revalidate_total Number of times cached inode attributes are re-validated from the server. # TYPE node_mountstats_nfs_event_inode_revalidate_total counter -node_mountstats_nfs_event_inode_revalidate_total{export="192.168.1.1:/srv/test"} 52 +node_mountstats_nfs_event_inode_revalidate_total{export="192.168.1.1:/srv/test",protocol="tcp"} 52 +node_mountstats_nfs_event_inode_revalidate_total{export="192.168.1.1:/srv/test",protocol="udp"} 52 # HELP node_mountstats_nfs_event_jukebox_delay_total Number of times the NFS server indicated EJUKEBOX; retrieving data from offline storage. # TYPE node_mountstats_nfs_event_jukebox_delay_total counter -node_mountstats_nfs_event_jukebox_delay_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_jukebox_delay_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_jukebox_delay_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_pnfs_read_total Number of NFS v4.1+ pNFS reads. # TYPE node_mountstats_nfs_event_pnfs_read_total counter -node_mountstats_nfs_event_pnfs_read_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_pnfs_read_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_pnfs_read_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_pnfs_write_total Number of NFS v4.1+ pNFS writes. # TYPE node_mountstats_nfs_event_pnfs_write_total counter -node_mountstats_nfs_event_pnfs_write_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_pnfs_write_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_pnfs_write_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_short_read_total Number of times the NFS server gave less data than expected while reading. # TYPE node_mountstats_nfs_event_short_read_total counter -node_mountstats_nfs_event_short_read_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_short_read_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_short_read_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_short_write_total Number of times the NFS server wrote less data than expected while writing. # TYPE node_mountstats_nfs_event_short_write_total counter -node_mountstats_nfs_event_short_write_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_short_write_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_short_write_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_silly_rename_total Number of times a file was removed while still open by another process. # TYPE node_mountstats_nfs_event_silly_rename_total counter -node_mountstats_nfs_event_silly_rename_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_silly_rename_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_silly_rename_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_truncation_total Number of times files have been truncated. # TYPE node_mountstats_nfs_event_truncation_total counter -node_mountstats_nfs_event_truncation_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_truncation_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_truncation_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_access_total Number of times permissions have been checked. # TYPE node_mountstats_nfs_event_vfs_access_total counter -node_mountstats_nfs_event_vfs_access_total{export="192.168.1.1:/srv/test"} 398 +node_mountstats_nfs_event_vfs_access_total{export="192.168.1.1:/srv/test",protocol="tcp"} 398 +node_mountstats_nfs_event_vfs_access_total{export="192.168.1.1:/srv/test",protocol="udp"} 398 # HELP node_mountstats_nfs_event_vfs_file_release_total Number of times files have been closed and released. # TYPE node_mountstats_nfs_event_vfs_file_release_total counter -node_mountstats_nfs_event_vfs_file_release_total{export="192.168.1.1:/srv/test"} 77 +node_mountstats_nfs_event_vfs_file_release_total{export="192.168.1.1:/srv/test",protocol="tcp"} 77 +node_mountstats_nfs_event_vfs_file_release_total{export="192.168.1.1:/srv/test",protocol="udp"} 77 # HELP node_mountstats_nfs_event_vfs_flush_total Number of pending writes that have been forcefully flushed to the server. # TYPE node_mountstats_nfs_event_vfs_flush_total counter -node_mountstats_nfs_event_vfs_flush_total{export="192.168.1.1:/srv/test"} 77 +node_mountstats_nfs_event_vfs_flush_total{export="192.168.1.1:/srv/test",protocol="tcp"} 77 +node_mountstats_nfs_event_vfs_flush_total{export="192.168.1.1:/srv/test",protocol="udp"} 77 # HELP node_mountstats_nfs_event_vfs_fsync_total Number of times fsync() has been called on directories and files. # TYPE node_mountstats_nfs_event_vfs_fsync_total counter -node_mountstats_nfs_event_vfs_fsync_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_fsync_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_fsync_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_getdents_total Number of times directory entries have been read with getdents(). # TYPE node_mountstats_nfs_event_vfs_getdents_total counter -node_mountstats_nfs_event_vfs_getdents_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_getdents_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_getdents_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_lock_total Number of times locking has been attempted on a file. # TYPE node_mountstats_nfs_event_vfs_lock_total counter -node_mountstats_nfs_event_vfs_lock_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_lock_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_lock_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_lookup_total Number of times a directory lookup has occurred. # TYPE node_mountstats_nfs_event_vfs_lookup_total counter -node_mountstats_nfs_event_vfs_lookup_total{export="192.168.1.1:/srv/test"} 13 +node_mountstats_nfs_event_vfs_lookup_total{export="192.168.1.1:/srv/test",protocol="tcp"} 13 +node_mountstats_nfs_event_vfs_lookup_total{export="192.168.1.1:/srv/test",protocol="udp"} 13 # HELP node_mountstats_nfs_event_vfs_open_total Number of times cached inode attributes are invalidated. # TYPE node_mountstats_nfs_event_vfs_open_total counter -node_mountstats_nfs_event_vfs_open_total{export="192.168.1.1:/srv/test"} 1 +node_mountstats_nfs_event_vfs_open_total{export="192.168.1.1:/srv/test",protocol="tcp"} 1 +node_mountstats_nfs_event_vfs_open_total{export="192.168.1.1:/srv/test",protocol="udp"} 1 # HELP node_mountstats_nfs_event_vfs_read_page_total Number of pages read directly via mmap()'d files. # TYPE node_mountstats_nfs_event_vfs_read_page_total counter -node_mountstats_nfs_event_vfs_read_page_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_read_page_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_read_page_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_read_pages_total Number of times a group of pages have been read. # TYPE node_mountstats_nfs_event_vfs_read_pages_total counter -node_mountstats_nfs_event_vfs_read_pages_total{export="192.168.1.1:/srv/test"} 331 +node_mountstats_nfs_event_vfs_read_pages_total{export="192.168.1.1:/srv/test",protocol="tcp"} 331 +node_mountstats_nfs_event_vfs_read_pages_total{export="192.168.1.1:/srv/test",protocol="udp"} 331 # HELP node_mountstats_nfs_event_vfs_setattr_total Number of times directory entries have been read with getdents(). # TYPE node_mountstats_nfs_event_vfs_setattr_total counter -node_mountstats_nfs_event_vfs_setattr_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_setattr_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_setattr_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_update_page_total Number of updates (and potential writes) to pages. # TYPE node_mountstats_nfs_event_vfs_update_page_total counter -node_mountstats_nfs_event_vfs_update_page_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_update_page_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_update_page_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_write_page_total Number of pages written directly via mmap()'d files. # TYPE node_mountstats_nfs_event_vfs_write_page_total counter -node_mountstats_nfs_event_vfs_write_page_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_write_page_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_write_page_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_write_pages_total Number of times a group of pages have been written. # TYPE node_mountstats_nfs_event_vfs_write_pages_total counter -node_mountstats_nfs_event_vfs_write_pages_total{export="192.168.1.1:/srv/test"} 47 +node_mountstats_nfs_event_vfs_write_pages_total{export="192.168.1.1:/srv/test",protocol="tcp"} 47 +node_mountstats_nfs_event_vfs_write_pages_total{export="192.168.1.1:/srv/test",protocol="udp"} 47 # HELP node_mountstats_nfs_event_write_extension_total Number of times a file has been grown due to writes beyond its existing end. # TYPE node_mountstats_nfs_event_write_extension_total counter -node_mountstats_nfs_event_write_extension_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_write_extension_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_write_extension_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_major_timeouts_total Number of times a request has had a major timeout for a given operation. # TYPE node_mountstats_nfs_operations_major_timeouts_total counter -node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="READ"} 0 -node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_queue_time_seconds_total Duration all requests spent queued for transmission for a given operation before they were sent, in seconds. # TYPE node_mountstats_nfs_operations_queue_time_seconds_total counter -node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ"} 0.006 -node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 0.006 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 0.006 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_received_bytes_total Number of bytes received for a given operation, including RPC headers and payload. # TYPE node_mountstats_nfs_operations_received_bytes_total counter -node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="READ"} 1.210292152e+09 -node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 1.210292152e+09 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 1.210292152e+09 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_request_time_seconds_total Duration all requests took from when a request was enqueued to when it was completely handled for a given operation, in seconds. # TYPE node_mountstats_nfs_operations_request_time_seconds_total counter -node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ"} 79.407 -node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 79.407 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 79.407 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_requests_total Number of requests performed for a given operation. # TYPE node_mountstats_nfs_operations_requests_total counter -node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="READ"} 1298 -node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 1298 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 1298 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_response_time_seconds_total Duration all requests took to get a reply back after a request for a given operation was transmitted, in seconds. # TYPE node_mountstats_nfs_operations_response_time_seconds_total counter -node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ"} 79.386 -node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 79.386 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 79.386 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_sent_bytes_total Number of bytes sent for a given operation, including RPC headers and payload. # TYPE node_mountstats_nfs_operations_sent_bytes_total counter -node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="READ"} 207680 -node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 207680 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 207680 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_transmissions_total Number of times an actual RPC request has been transmitted for a given operation. # TYPE node_mountstats_nfs_operations_transmissions_total counter -node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="READ"} 1298 -node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 1298 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 1298 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_read_bytes_total Number of bytes read using the read() syscall. # TYPE node_mountstats_nfs_read_bytes_total counter -node_mountstats_nfs_read_bytes_total{export="192.168.1.1:/srv/test"} 1.20764023e+09 +node_mountstats_nfs_read_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 1.20764023e+09 +node_mountstats_nfs_read_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 1.20764023e+09 # HELP node_mountstats_nfs_read_pages_total Number of pages read directly via mmap()'d files. # TYPE node_mountstats_nfs_read_pages_total counter -node_mountstats_nfs_read_pages_total{export="192.168.1.1:/srv/test"} 295483 +node_mountstats_nfs_read_pages_total{export="192.168.1.1:/srv/test",protocol="tcp"} 295483 +node_mountstats_nfs_read_pages_total{export="192.168.1.1:/srv/test",protocol="udp"} 295483 # HELP node_mountstats_nfs_total_read_bytes_total Number of bytes read from the NFS server, in total. # TYPE node_mountstats_nfs_total_read_bytes_total counter -node_mountstats_nfs_total_read_bytes_total{export="192.168.1.1:/srv/test"} 1.210214218e+09 +node_mountstats_nfs_total_read_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 1.210214218e+09 +node_mountstats_nfs_total_read_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 1.210214218e+09 # HELP node_mountstats_nfs_total_write_bytes_total Number of bytes written to the NFS server, in total. # TYPE node_mountstats_nfs_total_write_bytes_total counter -node_mountstats_nfs_total_write_bytes_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_total_write_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_total_write_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_backlog_queue_total Total number of items added to the RPC backlog queue. # TYPE node_mountstats_nfs_transport_backlog_queue_total counter -node_mountstats_nfs_transport_backlog_queue_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_transport_backlog_queue_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_transport_backlog_queue_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_bad_transaction_ids_total Number of times the NFS server sent a response with a transaction ID unknown to this client. # TYPE node_mountstats_nfs_transport_bad_transaction_ids_total counter -node_mountstats_nfs_transport_bad_transaction_ids_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_transport_bad_transaction_ids_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_transport_bad_transaction_ids_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_bind_total Number of times the client has had to establish a connection from scratch to the NFS server. # TYPE node_mountstats_nfs_transport_bind_total counter -node_mountstats_nfs_transport_bind_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_transport_bind_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_transport_bind_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_connect_total Number of times the client has made a TCP connection to the NFS server. # TYPE node_mountstats_nfs_transport_connect_total counter -node_mountstats_nfs_transport_connect_total{export="192.168.1.1:/srv/test"} 1 +node_mountstats_nfs_transport_connect_total{export="192.168.1.1:/srv/test",protocol="tcp"} 1 +node_mountstats_nfs_transport_connect_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_idle_time_seconds Duration since the NFS mount last saw any RPC traffic, in seconds. # TYPE node_mountstats_nfs_transport_idle_time_seconds gauge -node_mountstats_nfs_transport_idle_time_seconds{export="192.168.1.1:/srv/test"} 11 +node_mountstats_nfs_transport_idle_time_seconds{export="192.168.1.1:/srv/test",protocol="tcp"} 11 +node_mountstats_nfs_transport_idle_time_seconds{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_maximum_rpc_slots Maximum number of simultaneously active RPC requests ever used. # TYPE node_mountstats_nfs_transport_maximum_rpc_slots gauge -node_mountstats_nfs_transport_maximum_rpc_slots{export="192.168.1.1:/srv/test"} 24 +node_mountstats_nfs_transport_maximum_rpc_slots{export="192.168.1.1:/srv/test",protocol="tcp"} 24 +node_mountstats_nfs_transport_maximum_rpc_slots{export="192.168.1.1:/srv/test",protocol="udp"} 24 # HELP node_mountstats_nfs_transport_pending_queue_total Total number of items added to the RPC transmission pending queue. # TYPE node_mountstats_nfs_transport_pending_queue_total counter -node_mountstats_nfs_transport_pending_queue_total{export="192.168.1.1:/srv/test"} 5726 +node_mountstats_nfs_transport_pending_queue_total{export="192.168.1.1:/srv/test",protocol="tcp"} 5726 +node_mountstats_nfs_transport_pending_queue_total{export="192.168.1.1:/srv/test",protocol="udp"} 5726 # HELP node_mountstats_nfs_transport_receives_total Number of RPC responses for this mount received from the NFS server. # TYPE node_mountstats_nfs_transport_receives_total counter -node_mountstats_nfs_transport_receives_total{export="192.168.1.1:/srv/test"} 6428 +node_mountstats_nfs_transport_receives_total{export="192.168.1.1:/srv/test",protocol="tcp"} 6428 +node_mountstats_nfs_transport_receives_total{export="192.168.1.1:/srv/test",protocol="udp"} 6428 # HELP node_mountstats_nfs_transport_sending_queue_total Total number of items added to the RPC transmission sending queue. # TYPE node_mountstats_nfs_transport_sending_queue_total counter -node_mountstats_nfs_transport_sending_queue_total{export="192.168.1.1:/srv/test"} 26 +node_mountstats_nfs_transport_sending_queue_total{export="192.168.1.1:/srv/test",protocol="tcp"} 26 +node_mountstats_nfs_transport_sending_queue_total{export="192.168.1.1:/srv/test",protocol="udp"} 26 # HELP node_mountstats_nfs_transport_sends_total Number of RPC requests for this mount sent to the NFS server. # TYPE node_mountstats_nfs_transport_sends_total counter -node_mountstats_nfs_transport_sends_total{export="192.168.1.1:/srv/test"} 6428 +node_mountstats_nfs_transport_sends_total{export="192.168.1.1:/srv/test",protocol="tcp"} 6428 +node_mountstats_nfs_transport_sends_total{export="192.168.1.1:/srv/test",protocol="udp"} 6428 # HELP node_mountstats_nfs_write_bytes_total Number of bytes written using the write() syscall. # TYPE node_mountstats_nfs_write_bytes_total counter -node_mountstats_nfs_write_bytes_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_write_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_write_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_write_pages_total Number of pages written directly via mmap()'d files. # TYPE node_mountstats_nfs_write_pages_total counter -node_mountstats_nfs_write_pages_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_write_pages_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_write_pages_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_netstat_Icmp6_InErrors Statistic Icmp6InErrors. # TYPE node_netstat_Icmp6_InErrors untyped node_netstat_Icmp6_InErrors 0 diff --git a/collector/fixtures/e2e-output.txt b/collector/fixtures/e2e-output.txt index 326890f5..bf103204 100644 --- a/collector/fixtures/e2e-output.txt +++ b/collector/fixtures/e2e-output.txt @@ -1403,179 +1403,248 @@ node_memory_numa_other_node_total{node="1"} 5.986052692e+10 node_memory_numa_other_node_total{node="2"} 9.86052692e+09 # HELP node_mountstats_nfs_age_seconds_total The age of the NFS mount in seconds. # TYPE node_mountstats_nfs_age_seconds_total counter -node_mountstats_nfs_age_seconds_total{export="192.168.1.1:/srv/test"} 13968 +node_mountstats_nfs_age_seconds_total{export="192.168.1.1:/srv/test",protocol="tcp"} 13968 +node_mountstats_nfs_age_seconds_total{export="192.168.1.1:/srv/test",protocol="udp"} 13968 # HELP node_mountstats_nfs_direct_read_bytes_total Number of bytes read using the read() syscall in O_DIRECT mode. # TYPE node_mountstats_nfs_direct_read_bytes_total counter -node_mountstats_nfs_direct_read_bytes_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_direct_read_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_direct_read_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_direct_write_bytes_total Number of bytes written using the write() syscall in O_DIRECT mode. # TYPE node_mountstats_nfs_direct_write_bytes_total counter -node_mountstats_nfs_direct_write_bytes_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_direct_write_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_direct_write_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_attribute_invalidate_total Number of times cached inode attributes are invalidated. # TYPE node_mountstats_nfs_event_attribute_invalidate_total counter -node_mountstats_nfs_event_attribute_invalidate_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_attribute_invalidate_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_attribute_invalidate_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_data_invalidate_total Number of times an inode cache is cleared. # TYPE node_mountstats_nfs_event_data_invalidate_total counter -node_mountstats_nfs_event_data_invalidate_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_data_invalidate_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_data_invalidate_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_dnode_revalidate_total Number of times cached dentry nodes are re-validated from the server. # TYPE node_mountstats_nfs_event_dnode_revalidate_total counter -node_mountstats_nfs_event_dnode_revalidate_total{export="192.168.1.1:/srv/test"} 226 +node_mountstats_nfs_event_dnode_revalidate_total{export="192.168.1.1:/srv/test",protocol="tcp"} 226 +node_mountstats_nfs_event_dnode_revalidate_total{export="192.168.1.1:/srv/test",protocol="udp"} 226 # HELP node_mountstats_nfs_event_inode_revalidate_total Number of times cached inode attributes are re-validated from the server. # TYPE node_mountstats_nfs_event_inode_revalidate_total counter -node_mountstats_nfs_event_inode_revalidate_total{export="192.168.1.1:/srv/test"} 52 +node_mountstats_nfs_event_inode_revalidate_total{export="192.168.1.1:/srv/test",protocol="tcp"} 52 +node_mountstats_nfs_event_inode_revalidate_total{export="192.168.1.1:/srv/test",protocol="udp"} 52 # HELP node_mountstats_nfs_event_jukebox_delay_total Number of times the NFS server indicated EJUKEBOX; retrieving data from offline storage. # TYPE node_mountstats_nfs_event_jukebox_delay_total counter -node_mountstats_nfs_event_jukebox_delay_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_jukebox_delay_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_jukebox_delay_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_pnfs_read_total Number of NFS v4.1+ pNFS reads. # TYPE node_mountstats_nfs_event_pnfs_read_total counter -node_mountstats_nfs_event_pnfs_read_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_pnfs_read_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_pnfs_read_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_pnfs_write_total Number of NFS v4.1+ pNFS writes. # TYPE node_mountstats_nfs_event_pnfs_write_total counter -node_mountstats_nfs_event_pnfs_write_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_pnfs_write_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_pnfs_write_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_short_read_total Number of times the NFS server gave less data than expected while reading. # TYPE node_mountstats_nfs_event_short_read_total counter -node_mountstats_nfs_event_short_read_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_short_read_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_short_read_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_short_write_total Number of times the NFS server wrote less data than expected while writing. # TYPE node_mountstats_nfs_event_short_write_total counter -node_mountstats_nfs_event_short_write_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_short_write_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_short_write_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_silly_rename_total Number of times a file was removed while still open by another process. # TYPE node_mountstats_nfs_event_silly_rename_total counter -node_mountstats_nfs_event_silly_rename_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_silly_rename_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_silly_rename_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_truncation_total Number of times files have been truncated. # TYPE node_mountstats_nfs_event_truncation_total counter -node_mountstats_nfs_event_truncation_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_truncation_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_truncation_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_access_total Number of times permissions have been checked. # TYPE node_mountstats_nfs_event_vfs_access_total counter -node_mountstats_nfs_event_vfs_access_total{export="192.168.1.1:/srv/test"} 398 +node_mountstats_nfs_event_vfs_access_total{export="192.168.1.1:/srv/test",protocol="tcp"} 398 +node_mountstats_nfs_event_vfs_access_total{export="192.168.1.1:/srv/test",protocol="udp"} 398 # HELP node_mountstats_nfs_event_vfs_file_release_total Number of times files have been closed and released. # TYPE node_mountstats_nfs_event_vfs_file_release_total counter -node_mountstats_nfs_event_vfs_file_release_total{export="192.168.1.1:/srv/test"} 77 +node_mountstats_nfs_event_vfs_file_release_total{export="192.168.1.1:/srv/test",protocol="tcp"} 77 +node_mountstats_nfs_event_vfs_file_release_total{export="192.168.1.1:/srv/test",protocol="udp"} 77 # HELP node_mountstats_nfs_event_vfs_flush_total Number of pending writes that have been forcefully flushed to the server. # TYPE node_mountstats_nfs_event_vfs_flush_total counter -node_mountstats_nfs_event_vfs_flush_total{export="192.168.1.1:/srv/test"} 77 +node_mountstats_nfs_event_vfs_flush_total{export="192.168.1.1:/srv/test",protocol="tcp"} 77 +node_mountstats_nfs_event_vfs_flush_total{export="192.168.1.1:/srv/test",protocol="udp"} 77 # HELP node_mountstats_nfs_event_vfs_fsync_total Number of times fsync() has been called on directories and files. # TYPE node_mountstats_nfs_event_vfs_fsync_total counter -node_mountstats_nfs_event_vfs_fsync_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_fsync_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_fsync_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_getdents_total Number of times directory entries have been read with getdents(). # TYPE node_mountstats_nfs_event_vfs_getdents_total counter -node_mountstats_nfs_event_vfs_getdents_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_getdents_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_getdents_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_lock_total Number of times locking has been attempted on a file. # TYPE node_mountstats_nfs_event_vfs_lock_total counter -node_mountstats_nfs_event_vfs_lock_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_lock_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_lock_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_lookup_total Number of times a directory lookup has occurred. # TYPE node_mountstats_nfs_event_vfs_lookup_total counter -node_mountstats_nfs_event_vfs_lookup_total{export="192.168.1.1:/srv/test"} 13 +node_mountstats_nfs_event_vfs_lookup_total{export="192.168.1.1:/srv/test",protocol="tcp"} 13 +node_mountstats_nfs_event_vfs_lookup_total{export="192.168.1.1:/srv/test",protocol="udp"} 13 # HELP node_mountstats_nfs_event_vfs_open_total Number of times cached inode attributes are invalidated. # TYPE node_mountstats_nfs_event_vfs_open_total counter -node_mountstats_nfs_event_vfs_open_total{export="192.168.1.1:/srv/test"} 1 +node_mountstats_nfs_event_vfs_open_total{export="192.168.1.1:/srv/test",protocol="tcp"} 1 +node_mountstats_nfs_event_vfs_open_total{export="192.168.1.1:/srv/test",protocol="udp"} 1 # HELP node_mountstats_nfs_event_vfs_read_page_total Number of pages read directly via mmap()'d files. # TYPE node_mountstats_nfs_event_vfs_read_page_total counter -node_mountstats_nfs_event_vfs_read_page_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_read_page_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_read_page_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_read_pages_total Number of times a group of pages have been read. # TYPE node_mountstats_nfs_event_vfs_read_pages_total counter -node_mountstats_nfs_event_vfs_read_pages_total{export="192.168.1.1:/srv/test"} 331 +node_mountstats_nfs_event_vfs_read_pages_total{export="192.168.1.1:/srv/test",protocol="tcp"} 331 +node_mountstats_nfs_event_vfs_read_pages_total{export="192.168.1.1:/srv/test",protocol="udp"} 331 # HELP node_mountstats_nfs_event_vfs_setattr_total Number of times directory entries have been read with getdents(). # TYPE node_mountstats_nfs_event_vfs_setattr_total counter -node_mountstats_nfs_event_vfs_setattr_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_setattr_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_setattr_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_update_page_total Number of updates (and potential writes) to pages. # TYPE node_mountstats_nfs_event_vfs_update_page_total counter -node_mountstats_nfs_event_vfs_update_page_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_update_page_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_update_page_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_write_page_total Number of pages written directly via mmap()'d files. # TYPE node_mountstats_nfs_event_vfs_write_page_total counter -node_mountstats_nfs_event_vfs_write_page_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_vfs_write_page_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_vfs_write_page_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_event_vfs_write_pages_total Number of times a group of pages have been written. # TYPE node_mountstats_nfs_event_vfs_write_pages_total counter -node_mountstats_nfs_event_vfs_write_pages_total{export="192.168.1.1:/srv/test"} 47 +node_mountstats_nfs_event_vfs_write_pages_total{export="192.168.1.1:/srv/test",protocol="tcp"} 47 +node_mountstats_nfs_event_vfs_write_pages_total{export="192.168.1.1:/srv/test",protocol="udp"} 47 # HELP node_mountstats_nfs_event_write_extension_total Number of times a file has been grown due to writes beyond its existing end. # TYPE node_mountstats_nfs_event_write_extension_total counter -node_mountstats_nfs_event_write_extension_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_event_write_extension_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_event_write_extension_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_major_timeouts_total Number of times a request has had a major timeout for a given operation. # TYPE node_mountstats_nfs_operations_major_timeouts_total counter -node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="READ"} 0 -node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_major_timeouts_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_queue_time_seconds_total Duration all requests spent queued for transmission for a given operation before they were sent, in seconds. # TYPE node_mountstats_nfs_operations_queue_time_seconds_total counter -node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ"} 0.006 -node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 0.006 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 0.006 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_queue_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_received_bytes_total Number of bytes received for a given operation, including RPC headers and payload. # TYPE node_mountstats_nfs_operations_received_bytes_total counter -node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="READ"} 1.210292152e+09 -node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 1.210292152e+09 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 1.210292152e+09 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_received_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_request_time_seconds_total Duration all requests took from when a request was enqueued to when it was completely handled for a given operation, in seconds. # TYPE node_mountstats_nfs_operations_request_time_seconds_total counter -node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ"} 79.407 -node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 79.407 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 79.407 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_request_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_requests_total Number of requests performed for a given operation. # TYPE node_mountstats_nfs_operations_requests_total counter -node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="READ"} 1298 -node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 1298 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 1298 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_requests_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_response_time_seconds_total Duration all requests took to get a reply back after a request for a given operation was transmitted, in seconds. # TYPE node_mountstats_nfs_operations_response_time_seconds_total counter -node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ"} 79.386 -node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 79.386 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 79.386 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_response_time_seconds_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_sent_bytes_total Number of bytes sent for a given operation, including RPC headers and payload. # TYPE node_mountstats_nfs_operations_sent_bytes_total counter -node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="READ"} 207680 -node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 207680 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 207680 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_sent_bytes_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_operations_transmissions_total Number of times an actual RPC request has been transmitted for a given operation. # TYPE node_mountstats_nfs_operations_transmissions_total counter -node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="NULL"} 0 -node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="READ"} 1298 -node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="WRITE"} 0 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="tcp"} 0 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="NULL",protocol="udp"} 0 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="READ",protocol="tcp"} 1298 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="READ",protocol="udp"} 1298 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="tcp"} 0 +node_mountstats_nfs_operations_transmissions_total{export="192.168.1.1:/srv/test",operation="WRITE",protocol="udp"} 0 # HELP node_mountstats_nfs_read_bytes_total Number of bytes read using the read() syscall. # TYPE node_mountstats_nfs_read_bytes_total counter -node_mountstats_nfs_read_bytes_total{export="192.168.1.1:/srv/test"} 1.20764023e+09 +node_mountstats_nfs_read_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 1.20764023e+09 +node_mountstats_nfs_read_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 1.20764023e+09 # HELP node_mountstats_nfs_read_pages_total Number of pages read directly via mmap()'d files. # TYPE node_mountstats_nfs_read_pages_total counter -node_mountstats_nfs_read_pages_total{export="192.168.1.1:/srv/test"} 295483 +node_mountstats_nfs_read_pages_total{export="192.168.1.1:/srv/test",protocol="tcp"} 295483 +node_mountstats_nfs_read_pages_total{export="192.168.1.1:/srv/test",protocol="udp"} 295483 # HELP node_mountstats_nfs_total_read_bytes_total Number of bytes read from the NFS server, in total. # TYPE node_mountstats_nfs_total_read_bytes_total counter -node_mountstats_nfs_total_read_bytes_total{export="192.168.1.1:/srv/test"} 1.210214218e+09 +node_mountstats_nfs_total_read_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 1.210214218e+09 +node_mountstats_nfs_total_read_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 1.210214218e+09 # HELP node_mountstats_nfs_total_write_bytes_total Number of bytes written to the NFS server, in total. # TYPE node_mountstats_nfs_total_write_bytes_total counter -node_mountstats_nfs_total_write_bytes_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_total_write_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_total_write_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_backlog_queue_total Total number of items added to the RPC backlog queue. # TYPE node_mountstats_nfs_transport_backlog_queue_total counter -node_mountstats_nfs_transport_backlog_queue_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_transport_backlog_queue_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_transport_backlog_queue_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_bad_transaction_ids_total Number of times the NFS server sent a response with a transaction ID unknown to this client. # TYPE node_mountstats_nfs_transport_bad_transaction_ids_total counter -node_mountstats_nfs_transport_bad_transaction_ids_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_transport_bad_transaction_ids_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_transport_bad_transaction_ids_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_bind_total Number of times the client has had to establish a connection from scratch to the NFS server. # TYPE node_mountstats_nfs_transport_bind_total counter -node_mountstats_nfs_transport_bind_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_transport_bind_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_transport_bind_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_connect_total Number of times the client has made a TCP connection to the NFS server. # TYPE node_mountstats_nfs_transport_connect_total counter -node_mountstats_nfs_transport_connect_total{export="192.168.1.1:/srv/test"} 1 +node_mountstats_nfs_transport_connect_total{export="192.168.1.1:/srv/test",protocol="tcp"} 1 +node_mountstats_nfs_transport_connect_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_idle_time_seconds Duration since the NFS mount last saw any RPC traffic, in seconds. # TYPE node_mountstats_nfs_transport_idle_time_seconds gauge -node_mountstats_nfs_transport_idle_time_seconds{export="192.168.1.1:/srv/test"} 11 +node_mountstats_nfs_transport_idle_time_seconds{export="192.168.1.1:/srv/test",protocol="tcp"} 11 +node_mountstats_nfs_transport_idle_time_seconds{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_transport_maximum_rpc_slots Maximum number of simultaneously active RPC requests ever used. # TYPE node_mountstats_nfs_transport_maximum_rpc_slots gauge -node_mountstats_nfs_transport_maximum_rpc_slots{export="192.168.1.1:/srv/test"} 24 +node_mountstats_nfs_transport_maximum_rpc_slots{export="192.168.1.1:/srv/test",protocol="tcp"} 24 +node_mountstats_nfs_transport_maximum_rpc_slots{export="192.168.1.1:/srv/test",protocol="udp"} 24 # HELP node_mountstats_nfs_transport_pending_queue_total Total number of items added to the RPC transmission pending queue. # TYPE node_mountstats_nfs_transport_pending_queue_total counter -node_mountstats_nfs_transport_pending_queue_total{export="192.168.1.1:/srv/test"} 5726 +node_mountstats_nfs_transport_pending_queue_total{export="192.168.1.1:/srv/test",protocol="tcp"} 5726 +node_mountstats_nfs_transport_pending_queue_total{export="192.168.1.1:/srv/test",protocol="udp"} 5726 # HELP node_mountstats_nfs_transport_receives_total Number of RPC responses for this mount received from the NFS server. # TYPE node_mountstats_nfs_transport_receives_total counter -node_mountstats_nfs_transport_receives_total{export="192.168.1.1:/srv/test"} 6428 +node_mountstats_nfs_transport_receives_total{export="192.168.1.1:/srv/test",protocol="tcp"} 6428 +node_mountstats_nfs_transport_receives_total{export="192.168.1.1:/srv/test",protocol="udp"} 6428 # HELP node_mountstats_nfs_transport_sending_queue_total Total number of items added to the RPC transmission sending queue. # TYPE node_mountstats_nfs_transport_sending_queue_total counter -node_mountstats_nfs_transport_sending_queue_total{export="192.168.1.1:/srv/test"} 26 +node_mountstats_nfs_transport_sending_queue_total{export="192.168.1.1:/srv/test",protocol="tcp"} 26 +node_mountstats_nfs_transport_sending_queue_total{export="192.168.1.1:/srv/test",protocol="udp"} 26 # HELP node_mountstats_nfs_transport_sends_total Number of RPC requests for this mount sent to the NFS server. # TYPE node_mountstats_nfs_transport_sends_total counter -node_mountstats_nfs_transport_sends_total{export="192.168.1.1:/srv/test"} 6428 +node_mountstats_nfs_transport_sends_total{export="192.168.1.1:/srv/test",protocol="tcp"} 6428 +node_mountstats_nfs_transport_sends_total{export="192.168.1.1:/srv/test",protocol="udp"} 6428 # HELP node_mountstats_nfs_write_bytes_total Number of bytes written using the write() syscall. # TYPE node_mountstats_nfs_write_bytes_total counter -node_mountstats_nfs_write_bytes_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_write_bytes_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_write_bytes_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_mountstats_nfs_write_pages_total Number of pages written directly via mmap()'d files. # TYPE node_mountstats_nfs_write_pages_total counter -node_mountstats_nfs_write_pages_total{export="192.168.1.1:/srv/test"} 0 +node_mountstats_nfs_write_pages_total{export="192.168.1.1:/srv/test",protocol="tcp"} 0 +node_mountstats_nfs_write_pages_total{export="192.168.1.1:/srv/test",protocol="udp"} 0 # HELP node_netstat_Icmp6_InErrors Statistic Icmp6InErrors. # TYPE node_netstat_Icmp6_InErrors untyped node_netstat_Icmp6_InErrors 0 diff --git a/collector/fixtures/proc/10/mountstats b/collector/fixtures/proc/10/mountstats index fdda6765..ddddcd34 100644 --- a/collector/fixtures/proc/10/mountstats +++ b/collector/fixtures/proc/10/mountstats @@ -32,3 +32,17 @@ device 192.168.1.1:/srv/test mounted on /mnt/nfs/test-dupe with fstype nfs4 stat READ: 1298 1298 0 207680 1210292152 6 79386 79407 WRITE: 0 0 0 0 0 0 0 0 +device 192.168.1.1:/srv/test mounted on /mnt/nfs/test-dupe with fstype nfs4 statvers=1.1 + opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=udp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none + age: 13968 + caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 + nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured + sec: flavor=1,pseudoflavor=1 + events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 + bytes: 1207640230 0 0 0 1210214218 0 295483 0 + RPC iostats version: 1.0 p/v: 100003/4 (nfs) + xprt: udp 832 0 6428 6428 0 12154 0 24 26 5726 + per-op statistics + NULL: 0 0 0 0 0 0 0 0 + READ: 1298 1298 0 207680 1210292152 6 79386 79407 + WRITE: 0 0 0 0 0 0 0 0 diff --git a/collector/mountstats_linux.go b/collector/mountstats_linux.go index 62e715df..561c7aa9 100644 --- a/collector/mountstats_linux.go +++ b/collector/mountstats_linux.go @@ -15,7 +15,6 @@ package collector import ( "fmt" - "sort" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/log" @@ -89,6 +88,12 @@ type mountStatsCollector struct { proc procfs.Proc } +// used to uniquely identify an NFS mount to prevent duplicates +type nfsDeviceIdentifier struct { + Device string + Protocol string +} + func init() { registerCollector("mountstats", defaultDisabled, NewMountStatsCollector) } @@ -111,8 +116,8 @@ func NewMountStatsCollector() (Collector, error) { ) var ( - labels = []string{"export"} - opLabels = []string{"export", "operation"} + labels = []string{"export", "protocol"} + opLabels = []string{"export", "protocol", "operation"} ) return &mountStatsCollector{ @@ -496,7 +501,9 @@ func (c *mountStatsCollector) Update(ch chan<- prometheus.Metric) error { if err != nil { return fmt.Errorf("failed to parse mountstats: %v", err) } - var deviceList []string + + // store all seen nfsDeviceIdentifiers for deduplication + deviceList := make(map[nfsDeviceIdentifier]bool) for _, m := range mounts { // For the time being, only NFS statistics are available via this mechanism @@ -505,25 +512,27 @@ func (c *mountStatsCollector) Update(ch chan<- prometheus.Metric) error { continue } - sort.Strings(deviceList) - i := sort.SearchStrings(deviceList, m.Device) - if i < len(deviceList) && deviceList[i] == m.Device { - log.Debugf("Skipping duplicate device entry %q", m.Device) - } else { - deviceList = append(deviceList, m.Device) - c.updateNFSStats(ch, m.Device, stats) + deviceIdentifier := nfsDeviceIdentifier{m.Device, stats.Transport.Protocol} + i := deviceList[deviceIdentifier] + if i { + log.Debugf("Skipping duplicate device entry %q", deviceIdentifier) + continue } + + deviceList[deviceIdentifier] = true + c.updateNFSStats(ch, m.Device, stats.Transport.Protocol, stats) } return nil } -func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export string, s *procfs.MountStatsNFS) { +func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export string, protocol string, s *procfs.MountStatsNFS) { ch <- prometheus.MustNewConstMetric( c.NFSAgeSecondsTotal, prometheus.CounterValue, s.Age.Seconds(), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -531,6 +540,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Bytes.Read), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -538,6 +548,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Bytes.Write), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -545,6 +556,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Bytes.DirectRead), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -552,6 +564,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Bytes.DirectWrite), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -559,6 +572,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Bytes.ReadTotal), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -566,6 +580,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Bytes.WriteTotal), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -573,6 +588,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Bytes.ReadPages), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -580,6 +596,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Bytes.WritePages), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -587,6 +604,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Transport.Bind), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -594,6 +612,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Transport.Connect), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -601,6 +620,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.GaugeValue, s.Transport.IdleTime.Seconds(), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -608,6 +628,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Transport.Sends), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -615,6 +636,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Transport.Receives), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -622,6 +644,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Transport.BadTransactionIDs), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -629,6 +652,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Transport.CumulativeBacklog), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -636,6 +660,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.GaugeValue, float64(s.Transport.MaximumRPCSlotsUsed), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -643,6 +668,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Transport.CumulativeSendingQueue), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -650,6 +676,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Transport.CumulativePendingQueue), export, + protocol, ) for _, op := range s.Operations { @@ -658,6 +685,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(op.Requests), export, + protocol, op.Operation, ) @@ -666,6 +694,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(op.Transmissions), export, + protocol, op.Operation, ) @@ -674,6 +703,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(op.MajorTimeouts), export, + protocol, op.Operation, ) @@ -682,6 +712,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(op.BytesSent), export, + protocol, op.Operation, ) @@ -690,6 +721,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(op.BytesReceived), export, + protocol, op.Operation, ) @@ -698,6 +730,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, op.CumulativeQueueTime.Seconds(), export, + protocol, op.Operation, ) @@ -706,6 +739,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, op.CumulativeTotalResponseTime.Seconds(), export, + protocol, op.Operation, ) @@ -714,6 +748,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, op.CumulativeTotalRequestTime.Seconds(), export, + protocol, op.Operation, ) } @@ -723,6 +758,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.InodeRevalidate), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -730,6 +766,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.DnodeRevalidate), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -737,6 +774,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.DataInvalidate), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -744,6 +782,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.AttributeInvalidate), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -751,6 +790,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSOpen), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -758,6 +798,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSLookup), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -765,6 +806,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSAccess), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -772,6 +814,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSUpdatePage), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -779,6 +822,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSReadPage), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -786,6 +830,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSReadPages), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -793,6 +838,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSWritePage), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -800,6 +846,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSWritePages), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -807,6 +854,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSGetdents), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -814,6 +862,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSSetattr), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -821,6 +870,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSFlush), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -828,6 +878,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSFsync), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -835,6 +886,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSLock), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -842,6 +894,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.VFSFileRelease), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -849,6 +902,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.Truncation), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -856,6 +910,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.WriteExtension), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -863,6 +918,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.SillyRename), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -870,6 +926,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.ShortRead), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -877,6 +934,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.ShortWrite), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -884,6 +942,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.JukeboxDelay), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -891,6 +950,7 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.PNFSRead), export, + protocol, ) ch <- prometheus.MustNewConstMetric( @@ -898,5 +958,6 @@ func (c *mountStatsCollector) updateNFSStats(ch chan<- prometheus.Metric, export prometheus.CounterValue, float64(s.Events.PNFSWrite), export, + protocol, ) } diff --git a/vendor/github.com/prometheus/procfs/.gitignore b/vendor/github.com/prometheus/procfs/.gitignore new file mode 100644 index 00000000..25e3659a --- /dev/null +++ b/vendor/github.com/prometheus/procfs/.gitignore @@ -0,0 +1 @@ +/fixtures/ diff --git a/vendor/github.com/prometheus/procfs/.travis.yml b/vendor/github.com/prometheus/procfs/.travis.yml new file mode 100644 index 00000000..5416cf8a --- /dev/null +++ b/vendor/github.com/prometheus/procfs/.travis.yml @@ -0,0 +1,15 @@ +sudo: false + +language: go + +go: +- 1.7.x +- 1.8.x +- 1.9.x +- 1.10.x +- 1.x + +go_import_path: github.com/prometheus/procfs + +script: +- make style check_license vet test staticcheck diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile index 5c8f7262..4d109839 100644 --- a/vendor/github.com/prometheus/procfs/Makefile +++ b/vendor/github.com/prometheus/procfs/Makefile @@ -59,6 +59,12 @@ staticcheck: $(STATICCHECK) ./ttar -C $(dir $*) -x -f $*.ttar touch $@ +update_fixtures: fixtures.ttar sysfs/fixtures.ttar + +%fixtures.ttar: %/fixtures + rm -v $(dir $*)fixtures/.unpacked + ./ttar -C $(dir $*) -c -f $*fixtures.ttar fixtures/ + $(FIRST_GOPATH)/bin/staticcheck: @GOOS= GOARCH= $(GO) get -u honnef.co/go/tools/cmd/staticcheck diff --git a/vendor/github.com/prometheus/procfs/bcache/get_test.go b/vendor/github.com/prometheus/procfs/bcache/get_test.go new file mode 100644 index 00000000..1d41a5ad --- /dev/null +++ b/vendor/github.com/prometheus/procfs/bcache/get_test.go @@ -0,0 +1,114 @@ +// Copyright 2017 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. + +package bcache + +import ( + "math" + "testing" +) + +func TestDehumanizeTests(t *testing.T) { + dehumanizeTests := []struct { + in []byte + out uint64 + invalid bool + }{ + { + in: []byte("542k"), + out: 555008, + }, + { + in: []byte("322M"), + out: 337641472, + }, + { + in: []byte("1.1k"), + out: 1124, + }, + { + in: []byte("1.9k"), + out: 1924, + }, + { + in: []byte("1.10k"), + out: 2024, + }, + { + in: []byte(""), + out: 0, + invalid: true, + }, + } + for _, tst := range dehumanizeTests { + got, err := dehumanize(tst.in) + if tst.invalid && err == nil { + t.Error("expected an error, but none occurred") + } + if !tst.invalid && err != nil { + t.Errorf("unexpected error: %v", err) + } + if got != tst.out { + t.Errorf("dehumanize: '%s', want %d, got %d", tst.in, tst.out, got) + } + } +} + +func TestParsePseudoFloatTests(t *testing.T) { + parsePseudoFloatTests := []struct { + in string + out float64 + }{ + { + in: "1.1", + out: float64(1.097656), + }, + { + in: "1.9", + out: float64(1.878906), + }, + { + in: "1.10", + out: float64(1.976562), + }, + } + for _, tst := range parsePseudoFloatTests { + got, err := parsePseudoFloat(tst.in) + if err != nil || math.Abs(got-tst.out) > 0.0001 { + t.Errorf("parsePseudoFloat: %s, want %f, got %f", tst.in, tst.out, got) + } + } +} + +func TestPriorityStats(t *testing.T) { + var want = PriorityStats{ + UnusedPercent: 99, + MetadataPercent: 5, + } + var ( + in string + gotErr error + got PriorityStats + ) + in = "Metadata: 5%" + gotErr = parsePriorityStats(in, &got) + if gotErr != nil || got.MetadataPercent != want.MetadataPercent { + t.Errorf("parsePriorityStats: '%s', want %d, got %d", in, want.MetadataPercent, got.MetadataPercent) + } + + in = "Unused: 99%" + gotErr = parsePriorityStats(in, &got) + if gotErr != nil || got.UnusedPercent != want.UnusedPercent { + t.Errorf("parsePriorityStats: '%s', want %d, got %d", in, want.UnusedPercent, got.UnusedPercent) + } +} diff --git a/vendor/github.com/prometheus/procfs/buddyinfo_test.go b/vendor/github.com/prometheus/procfs/buddyinfo_test.go new file mode 100644 index 00000000..bcf9355c --- /dev/null +++ b/vendor/github.com/prometheus/procfs/buddyinfo_test.go @@ -0,0 +1,64 @@ +// Copyright 2017 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. + +package procfs + +import ( + "strings" + "testing" +) + +func TestBuddyInfo(t *testing.T) { + buddyInfo, err := FS("fixtures/buddyinfo/valid").NewBuddyInfo() + if err != nil { + t.Fatal(err) + } + + if want, got := "DMA", buddyInfo[0].Zone; want != got { + t.Errorf("want Node 0, Zone %s, got %s", want, got) + } + + if want, got := "Normal", buddyInfo[2].Zone; want != got { + t.Errorf("want Node 0, Zone %s, got %s", want, got) + } + + if want, got := 4381.0, buddyInfo[2].Sizes[0]; want != got { + t.Errorf("want Node 0, Zone Normal %f, got %f", want, got) + } + + if want, got := 572.0, buddyInfo[1].Sizes[1]; want != got { + t.Errorf("want Node 0, Zone DMA32 %f, got %f", want, got) + } +} + +func TestBuddyInfoShort(t *testing.T) { + _, err := FS("fixtures/buddyinfo/short").NewBuddyInfo() + if err == nil { + t.Errorf("expected error, but none occurred") + } + + if want, got := "invalid number of fields when parsing buddyinfo", err.Error(); want != got { + t.Errorf("wrong error returned, wanted %q, got %q", want, got) + } +} + +func TestBuddyInfoSizeMismatch(t *testing.T) { + _, err := FS("fixtures/buddyinfo/sizemismatch").NewBuddyInfo() + if err == nil { + t.Errorf("expected error, but none occurred") + } + + if want, got := "mismatch in number of buddyinfo buckets", err.Error(); !strings.HasPrefix(got, want) { + t.Errorf("wrong error returned, wanted prefix %q, got %q", want, got) + } +} diff --git a/vendor/github.com/prometheus/procfs/fs_test.go b/vendor/github.com/prometheus/procfs/fs_test.go new file mode 100644 index 00000000..a4e07f5c --- /dev/null +++ b/vendor/github.com/prometheus/procfs/fs_test.go @@ -0,0 +1,39 @@ +// Copyright 2018 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. + +package procfs + +import "testing" + +func TestNewFS(t *testing.T) { + if _, err := NewFS("foobar"); err == nil { + t.Error("want NewFS to fail for non-existing mount point") + } + + if _, err := NewFS("procfs.go"); err == nil { + t.Error("want NewFS to fail if mount point is not a directory") + } +} + +func TestFSXFSStats(t *testing.T) { + stats, err := FS("fixtures").XFSStats() + if err != nil { + t.Fatalf("failed to parse XFS stats: %v", err) + } + + // Very lightweight test just to sanity check the path used + // to open XFS stats. Heavier tests in package xfs. + if want, got := uint32(92447), stats.ExtentAllocation.ExtentsAllocated; want != got { + t.Errorf("unexpected extents allocated:\nwant: %d\nhave: %d", want, got) + } +} diff --git a/vendor/github.com/prometheus/procfs/ipvs_test.go b/vendor/github.com/prometheus/procfs/ipvs_test.go new file mode 100644 index 00000000..9c34e6d0 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/ipvs_test.go @@ -0,0 +1,250 @@ +// Copyright 2018 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. + +package procfs + +import ( + "net" + "testing" +) + +var ( + expectedIPVSStats = IPVSStats{ + Connections: 23765872, + IncomingPackets: 3811989221, + OutgoingPackets: 0, + IncomingBytes: 89991519156915, + OutgoingBytes: 0, + } + expectedIPVSBackendStatuses = []IPVSBackendStatus{ + { + LocalAddress: net.ParseIP("192.168.0.22"), + LocalPort: 3306, + RemoteAddress: net.ParseIP("192.168.82.22"), + RemotePort: 3306, + Proto: "TCP", + Weight: 100, + ActiveConn: 248, + InactConn: 2, + }, + { + LocalAddress: net.ParseIP("192.168.0.22"), + LocalPort: 3306, + RemoteAddress: net.ParseIP("192.168.83.24"), + RemotePort: 3306, + Proto: "TCP", + Weight: 100, + ActiveConn: 248, + InactConn: 2, + }, + { + LocalAddress: net.ParseIP("192.168.0.22"), + LocalPort: 3306, + RemoteAddress: net.ParseIP("192.168.83.21"), + RemotePort: 3306, + Proto: "TCP", + Weight: 100, + ActiveConn: 248, + InactConn: 1, + }, + { + LocalAddress: net.ParseIP("192.168.0.57"), + LocalPort: 3306, + RemoteAddress: net.ParseIP("192.168.84.22"), + RemotePort: 3306, + Proto: "TCP", + Weight: 0, + ActiveConn: 0, + InactConn: 0, + }, + { + LocalAddress: net.ParseIP("192.168.0.57"), + LocalPort: 3306, + RemoteAddress: net.ParseIP("192.168.82.21"), + RemotePort: 3306, + Proto: "TCP", + Weight: 100, + ActiveConn: 1499, + InactConn: 0, + }, + { + LocalAddress: net.ParseIP("192.168.0.57"), + LocalPort: 3306, + RemoteAddress: net.ParseIP("192.168.50.21"), + RemotePort: 3306, + Proto: "TCP", + Weight: 100, + ActiveConn: 1498, + InactConn: 0, + }, + { + LocalAddress: net.ParseIP("192.168.0.55"), + LocalPort: 3306, + RemoteAddress: net.ParseIP("192.168.50.26"), + RemotePort: 3306, + Proto: "TCP", + Weight: 0, + ActiveConn: 0, + InactConn: 0, + }, + { + LocalAddress: net.ParseIP("192.168.0.55"), + LocalPort: 3306, + RemoteAddress: net.ParseIP("192.168.49.32"), + RemotePort: 3306, + Proto: "TCP", + Weight: 100, + ActiveConn: 0, + InactConn: 0, + }, + { + LocalAddress: net.ParseIP("2620::1"), + LocalPort: 80, + RemoteAddress: net.ParseIP("2620::2"), + RemotePort: 80, + Proto: "TCP", + Weight: 1, + ActiveConn: 0, + InactConn: 0, + }, + { + LocalAddress: net.ParseIP("2620::1"), + LocalPort: 80, + RemoteAddress: net.ParseIP("2620::3"), + RemotePort: 80, + Proto: "TCP", + Weight: 1, + ActiveConn: 0, + InactConn: 0, + }, + { + LocalAddress: net.ParseIP("2620::1"), + LocalPort: 80, + RemoteAddress: net.ParseIP("2620::4"), + RemotePort: 80, + Proto: "TCP", + Weight: 1, + ActiveConn: 1, + InactConn: 1, + }, + { + LocalMark: "10001000", + RemoteAddress: net.ParseIP("192.168.50.26"), + RemotePort: 3306, + Proto: "FWM", + Weight: 0, + ActiveConn: 0, + InactConn: 1, + }, + { + LocalMark: "10001000", + RemoteAddress: net.ParseIP("192.168.50.21"), + RemotePort: 3306, + Proto: "FWM", + Weight: 0, + ActiveConn: 0, + InactConn: 2, + }, + } +) + +func TestIPVSStats(t *testing.T) { + stats, err := FS("fixtures").NewIPVSStats() + if err != nil { + t.Fatal(err) + } + + if stats != expectedIPVSStats { + t.Errorf("want %+v, have %+v", expectedIPVSStats, stats) + } +} + +func TestParseIPPort(t *testing.T) { + ip := net.ParseIP("192.168.0.22") + port := uint16(3306) + + gotIP, gotPort, err := parseIPPort("C0A80016:0CEA") + if err != nil { + t.Fatal(err) + } + if !(gotIP.Equal(ip) && port == gotPort) { + t.Errorf("want %s:%d, have %s:%d", ip, port, gotIP, gotPort) + } +} + +func TestParseIPPortInvalid(t *testing.T) { + testcases := []string{ + "", + "C0A80016", + "C0A800:1234", + "FOOBARBA:1234", + "C0A80016:0CEA:1234", + } + + for _, s := range testcases { + ip, port, err := parseIPPort(s) + if ip != nil || port != uint16(0) || err == nil { + t.Errorf("Expected error for input %s, have ip = %s, port = %v, err = %v", s, ip, port, err) + } + } +} + +func TestParseIPPortIPv6(t *testing.T) { + ip := net.ParseIP("dead:beef::1") + port := uint16(8080) + + gotIP, gotPort, err := parseIPPort("[DEAD:BEEF:0000:0000:0000:0000:0000:0001]:1F90") + if err != nil { + t.Fatal(err) + } + if !(gotIP.Equal(ip) && port == gotPort) { + t.Errorf("want %s:%d, have %s:%d", ip, port, gotIP, gotPort) + } +} + +func TestIPVSBackendStatus(t *testing.T) { + backendStats, err := FS("fixtures").NewIPVSBackendStatus() + if err != nil { + t.Fatal(err) + } + if want, have := len(expectedIPVSBackendStatuses), len(backendStats); want != have { + t.Fatalf("want %d backend statuses, have %d", want, have) + } + + for idx, expect := range expectedIPVSBackendStatuses { + if !backendStats[idx].LocalAddress.Equal(expect.LocalAddress) { + t.Errorf("want LocalAddress %s, have %s", expect.LocalAddress, backendStats[idx].LocalAddress) + } + if backendStats[idx].LocalPort != expect.LocalPort { + t.Errorf("want LocalPort %d, have %d", expect.LocalPort, backendStats[idx].LocalPort) + } + if !backendStats[idx].RemoteAddress.Equal(expect.RemoteAddress) { + t.Errorf("want RemoteAddress %s, have %s", expect.RemoteAddress, backendStats[idx].RemoteAddress) + } + if backendStats[idx].RemotePort != expect.RemotePort { + t.Errorf("want RemotePort %d, have %d", expect.RemotePort, backendStats[idx].RemotePort) + } + if backendStats[idx].Proto != expect.Proto { + t.Errorf("want Proto %s, have %s", expect.Proto, backendStats[idx].Proto) + } + if backendStats[idx].Weight != expect.Weight { + t.Errorf("want Weight %d, have %d", expect.Weight, backendStats[idx].Weight) + } + if backendStats[idx].ActiveConn != expect.ActiveConn { + t.Errorf("want ActiveConn %d, have %d", expect.ActiveConn, backendStats[idx].ActiveConn) + } + if backendStats[idx].InactConn != expect.InactConn { + t.Errorf("want InactConn %d, have %d", expect.InactConn, backendStats[idx].InactConn) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/mdstat_test.go b/vendor/github.com/prometheus/procfs/mdstat_test.go new file mode 100644 index 00000000..8819228f --- /dev/null +++ b/vendor/github.com/prometheus/procfs/mdstat_test.go @@ -0,0 +1,44 @@ +// Copyright 2018 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. + +package procfs + +import ( + "testing" +) + +func TestMDStat(t *testing.T) { + mdStates, err := FS("fixtures").ParseMDStat() + if err != nil { + t.Fatalf("parsing of reference-file failed entirely: %s", err) + } + + refs := map[string]MDStat{ + "md3": {"md3", "active", 8, 8, 5853468288, 5853468288}, + "md127": {"md127", "active", 2, 2, 312319552, 312319552}, + "md0": {"md0", "active", 2, 2, 248896, 248896}, + "md4": {"md4", "inactive", 2, 2, 4883648, 4883648}, + "md6": {"md6", "active", 1, 2, 195310144, 16775552}, + "md8": {"md8", "active", 2, 2, 195310144, 16775552}, + "md7": {"md7", "active", 3, 4, 7813735424, 7813735424}, + } + + if want, have := len(refs), len(mdStates); want != have { + t.Errorf("want %d parsed md-devices, have %d", want, have) + } + for _, md := range mdStates { + if want, have := refs[md.Name], md; want != have { + t.Errorf("%s: want %v, have %v", md.Name, want, have) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/mountstats.go b/vendor/github.com/prometheus/procfs/mountstats.go index e95ddbc6..7a8a1e09 100644 --- a/vendor/github.com/prometheus/procfs/mountstats.go +++ b/vendor/github.com/prometheus/procfs/mountstats.go @@ -39,8 +39,11 @@ const ( statVersion10 = "1.0" statVersion11 = "1.1" - fieldTransport10Len = 10 - fieldTransport11Len = 13 + fieldTransport10TCPLen = 10 + fieldTransport10UDPLen = 7 + + fieldTransport11TCPLen = 13 + fieldTransport11UDPLen = 10 ) // A Mount is a device mount parsed from /proc/[pid]/mountstats. @@ -186,6 +189,8 @@ type NFSOperationStats struct { // A NFSTransportStats contains statistics for the NFS mount RPC requests and // responses. type NFSTransportStats struct { + // The transport protocol used for the NFS mount. + Protocol string // The local port used for the NFS mount. Port uint64 // Number of times the client has had to establish a connection from scratch @@ -360,7 +365,7 @@ func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, e return nil, fmt.Errorf("not enough information for NFS transport stats: %v", ss) } - tstats, err := parseNFSTransportStats(ss[2:], statVersion) + tstats, err := parseNFSTransportStats(ss[1:], statVersion) if err != nil { return nil, err } @@ -522,13 +527,33 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) { // parseNFSTransportStats parses a NFSTransportStats line using an input set of // integer fields matched to a specific stats version. func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats, error) { + // Extract the protocol field. It is the only string value in the line + protocol := ss[0] + ss = ss[1:] + switch statVersion { case statVersion10: - if len(ss) != fieldTransport10Len { + var expectedLength int + if protocol == "tcp" { + expectedLength = fieldTransport10TCPLen + } else if protocol == "udp" { + expectedLength = fieldTransport10UDPLen + } else { + return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.0 statement: %v", protocol, ss) + } + if len(ss) != expectedLength { return nil, fmt.Errorf("invalid NFS transport stats 1.0 statement: %v", ss) } case statVersion11: - if len(ss) != fieldTransport11Len { + var expectedLength int + if protocol == "tcp" { + expectedLength = fieldTransport11TCPLen + } else if protocol == "udp" { + expectedLength = fieldTransport11UDPLen + } else { + return nil, fmt.Errorf("invalid NFS protocol \"%s\" in stats 1.1 statement: %v", protocol, ss) + } + if len(ss) != expectedLength { return nil, fmt.Errorf("invalid NFS transport stats 1.1 statement: %v", ss) } default: @@ -536,12 +561,13 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats } // Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay - // in a v1.0 response. + // in a v1.0 response. Since the stat length is bigger for TCP stats, we use + // the TCP length here. // // Note: slice length must be set to length of v1.1 stats to avoid a panic when // only v1.0 stats are present. // See: https://github.com/prometheus/node_exporter/issues/571. - ns := make([]uint64, fieldTransport11Len) + ns := make([]uint64, fieldTransport11TCPLen) for i, s := range ss { n, err := strconv.ParseUint(s, 10, 64) if err != nil { @@ -551,7 +577,18 @@ func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats ns[i] = n } + // The fields differ depending on the transport protocol (TCP or UDP) + // From https://utcc.utoronto.ca/%7Ecks/space/blog/linux/NFSMountstatsXprt + // + // For the udp RPC transport there is no connection count, connect idle time, + // or idle time (fields #3, #4, and #5); all other fields are the same. So + // we set them to 0 here. + if protocol == "udp" { + ns = append(ns[:2], append(make([]uint64, 3), ns[2:]...)...) + } + return &NFSTransportStats{ + Protocol: protocol, Port: ns[0], Bind: ns[1], Connect: ns[2], diff --git a/vendor/github.com/prometheus/procfs/mountstats_test.go b/vendor/github.com/prometheus/procfs/mountstats_test.go new file mode 100644 index 00000000..9ae3b02a --- /dev/null +++ b/vendor/github.com/prometheus/procfs/mountstats_test.go @@ -0,0 +1,380 @@ +// Copyright 2018 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. + +package procfs + +import ( + "fmt" + "reflect" + "strings" + "testing" + "time" +) + +func TestMountStats(t *testing.T) { + tests := []struct { + name string + s string + mounts []*Mount + invalid bool + }{ + { + name: "no devices", + s: `hello`, + }, + { + name: "device has too few fields", + s: `device foo`, + invalid: true, + }, + { + name: "device incorrect format", + s: `device rootfs BAD on / with fstype rootfs`, + invalid: true, + }, + { + name: "device incorrect format", + s: `device rootfs mounted BAD / with fstype rootfs`, + invalid: true, + }, + { + name: "device incorrect format", + s: `device rootfs mounted on / BAD fstype rootfs`, + invalid: true, + }, + { + name: "device incorrect format", + s: `device rootfs mounted on / with BAD rootfs`, + invalid: true, + }, + { + name: "device rootfs cannot have stats", + s: `device rootfs mounted on / with fstype rootfs stats`, + invalid: true, + }, + { + name: "NFSv4 device with too little info", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.1\nhello", + invalid: true, + }, + { + name: "NFSv4 device with bad bytes", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.1\nbytes: 0", + invalid: true, + }, + { + name: "NFSv4 device with bad events", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.1\nevents: 0", + invalid: true, + }, + { + name: "NFSv4 device with bad per-op stats", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.1\nper-op statistics\nFOO 0", + invalid: true, + }, + { + name: "NFSv4 device with bad transport stats", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.1\nxprt: tcp", + invalid: true, + }, + { + name: "NFSv4 device with bad transport version", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=foo\nxprt: tcp 0", + invalid: true, + }, + { + name: "NFSv4 device with bad transport stats version 1.0", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.0\nxprt: tcp 0 0 0 0 0 0 0 0 0 0 0 0 0", + invalid: true, + }, + { + name: "NFSv4 device with bad transport stats version 1.1", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.1\nxprt: tcp 0 0 0 0 0 0 0 0 0 0", + invalid: true, + }, + { + name: "NFSv3 device with bad transport protocol", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs4 statvers=1.1\nxprt: tcpx 0 0 0 0 0 0 0 0 0 0", + invalid: true, + }, + { + name: "NFSv3 device using TCP with transport stats version 1.0 OK", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.0\nxprt: tcp 1 2 3 4 5 6 7 8 9 10", + mounts: []*Mount{{ + Device: "192.168.1.1:/srv", + Mount: "/mnt/nfs", + Type: "nfs", + Stats: &MountStatsNFS{ + StatVersion: "1.0", + Transport: NFSTransportStats{ + Protocol: "tcp", + Port: 1, + Bind: 2, + Connect: 3, + ConnectIdleTime: 4, + IdleTime: 5 * time.Second, + Sends: 6, + Receives: 7, + BadTransactionIDs: 8, + CumulativeActiveRequests: 9, + CumulativeBacklog: 10, + MaximumRPCSlotsUsed: 0, // these three are not + CumulativeSendingQueue: 0, // present in statvers=1.0 + CumulativePendingQueue: 0, // + }, + }, + }}, + }, + { + name: "NFSv3 device using UDP with transport stats version 1.0 OK", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.0\nxprt: udp 1 2 3 4 5 6 7", + mounts: []*Mount{{ + Device: "192.168.1.1:/srv", + Mount: "/mnt/nfs", + Type: "nfs", + Stats: &MountStatsNFS{ + StatVersion: "1.0", + Transport: NFSTransportStats{ + Protocol: "udp", + Port: 1, + Bind: 2, + Connect: 0, + ConnectIdleTime: 0, + IdleTime: 0, + Sends: 3, + Receives: 4, + BadTransactionIDs: 5, + CumulativeActiveRequests: 6, + CumulativeBacklog: 7, + MaximumRPCSlotsUsed: 0, // these three are not + CumulativeSendingQueue: 0, // present in statvers=1.0 + CumulativePendingQueue: 0, // + }, + }, + }}, + }, + { + name: "NFSv3 device using TCP with transport stats version 1.1 OK", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.1\nxprt: tcp 1 2 3 4 5 6 7 8 9 10 11 12 13", + mounts: []*Mount{{ + Device: "192.168.1.1:/srv", + Mount: "/mnt/nfs", + Type: "nfs", + Stats: &MountStatsNFS{ + StatVersion: "1.1", + Transport: NFSTransportStats{ + Protocol: "tcp", + Port: 1, + Bind: 2, + Connect: 3, + ConnectIdleTime: 4, + IdleTime: 5 * time.Second, + Sends: 6, + Receives: 7, + BadTransactionIDs: 8, + CumulativeActiveRequests: 9, + CumulativeBacklog: 10, + MaximumRPCSlotsUsed: 11, + CumulativeSendingQueue: 12, + CumulativePendingQueue: 13, + }, + }, + }}, + }, + { + name: "NFSv3 device using UDP with transport stats version 1.1 OK", + s: "device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.1\nxprt: udp 1 2 3 4 5 6 7 8 9 10", + mounts: []*Mount{{ + Device: "192.168.1.1:/srv", + Mount: "/mnt/nfs", + Type: "nfs", + Stats: &MountStatsNFS{ + StatVersion: "1.1", + Transport: NFSTransportStats{ + Protocol: "udp", + Port: 1, + Bind: 2, + Connect: 0, // these three are not + ConnectIdleTime: 0, // present for UDP + IdleTime: 0, // + Sends: 3, + Receives: 4, + BadTransactionIDs: 5, + CumulativeActiveRequests: 6, + CumulativeBacklog: 7, + MaximumRPCSlotsUsed: 8, + CumulativeSendingQueue: 9, + CumulativePendingQueue: 10, + }, + }, + }}, + }, + { + name: "device rootfs OK", + s: `device rootfs mounted on / with fstype rootfs`, + mounts: []*Mount{{ + Device: "rootfs", + Mount: "/", + Type: "rootfs", + }}, + }, + { + name: "NFSv3 device with minimal stats OK", + s: `device 192.168.1.1:/srv mounted on /mnt/nfs with fstype nfs statvers=1.1`, + mounts: []*Mount{{ + Device: "192.168.1.1:/srv", + Mount: "/mnt/nfs", + Type: "nfs", + Stats: &MountStatsNFS{ + StatVersion: "1.1", + }, + }}, + }, + { + name: "fixtures OK", + mounts: []*Mount{ + { + Device: "rootfs", + Mount: "/", + Type: "rootfs", + }, + { + Device: "sysfs", + Mount: "/sys", + Type: "sysfs", + }, + { + Device: "proc", + Mount: "/proc", + Type: "proc", + }, + { + Device: "/dev/sda1", + Mount: "/", + Type: "ext4", + }, + { + Device: "192.168.1.1:/srv/test", + Mount: "/mnt/nfs/test", + Type: "nfs4", + Stats: &MountStatsNFS{ + StatVersion: "1.1", + Age: 13968 * time.Second, + Bytes: NFSBytesStats{ + Read: 1207640230, + ReadTotal: 1210214218, + ReadPages: 295483, + }, + Events: NFSEventsStats{ + InodeRevalidate: 52, + DnodeRevalidate: 226, + VFSOpen: 1, + VFSLookup: 13, + VFSAccess: 398, + VFSReadPages: 331, + VFSWritePages: 47, + VFSFlush: 77, + VFSFileRelease: 77, + }, + Operations: []NFSOperationStats{ + { + Operation: "NULL", + }, + { + Operation: "READ", + Requests: 1298, + Transmissions: 1298, + BytesSent: 207680, + BytesReceived: 1210292152, + CumulativeQueueTime: 6 * time.Millisecond, + CumulativeTotalResponseTime: 79386 * time.Millisecond, + CumulativeTotalRequestTime: 79407 * time.Millisecond, + }, + { + Operation: "WRITE", + }, + }, + Transport: NFSTransportStats{ + Protocol: "tcp", + Port: 832, + Connect: 1, + IdleTime: 11 * time.Second, + Sends: 6428, + Receives: 6428, + CumulativeActiveRequests: 12154, + MaximumRPCSlotsUsed: 24, + CumulativeSendingQueue: 26, + CumulativePendingQueue: 5726, + }, + }, + }, + }, + }, + } + + for i, tt := range tests { + t.Logf("[%02d] test %q", i, tt.name) + + var mounts []*Mount + var err error + + if tt.s != "" { + mounts, err = parseMountStats(strings.NewReader(tt.s)) + } else { + proc, e := FS("fixtures").NewProc(26231) + if e != nil { + t.Fatalf("failed to create proc: %v", err) + } + + mounts, err = proc.MountStats() + } + + if tt.invalid && err == nil { + t.Error("expected an error, but none occurred") + } + if !tt.invalid && err != nil { + t.Errorf("unexpected error: %v", err) + } + + if want, have := tt.mounts, mounts; !reflect.DeepEqual(want, have) { + t.Errorf("mounts:\nwant:\n%v\nhave:\n%v", mountsStr(want), mountsStr(have)) + } + } +} + +func mountsStr(mounts []*Mount) string { + var out string + for i, m := range mounts { + out += fmt.Sprintf("[%d] %q on %q (%q)", i, m.Device, m.Mount, m.Type) + + stats, ok := m.Stats.(*MountStatsNFS) + if !ok { + out += "\n" + continue + } + + out += fmt.Sprintf("\n\t- v%s, age: %s", stats.StatVersion, stats.Age) + out += fmt.Sprintf("\n\t- bytes: %v", stats.Bytes) + out += fmt.Sprintf("\n\t- events: %v", stats.Events) + out += fmt.Sprintf("\n\t- transport: %v", stats.Transport) + out += fmt.Sprintf("\n\t- per-operation stats:") + + for _, o := range stats.Operations { + out += fmt.Sprintf("\n\t\t- %v", o) + } + + out += "\n" + } + + return out +} diff --git a/vendor/github.com/prometheus/procfs/net_dev_test.go b/vendor/github.com/prometheus/procfs/net_dev_test.go new file mode 100644 index 00000000..b162e9c9 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/net_dev_test.go @@ -0,0 +1,86 @@ +// Copyright 2018 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. + +package procfs + +import ( + "testing" +) + +func TestNetDevParseLine(t *testing.T) { + const rawLine = ` eth0: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16` + + have, err := NetDev{}.parseLine(rawLine) + if err != nil { + t.Fatal(err) + } + + want := NetDevLine{"eth0", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + if want != *have { + t.Errorf("want %v, have %v", want, have) + } +} + +func TestNewNetDev(t *testing.T) { + fs, err := NewFS("fixtures") + if err != nil { + t.Fatal(err) + } + + nd, err := fs.NewNetDev() + if err != nil { + t.Fatal(err) + } + + lines := map[string]NetDevLine{ + "vethf345468": {Name: "vethf345468", RxBytes: 648, RxPackets: 8, TxBytes: 438, TxPackets: 5}, + "lo": {Name: "lo", RxBytes: 1664039048, RxPackets: 1566805, TxBytes: 1664039048, TxPackets: 1566805}, + "docker0": {Name: "docker0", RxBytes: 2568, RxPackets: 38, TxBytes: 438, TxPackets: 5}, + "eth0": {Name: "eth0", RxBytes: 874354587, RxPackets: 1036395, TxBytes: 563352563, TxPackets: 732147}, + } + + if want, have := len(lines), len(nd); want != have { + t.Errorf("want %d parsed net/dev lines, have %d", want, have) + } + for _, line := range nd { + if want, have := lines[line.Name], line; want != have { + t.Errorf("%s: want %v, have %v", line.Name, want, have) + } + } +} + +func TestProcNewNetDev(t *testing.T) { + p, err := FS("fixtures").NewProc(26231) + if err != nil { + t.Fatal(err) + } + + nd, err := p.NewNetDev() + if err != nil { + t.Fatal(err) + } + + lines := map[string]NetDevLine{ + "lo": {Name: "lo"}, + "eth0": {Name: "eth0", RxBytes: 438, RxPackets: 5, TxBytes: 648, TxPackets: 8}, + } + + if want, have := len(lines), len(nd); want != have { + t.Errorf("want %d parsed net/dev lines, have %d", want, have) + } + for _, line := range nd { + if want, have := lines[line.Name], line; want != have { + t.Errorf("%s: want %v, have %v", line.Name, want, have) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go b/vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go new file mode 100644 index 00000000..8ebcfd16 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go @@ -0,0 +1,305 @@ +// Copyright 2018 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. + +package nfs_test + +import ( + "reflect" + "strings" + "testing" + + "github.com/prometheus/procfs/nfs" +) + +func TestNewNFSClientRPCStats(t *testing.T) { + tests := []struct { + name string + content string + stats *nfs.ClientRPCStats + invalid bool + }{ + { + name: "invalid file", + content: "invalid", + invalid: true, + }, { + name: "good old kernel version file", + content: `net 70 70 69 45 +rpc 1218785755 374636 1218815394 +proc2 18 16 57 74 52 71 73 45 86 0 52 83 61 17 53 50 23 70 82 +proc3 22 0 1061909262 48906 4077635 117661341 5 29391916 2570425 2993289 590 0 0 7815 15 1130 0 3983 92385 13332 2 1 23729 +proc4 48 98 51 54 83 85 23 24 1 28 73 68 83 12 84 39 68 59 58 88 29 74 69 96 21 84 15 53 86 54 66 56 97 36 49 32 85 81 11 58 32 67 13 28 35 90 1 26 1337 +`, + stats: &nfs.ClientRPCStats{ + Network: nfs.Network{ + NetCount: 70, + UDPCount: 70, + TCPCount: 69, + TCPConnect: 45, + }, + ClientRPC: nfs.ClientRPC{ + RPCCount: 1218785755, + Retransmissions: 374636, + AuthRefreshes: 1218815394, + }, + V2Stats: nfs.V2Stats{ + Null: 16, + GetAttr: 57, + SetAttr: 74, + Root: 52, + Lookup: 71, + ReadLink: 73, + Read: 45, + WrCache: 86, + Write: 0, + Create: 52, + Remove: 83, + Rename: 61, + Link: 17, + SymLink: 53, + MkDir: 50, + RmDir: 23, + ReadDir: 70, + FsStat: 82, + }, + V3Stats: nfs.V3Stats{ + Null: 0, + GetAttr: 1061909262, + SetAttr: 48906, + Lookup: 4077635, + Access: 117661341, + ReadLink: 5, + Read: 29391916, + Write: 2570425, + Create: 2993289, + MkDir: 590, + SymLink: 0, + MkNod: 0, + Remove: 7815, + RmDir: 15, + Rename: 1130, + Link: 0, + ReadDir: 3983, + ReadDirPlus: 92385, + FsStat: 13332, + FsInfo: 2, + PathConf: 1, + Commit: 23729}, + ClientV4Stats: nfs.ClientV4Stats{ + Null: 98, + Read: 51, + Write: 54, + Commit: 83, + Open: 85, + OpenConfirm: 23, + OpenNoattr: 24, + OpenDowngrade: 1, + Close: 28, + Setattr: 73, + FsInfo: 68, + Renew: 83, + SetClientID: 12, + SetClientIDConfirm: 84, + Lock: 39, + Lockt: 68, + Locku: 59, + Access: 58, + Getattr: 88, + Lookup: 29, + LookupRoot: 74, + Remove: 69, + Rename: 96, + Link: 21, + Symlink: 84, + Create: 15, + Pathconf: 53, + StatFs: 86, + ReadLink: 54, + ReadDir: 66, + ServerCaps: 56, + DelegReturn: 97, + GetACL: 36, + SetACL: 49, + FsLocations: 32, + ReleaseLockowner: 85, + Secinfo: 81, + FsidPresent: 11, + ExchangeID: 58, + CreateSession: 32, + DestroySession: 67, + Sequence: 13, + GetLeaseTime: 28, + ReclaimComplete: 35, + LayoutGet: 90, + GetDeviceInfo: 1, + LayoutCommit: 26, + LayoutReturn: 1337, + SecinfoNoName: 0, + TestStateID: 0, + FreeStateID: 0, + GetDeviceList: 0, + BindConnToSession: 0, + DestroyClientID: 0, + Seek: 0, + Allocate: 0, + DeAllocate: 0, + LayoutStats: 0, + Clone: 0, + }, + }, + }, { + name: "good file", + content: `net 18628 0 18628 6 +rpc 4329785 0 4338291 +proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2 +proc3 22 1 4084749 29200 94754 32580 186 47747 7981 8639 0 6356 0 6962 0 7958 0 0 241 4 4 2 39 +proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +`, + stats: &nfs.ClientRPCStats{ + Network: nfs.Network{ + NetCount: 18628, + UDPCount: 0, + TCPCount: 18628, + TCPConnect: 6, + }, + ClientRPC: nfs.ClientRPC{ + RPCCount: 4329785, + Retransmissions: 0, + AuthRefreshes: 4338291, + }, + V2Stats: nfs.V2Stats{ + Null: 2, + GetAttr: 69, + SetAttr: 0, + Root: 0, + Lookup: 4410, + ReadLink: 0, + Read: 0, + WrCache: 0, + Write: 0, + Create: 0, + Remove: 0, + Rename: 0, + Link: 0, + SymLink: 0, + MkDir: 0, + RmDir: 0, + ReadDir: 99, + FsStat: 2, + }, + V3Stats: nfs.V3Stats{ + Null: 1, + GetAttr: 4084749, + SetAttr: 29200, + Lookup: 94754, + Access: 32580, + ReadLink: 186, + Read: 47747, + Write: 7981, + Create: 8639, + MkDir: 0, + SymLink: 6356, + MkNod: 0, + Remove: 6962, + RmDir: 0, + Rename: 7958, + Link: 0, + ReadDir: 0, + ReadDirPlus: 241, + FsStat: 4, + FsInfo: 4, + PathConf: 2, + Commit: 39, + }, + ClientV4Stats: nfs.ClientV4Stats{ + Null: 1, + Read: 0, + Write: 0, + Commit: 0, + Open: 0, + OpenConfirm: 0, + OpenNoattr: 0, + OpenDowngrade: 0, + Close: 0, + Setattr: 0, + FsInfo: 0, + Renew: 0, + SetClientID: 1, + SetClientIDConfirm: 1, + Lock: 0, + Lockt: 0, + Locku: 0, + Access: 0, + Getattr: 0, + Lookup: 0, + LookupRoot: 0, + Remove: 2, + Rename: 0, + Link: 0, + Symlink: 0, + Create: 0, + Pathconf: 0, + StatFs: 0, + ReadLink: 0, + ReadDir: 0, + ServerCaps: 0, + DelegReturn: 0, + GetACL: 0, + SetACL: 0, + FsLocations: 0, + ReleaseLockowner: 0, + Secinfo: 0, + FsidPresent: 0, + ExchangeID: 0, + CreateSession: 0, + DestroySession: 0, + Sequence: 0, + GetLeaseTime: 0, + ReclaimComplete: 0, + LayoutGet: 0, + GetDeviceInfo: 0, + LayoutCommit: 0, + LayoutReturn: 0, + SecinfoNoName: 0, + TestStateID: 0, + FreeStateID: 0, + GetDeviceList: 0, + BindConnToSession: 0, + DestroyClientID: 0, + Seek: 0, + Allocate: 0, + DeAllocate: 0, + LayoutStats: 0, + Clone: 0, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + stats, err := nfs.ParseClientRPCStats(strings.NewReader(tt.content)) + + if tt.invalid && err == nil { + t.Fatal("expected an error, but none occurred") + } + if !tt.invalid && err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if want, have := tt.stats, stats; !reflect.DeepEqual(want, have) { + t.Fatalf("unexpected NFS stats:\nwant:\n%v\nhave:\n%v", want, have) + } + }) + } +} diff --git a/vendor/github.com/prometheus/procfs/nfs/parse_nfsd_test.go b/vendor/github.com/prometheus/procfs/nfs/parse_nfsd_test.go new file mode 100644 index 00000000..b09b3b58 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/nfs/parse_nfsd_test.go @@ -0,0 +1,196 @@ +// Copyright 2018 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. + +package nfs_test + +import ( + "reflect" + "strings" + "testing" + + "github.com/prometheus/procfs/nfs" +) + +func TestNewNFSdServerRPCStats(t *testing.T) { + tests := []struct { + name string + content string + stats *nfs.ServerRPCStats + invalid bool + }{ + { + name: "invalid file", + content: "invalid", + invalid: true, + }, { + name: "good file", + content: `rc 0 6 18622 +fh 0 0 0 0 0 +io 157286400 0 +th 8 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 +ra 32 0 0 0 0 0 0 0 0 0 0 0 +net 18628 0 18628 6 +rpc 18628 0 0 0 0 +proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2 +proc3 22 2 112 0 2719 111 0 0 0 0 0 0 0 0 0 0 0 27 216 0 2 1 0 +proc4 2 2 10853 +proc4ops 72 0 0 0 1098 2 0 0 0 0 8179 5896 0 0 0 0 5900 0 0 2 0 2 0 9609 0 2 150 1272 0 0 0 1236 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +`, + stats: &nfs.ServerRPCStats{ + ReplyCache: nfs.ReplyCache{ + Hits: 0, + Misses: 6, + NoCache: 18622, + }, + FileHandles: nfs.FileHandles{ + Stale: 0, + TotalLookups: 0, + AnonLookups: 0, + DirNoCache: 0, + NoDirNoCache: 0, + }, + InputOutput: nfs.InputOutput{ + Read: 157286400, + Write: 0, + }, + Threads: nfs.Threads{ + Threads: 8, + FullCnt: 0, + }, + ReadAheadCache: nfs.ReadAheadCache{ + CacheSize: 32, + CacheHistogram: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + NotFound: 0, + }, + Network: nfs.Network{ + NetCount: 18628, + UDPCount: 0, + TCPCount: 18628, + TCPConnect: 6, + }, + ServerRPC: nfs.ServerRPC{ + RPCCount: 18628, + BadCnt: 0, + BadFmt: 0, + BadAuth: 0, + BadcInt: 0, + }, + V2Stats: nfs.V2Stats{ + Null: 2, + GetAttr: 69, + SetAttr: 0, + Root: 0, + Lookup: 4410, + ReadLink: 0, + Read: 0, + WrCache: 0, + Write: 0, + Create: 0, + Remove: 0, + Rename: 0, + Link: 0, + SymLink: 0, + MkDir: 0, + RmDir: 0, + ReadDir: 99, + FsStat: 2, + }, + V3Stats: nfs.V3Stats{ + Null: 2, + GetAttr: 112, + SetAttr: 0, + Lookup: 2719, + Access: 111, + ReadLink: 0, + Read: 0, + Write: 0, + Create: 0, + MkDir: 0, + SymLink: 0, + MkNod: 0, + Remove: 0, + RmDir: 0, + Rename: 0, + Link: 0, + ReadDir: 27, + ReadDirPlus: 216, + FsStat: 0, + FsInfo: 2, + PathConf: 1, + Commit: 0, + }, + ServerV4Stats: nfs.ServerV4Stats{ + Null: 2, + Compound: 10853, + }, + V4Ops: nfs.V4Ops{ + Op0Unused: 0, + Op1Unused: 0, + Op2Future: 0, + Access: 1098, + Close: 2, + Commit: 0, + Create: 0, + DelegPurge: 0, + DelegReturn: 0, + GetAttr: 8179, + GetFH: 5896, + Link: 0, + Lock: 0, + Lockt: 0, + Locku: 0, + Lookup: 5900, + LookupRoot: 0, + Nverify: 0, + Open: 2, + OpenAttr: 0, + OpenConfirm: 2, + OpenDgrd: 0, + PutFH: 9609, + PutPubFH: 0, + PutRootFH: 2, + Read: 150, + ReadDir: 1272, + ReadLink: 0, + Remove: 0, + Rename: 0, + Renew: 1236, + RestoreFH: 0, + SaveFH: 0, + SecInfo: 0, + SetAttr: 0, + Verify: 3, + Write: 3, + RelLockOwner: 0, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + stats, err := nfs.ParseServerRPCStats(strings.NewReader(tt.content)) + + if tt.invalid && err == nil { + t.Fatal("expected an error, but none occurred") + } + if !tt.invalid && err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if want, have := tt.stats, stats; !reflect.DeepEqual(want, have) { + t.Fatalf("unexpected NFS stats:\nwant:\n%v\nhave:\n%v", want, have) + } + }) + } +} diff --git a/vendor/github.com/prometheus/procfs/proc_io_test.go b/vendor/github.com/prometheus/procfs/proc_io_test.go new file mode 100644 index 00000000..1afdbd46 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_io_test.go @@ -0,0 +1,46 @@ +// Copyright 2018 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. + +package procfs + +import "testing" + +func TestProcIO(t *testing.T) { + p, err := FS("fixtures").NewProc(26231) + if err != nil { + t.Fatal(err) + } + + s, err := p.NewIO() + if err != nil { + t.Fatal(err) + } + + for _, test := range []struct { + name string + want int64 + have int64 + }{ + {name: "RChar", want: 750339, have: int64(s.RChar)}, + {name: "WChar", want: 818609, have: int64(s.WChar)}, + {name: "SyscR", want: 7405, have: int64(s.SyscR)}, + {name: "SyscW", want: 5245, have: int64(s.SyscW)}, + {name: "ReadBytes", want: 1024, have: int64(s.ReadBytes)}, + {name: "WriteBytes", want: 2048, have: int64(s.WriteBytes)}, + {name: "CancelledWriteBytes", want: -1024, have: s.CancelledWriteBytes}, + } { + if test.want != test.have { + t.Errorf("want %s %d, have %d", test.name, test.want, test.have) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/proc_limits_test.go b/vendor/github.com/prometheus/procfs/proc_limits_test.go new file mode 100644 index 00000000..ebb43ae7 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_limits_test.go @@ -0,0 +1,44 @@ +// Copyright 2018 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. + +package procfs + +import "testing" + +func TestNewLimits(t *testing.T) { + p, err := FS("fixtures").NewProc(26231) + if err != nil { + t.Fatal(err) + } + + l, err := p.NewLimits() + if err != nil { + t.Fatal(err) + } + + for _, test := range []struct { + name string + want int64 + have int64 + }{ + {name: "cpu time", want: -1, have: l.CPUTime}, + {name: "open files", want: 2048, have: l.OpenFiles}, + {name: "msgqueue size", want: 819200, have: l.MsqqueueSize}, + {name: "nice priority", want: 0, have: l.NicePriority}, + {name: "address space", want: 8589934592, have: l.AddressSpace}, + } { + if test.want != test.have { + t.Errorf("want %s %d, have %d", test.name, test.want, test.have) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/proc_ns_test.go b/vendor/github.com/prometheus/procfs/proc_ns_test.go new file mode 100644 index 00000000..abfd63e5 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_ns_test.go @@ -0,0 +1,44 @@ +// Copyright 2018 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. + +package procfs + +import ( + "testing" +) + +func TestNewNamespaces(t *testing.T) { + p, err := FS("fixtures").NewProc(26231) + if err != nil { + t.Fatal(err) + } + + namespaces, err := p.NewNamespaces() + if err != nil { + t.Fatal(err) + } + + expectedNamespaces := map[string]Namespace{ + "mnt": {"mnt", 4026531840}, + "net": {"net", 4026531993}, + } + + if want, have := len(expectedNamespaces), len(namespaces); want != have { + t.Errorf("want %d parsed namespaces, have %d", want, have) + } + for _, ns := range namespaces { + if want, have := expectedNamespaces[ns.Type], ns; want != have { + t.Errorf("%s: want %v, have %v", ns.Type, want, have) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/proc_stat_test.go b/vendor/github.com/prometheus/procfs/proc_stat_test.go new file mode 100644 index 00000000..e2df8845 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_stat_test.go @@ -0,0 +1,123 @@ +// Copyright 2018 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. + +package procfs + +import ( + "os" + "testing" +) + +func TestProcStat(t *testing.T) { + p, err := FS("fixtures").NewProc(26231) + if err != nil { + t.Fatal(err) + } + + s, err := p.NewStat() + if err != nil { + t.Fatal(err) + } + + for _, test := range []struct { + name string + want int + have int + }{ + {name: "pid", want: 26231, have: s.PID}, + {name: "user time", want: 1677, have: int(s.UTime)}, + {name: "system time", want: 44, have: int(s.STime)}, + {name: "start time", want: 82375, have: int(s.Starttime)}, + {name: "virtual memory size", want: 56274944, have: s.VSize}, + {name: "resident set size", want: 1981, have: s.RSS}, + } { + if test.want != test.have { + t.Errorf("want %s %d, have %d", test.name, test.want, test.have) + } + } +} + +func TestProcStatComm(t *testing.T) { + s1, err := testProcStat(26231) + if err != nil { + t.Fatal(err) + } + if want, have := "vim", s1.Comm; want != have { + t.Errorf("want comm %s, have %s", want, have) + } + + s2, err := testProcStat(584) + if err != nil { + t.Fatal(err) + } + if want, have := "(a b ) ( c d) ", s2.Comm; want != have { + t.Errorf("want comm %s, have %s", want, have) + } +} + +func TestProcStatVirtualMemory(t *testing.T) { + s, err := testProcStat(26231) + if err != nil { + t.Fatal(err) + } + + if want, have := 56274944, s.VirtualMemory(); want != have { + t.Errorf("want virtual memory %d, have %d", want, have) + } +} + +func TestProcStatResidentMemory(t *testing.T) { + s, err := testProcStat(26231) + if err != nil { + t.Fatal(err) + } + + if want, have := 1981*os.Getpagesize(), s.ResidentMemory(); want != have { + t.Errorf("want resident memory %d, have %d", want, have) + } +} + +func TestProcStatStartTime(t *testing.T) { + s, err := testProcStat(26231) + if err != nil { + t.Fatal(err) + } + + time, err := s.StartTime() + if err != nil { + t.Fatal(err) + } + if want, have := 1418184099.75, time; want != have { + t.Errorf("want start time %f, have %f", want, have) + } +} + +func TestProcStatCPUTime(t *testing.T) { + s, err := testProcStat(26231) + if err != nil { + t.Fatal(err) + } + + if want, have := 17.21, s.CPUTime(); want != have { + t.Errorf("want cpu time %f, have %f", want, have) + } +} + +func testProcStat(pid int) (ProcStat, error) { + p, err := FS("fixtures").NewProc(pid) + if err != nil { + return ProcStat{}, err + } + + return p.NewStat() +} diff --git a/vendor/github.com/prometheus/procfs/proc_test.go b/vendor/github.com/prometheus/procfs/proc_test.go new file mode 100644 index 00000000..ee7e69d6 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_test.go @@ -0,0 +1,174 @@ +// Copyright 2018 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. + +package procfs + +import ( + "reflect" + "sort" + "testing" +) + +func TestSelf(t *testing.T) { + fs := FS("fixtures") + + p1, err := fs.NewProc(26231) + if err != nil { + t.Fatal(err) + } + p2, err := fs.Self() + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(p1, p2) { + t.Errorf("want process %v, have %v", p1, p2) + } +} + +func TestAllProcs(t *testing.T) { + procs, err := FS("fixtures").AllProcs() + if err != nil { + t.Fatal(err) + } + sort.Sort(procs) + for i, p := range []*Proc{{PID: 584}, {PID: 26231}} { + if want, have := p.PID, procs[i].PID; want != have { + t.Errorf("want processes %d, have %d", want, have) + } + } +} + +func TestCmdLine(t *testing.T) { + for _, tt := range []struct { + process int + want []string + }{ + {process: 26231, want: []string{"vim", "test.go", "+10"}}, + {process: 26232, want: []string{}}, + {process: 26233, want: []string{"com.github.uiautomator"}}, + } { + p1, err := FS("fixtures").NewProc(tt.process) + if err != nil { + t.Fatal(err) + } + c1, err := p1.CmdLine() + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(tt.want, c1) { + t.Errorf("want cmdline %v, have %v", tt.want, c1) + } + } +} + +func TestComm(t *testing.T) { + for _, tt := range []struct { + process int + want string + }{ + {process: 26231, want: "vim"}, + {process: 26232, want: "ata_sff"}, + } { + p1, err := FS("fixtures").NewProc(tt.process) + if err != nil { + t.Fatal(err) + } + c1, err := p1.Comm() + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(tt.want, c1) { + t.Errorf("want comm %v, have %v", tt.want, c1) + } + } +} + +func TestExecutable(t *testing.T) { + for _, tt := range []struct { + process int + want string + }{ + {process: 26231, want: "/usr/bin/vim"}, + {process: 26232, want: ""}, + } { + p, err := FS("fixtures").NewProc(tt.process) + if err != nil { + t.Fatal(err) + } + exe, err := p.Executable() + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(tt.want, exe) { + t.Errorf("want absolute path to cmdline %v, have %v", tt.want, exe) + } + } +} + +func TestFileDescriptors(t *testing.T) { + p1, err := FS("fixtures").NewProc(26231) + if err != nil { + t.Fatal(err) + } + fds, err := p1.FileDescriptors() + if err != nil { + t.Fatal(err) + } + sort.Sort(byUintptr(fds)) + if want := []uintptr{0, 1, 2, 3, 10}; !reflect.DeepEqual(want, fds) { + t.Errorf("want fds %v, have %v", want, fds) + } +} + +func TestFileDescriptorTargets(t *testing.T) { + p1, err := FS("fixtures").NewProc(26231) + if err != nil { + t.Fatal(err) + } + fds, err := p1.FileDescriptorTargets() + if err != nil { + t.Fatal(err) + } + sort.Strings(fds) + var want = []string{ + "../../symlinktargets/abc", + "../../symlinktargets/def", + "../../symlinktargets/ghi", + "../../symlinktargets/uvw", + "../../symlinktargets/xyz", + } + if !reflect.DeepEqual(want, fds) { + t.Errorf("want fds %v, have %v", want, fds) + } +} + +func TestFileDescriptorsLen(t *testing.T) { + p1, err := FS("fixtures").NewProc(26231) + if err != nil { + t.Fatal(err) + } + l, err := p1.FileDescriptorsLen() + if err != nil { + t.Fatal(err) + } + if want, have := 5, l; want != have { + t.Errorf("want fds %d, have %d", want, have) + } +} + +type byUintptr []uintptr + +func (a byUintptr) Len() int { return len(a) } +func (a byUintptr) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byUintptr) Less(i, j int) bool { return a[i] < a[j] } diff --git a/vendor/github.com/prometheus/procfs/scripts/check_license.sh b/vendor/github.com/prometheus/procfs/scripts/check_license.sh new file mode 100755 index 00000000..ac13e960 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/scripts/check_license.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Copyright 2018 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. + +check_license() { + local file="" + for file in $(find . -type f -iname '*.go' ! -path './vendor/*'); do + head -n3 "${file}" | grep -Eq "(Copyright|generated|GENERATED)" || echo " ${file}" + done +} + +licRes=$(check_license) + +if [ -n "${licRes}" ]; then + echo "license header checking failed:" + echo "${licRes}" + exit 255 +fi diff --git a/vendor/github.com/prometheus/procfs/stat_test.go b/vendor/github.com/prometheus/procfs/stat_test.go new file mode 100644 index 00000000..2043b5e4 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/stat_test.go @@ -0,0 +1,74 @@ +// Copyright 2018 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. + +package procfs + +import "testing" + +func TestStat(t *testing.T) { + s, err := FS("fixtures").NewStat() + if err != nil { + t.Fatal(err) + } + + // cpu + if want, have := float64(301854)/userHZ, s.CPUTotal.User; want != have { + t.Errorf("want cpu/user %v, have %v", want, have) + } + if want, have := float64(31)/userHZ, s.CPU[7].SoftIRQ; want != have { + t.Errorf("want cpu7/softirq %v, have %v", want, have) + } + + // intr + if want, have := uint64(8885917), s.IRQTotal; want != have { + t.Errorf("want irq/total %d, have %d", want, have) + } + if want, have := uint64(1), s.IRQ[8]; want != have { + t.Errorf("want irq8 %d, have %d", want, have) + } + + // ctxt + if want, have := uint64(38014093), s.ContextSwitches; want != have { + t.Errorf("want context switches (ctxt) %d, have %d", want, have) + } + + // btime + if want, have := uint64(1418183276), s.BootTime; want != have { + t.Errorf("want boot time (btime) %d, have %d", want, have) + } + + // processes + if want, have := uint64(26442), s.ProcessCreated; want != have { + t.Errorf("want process created (processes) %d, have %d", want, have) + } + + // procs_running + if want, have := uint64(2), s.ProcessesRunning; want != have { + t.Errorf("want processes running (procs_running) %d, have %d", want, have) + } + + // procs_blocked + if want, have := uint64(1), s.ProcessesBlocked; want != have { + t.Errorf("want processes blocked (procs_blocked) %d, have %d", want, have) + } + + // softirq + if want, have := uint64(5057579), s.SoftIRQTotal; want != have { + t.Errorf("want softirq total %d, have %d", want, have) + } + + if want, have := uint64(508444), s.SoftIRQ.Rcu; want != have { + t.Errorf("want softirq RCU %d, have %d", want, have) + } + +} diff --git a/vendor/github.com/prometheus/procfs/sysfs/.gitignore b/vendor/github.com/prometheus/procfs/sysfs/.gitignore new file mode 100644 index 00000000..67fc140b --- /dev/null +++ b/vendor/github.com/prometheus/procfs/sysfs/.gitignore @@ -0,0 +1 @@ +fixtures/ diff --git a/vendor/github.com/prometheus/procfs/sysfs/fixtures.ttar b/vendor/github.com/prometheus/procfs/sysfs/fixtures.ttar index 8e665ce5..9731b508 100644 --- a/vendor/github.com/prometheus/procfs/sysfs/fixtures.ttar +++ b/vendor/github.com/prometheus/procfs/sysfs/fixtures.ttar @@ -1,7 +1,142 @@ -# Archive created by ttar -c -f fixtures.ttar fixtures/ +# Archive created by ttar -C sysfs/ -c -f sysfs/fixtures.ttar fixtures/ Directory: fixtures Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/class +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/class/net +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/class/net/eth0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/addr_assign_type +Lines: 1 +3 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/addr_len +Lines: 1 +6 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/address +Lines: 1 +01:01:01:01:01:01 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/broadcast +Lines: 1 +ff:ff:ff:ff:ff:ff +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/carrier +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/carrier_changes +Lines: 1 +2 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/carrier_down_count +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/carrier_up_count +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/dev_id +Lines: 1 +0x20 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/dormant +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/duplex +Lines: 1 +full +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/flags +Lines: 1 +0x1303 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/ifalias +Lines: 0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/ifindex +Lines: 1 +2 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/iflink +Lines: 1 +2 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/link_mode +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/mtu +Lines: 1 +1500 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/name_assign_type +Lines: 1 +2 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/netdev_group +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/operstate +Lines: 1 +up +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/phys_port_id +Lines: 0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/phys_port_name +Lines: 0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/phys_switch_id +Lines: 0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/speed +Lines: 1 +1000 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/tx_queue_len +Lines: 1 +1000 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/class/net/eth0/type +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/devices Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -720,132 +855,3 @@ Lines: 1 extent_alloc 2 0 0 0 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/class/net/eth0/ -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/addr_assign_type -Lines: 1 -3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/addr_len -Lines: 1 -6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/address -Lines: 1 -01:01:01:01:01:01 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/broadcast -Lines: 1 -ff:ff:ff:ff:ff:ff -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/carrier -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/carrier_changes -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/carrier_down_count -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/carrier_up_count -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/dev_id -Lines: 1 -0x20 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/dormant -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/duplex -Lines: 1 -full -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/flags -Lines: 1 -0x1303 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/ifalias -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/ifindex -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/iflink -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/link_mode -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/mtu -Lines: 1 -1500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/name_assign_type -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/netdev_group -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/operstate -Lines: 1 -up -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/phys_port_id -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/phys_port_name -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/phys_switch_id -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/speed -Lines: 1 -1000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/tx_queue_len -Lines: 1 -1000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/class/net/eth0/type -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/prometheus/procfs/sysfs/fs_test.go b/vendor/github.com/prometheus/procfs/sysfs/fs_test.go new file mode 100644 index 00000000..2b7402ec --- /dev/null +++ b/vendor/github.com/prometheus/procfs/sysfs/fs_test.go @@ -0,0 +1,108 @@ +// Copyright 2017 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. + +package sysfs + +import "testing" + +func TestNewFS(t *testing.T) { + if _, err := NewFS("foobar"); err == nil { + t.Error("want NewFS to fail for non-existing mount point") + } + + if _, err := NewFS("doc.go"); err == nil { + t.Error("want NewFS to fail if mount point is not a directory") + } +} + +func TestFSXFSStats(t *testing.T) { + stats, err := FS("fixtures").XFSStats() + if err != nil { + t.Fatalf("failed to parse XFS stats: %v", err) + } + + tests := []struct { + name string + allocated uint32 + }{ + { + name: "sda1", + allocated: 1, + }, + { + name: "sdb1", + allocated: 2, + }, + } + + const expect = 2 + + if l := len(stats); l != expect { + t.Fatalf("unexpected number of XFS stats: %d", l) + } + if l := len(tests); l != expect { + t.Fatalf("unexpected number of tests: %d", l) + } + + for i, tt := range tests { + if want, got := tt.name, stats[i].Name; want != got { + t.Errorf("unexpected stats name:\nwant: %q\nhave: %q", want, got) + } + + if want, got := tt.allocated, stats[i].ExtentAllocation.ExtentsAllocated; want != got { + t.Errorf("unexpected extents allocated:\nwant: %d\nhave: %d", want, got) + } + } +} + +func TestFSBcacheStats(t *testing.T) { + stats, err := FS("fixtures").BcacheStats() + if err != nil { + t.Fatalf("failed to parse bcache stats: %v", err) + } + + tests := []struct { + name string + bdevs int + caches int + }{ + { + name: "deaddd54-c735-46d5-868e-f331c5fd7c74", + bdevs: 1, + caches: 1, + }, + } + + const expect = 1 + + if l := len(stats); l != expect { + t.Fatalf("unexpected number of bcache stats: %d", l) + } + if l := len(tests); l != expect { + t.Fatalf("unexpected number of tests: %d", l) + } + + for i, tt := range tests { + if want, got := tt.name, stats[i].Name; want != got { + t.Errorf("unexpected stats name:\nwant: %q\nhave: %q", want, got) + } + + if want, got := tt.bdevs, len(stats[i].Bdevs); want != got { + t.Errorf("unexpected value allocated:\nwant: %d\nhave: %d", want, got) + } + + if want, got := tt.caches, len(stats[i].Caches); want != got { + t.Errorf("unexpected value allocated:\nwant: %d\nhave: %d", want, got) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/sysfs/net_class_test.go b/vendor/github.com/prometheus/procfs/sysfs/net_class_test.go new file mode 100644 index 00000000..e6d05f01 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/sysfs/net_class_test.go @@ -0,0 +1,88 @@ +// Copyright 2018 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. + +package sysfs + +import ( + "reflect" + "testing" +) + +func TestNewNetClass(t *testing.T) { + fs, err := NewFS("fixtures") + if err != nil { + t.Fatal(err) + } + + nc, err := fs.NewNetClass() + if err != nil { + t.Fatal(err) + } + + var ( + addrAssignType int64 = 3 + addrLen int64 = 6 + carrier int64 = 1 + carrierChanges int64 = 2 + carrierDownCount int64 = 1 + carrierUpCount int64 = 1 + devID int64 = 32 + dormant int64 = 1 + flags int64 = 4867 + ifIndex int64 = 2 + ifLink int64 = 2 + linkMode int64 = 1 + mtu int64 = 1500 + nameAssignType int64 = 2 + netDevGroup int64 = 0 + speed int64 = 1000 + txQueueLen int64 = 1000 + netType int64 = 1 + ) + + netClass := NetClass{ + "eth0": { + Address: "01:01:01:01:01:01", + AddrAssignType: &addrAssignType, + AddrLen: &addrLen, + Broadcast: "ff:ff:ff:ff:ff:ff", + Carrier: &carrier, + CarrierChanges: &carrierChanges, + CarrierDownCount: &carrierDownCount, + CarrierUpCount: &carrierUpCount, + DevID: &devID, + Dormant: &dormant, + Duplex: "full", + Flags: &flags, + IfAlias: "", + IfIndex: &ifIndex, + IfLink: &ifLink, + LinkMode: &linkMode, + MTU: &mtu, + Name: "eth0", + NameAssignType: &nameAssignType, + NetDevGroup: &netDevGroup, + OperState: "up", + PhysPortID: "", + PhysPortName: "", + PhysSwitchID: "", + Speed: &speed, + TxQueueLen: &txQueueLen, + Type: &netType, + }, + } + + if !reflect.DeepEqual(netClass, nc) { + t.Errorf("Result not correct: want %v, have %v", netClass, nc) + } +} diff --git a/vendor/github.com/prometheus/procfs/xfrm.go b/vendor/github.com/prometheus/procfs/xfrm.go index ffe9df50..8f1508f0 100644 --- a/vendor/github.com/prometheus/procfs/xfrm.go +++ b/vendor/github.com/prometheus/procfs/xfrm.go @@ -113,7 +113,7 @@ func (fs FS) NewXfrmStat() (XfrmStat, error) { if len(fields) != 2 { return XfrmStat{}, fmt.Errorf( - "couldnt parse %s line %s", file.Name(), s.Text()) + "couldn't parse %s line %s", file.Name(), s.Text()) } name := fields[0] diff --git a/vendor/github.com/prometheus/procfs/xfrm_test.go b/vendor/github.com/prometheus/procfs/xfrm_test.go new file mode 100644 index 00000000..5918c390 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/xfrm_test.go @@ -0,0 +1,66 @@ +// Copyright 2017 Prometheus Team +// 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. + +package procfs + +import ( + "testing" +) + +func TestXfrmStats(t *testing.T) { + xfrmStats, err := FS("fixtures").NewXfrmStat() + if err != nil { + t.Fatal(err) + } + + for _, test := range []struct { + name string + want int + got int + }{ + {name: "XfrmInError", want: 1, got: xfrmStats.XfrmInError}, + {name: "XfrmInBufferError", want: 2, got: xfrmStats.XfrmInBufferError}, + {name: "XfrmInHdrError", want: 4, got: xfrmStats.XfrmInHdrError}, + {name: "XfrmInNoStates", want: 3, got: xfrmStats.XfrmInNoStates}, + {name: "XfrmInStateProtoError", want: 40, got: xfrmStats.XfrmInStateProtoError}, + {name: "XfrmInStateModeError", want: 100, got: xfrmStats.XfrmInStateModeError}, + {name: "XfrmInStateSeqError", want: 6000, got: xfrmStats.XfrmInStateSeqError}, + {name: "XfrmInStateExpired", want: 4, got: xfrmStats.XfrmInStateExpired}, + {name: "XfrmInStateMismatch", want: 23451, got: xfrmStats.XfrmInStateMismatch}, + {name: "XfrmInStateInvalid", want: 55555, got: xfrmStats.XfrmInStateInvalid}, + {name: "XfrmInTmplMismatch", want: 51, got: xfrmStats.XfrmInTmplMismatch}, + {name: "XfrmInNoPols", want: 65432, got: xfrmStats.XfrmInNoPols}, + {name: "XfrmInPolBlock", want: 100, got: xfrmStats.XfrmInPolBlock}, + {name: "XfrmInPolError", want: 10000, got: xfrmStats.XfrmInPolError}, + {name: "XfrmOutError", want: 1000000, got: xfrmStats.XfrmOutError}, + {name: "XfrmOutBundleGenError", want: 43321, got: xfrmStats.XfrmOutBundleGenError}, + {name: "XfrmOutBundleCheckError", want: 555, got: xfrmStats.XfrmOutBundleCheckError}, + {name: "XfrmOutNoStates", want: 869, got: xfrmStats.XfrmOutNoStates}, + {name: "XfrmOutStateProtoError", want: 4542, got: xfrmStats.XfrmOutStateProtoError}, + {name: "XfrmOutStateModeError", want: 4, got: xfrmStats.XfrmOutStateModeError}, + {name: "XfrmOutStateSeqError", want: 543, got: xfrmStats.XfrmOutStateSeqError}, + {name: "XfrmOutStateExpired", want: 565, got: xfrmStats.XfrmOutStateExpired}, + {name: "XfrmOutPolBlock", want: 43456, got: xfrmStats.XfrmOutPolBlock}, + {name: "XfrmOutPolDead", want: 7656, got: xfrmStats.XfrmOutPolDead}, + {name: "XfrmOutPolError", want: 1454, got: xfrmStats.XfrmOutPolError}, + {name: "XfrmFwdHdrError", want: 6654, got: xfrmStats.XfrmFwdHdrError}, + {name: "XfrmOutStateInvaliad", want: 28765, got: xfrmStats.XfrmOutStateInvalid}, + {name: "XfrmAcquireError", want: 24532, got: xfrmStats.XfrmAcquireError}, + {name: "XfrmInStateInvalid", want: 55555, got: xfrmStats.XfrmInStateInvalid}, + {name: "XfrmOutError", want: 1000000, got: xfrmStats.XfrmOutError}, + } { + if test.want != test.got { + t.Errorf("Want %s %d, have %d", test.name, test.want, test.got) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/xfs/parse_test.go b/vendor/github.com/prometheus/procfs/xfs/parse_test.go new file mode 100644 index 00000000..2e946c2c --- /dev/null +++ b/vendor/github.com/prometheus/procfs/xfs/parse_test.go @@ -0,0 +1,442 @@ +// Copyright 2017 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. + +package xfs_test + +import ( + "reflect" + "strings" + "testing" + + "github.com/prometheus/procfs" + "github.com/prometheus/procfs/xfs" +) + +func TestParseStats(t *testing.T) { + tests := []struct { + name string + s string + fs bool + stats *xfs.Stats + invalid bool + }{ + { + name: "empty file OK", + }, + { + name: "short or empty lines and unknown labels ignored", + s: "one\n\ntwo 1 2 3\n", + stats: &xfs.Stats{}, + }, + { + name: "bad uint32", + s: "extent_alloc XXX", + invalid: true, + }, + { + name: "bad uint64", + s: "xpc XXX", + invalid: true, + }, + { + name: "extent_alloc bad", + s: "extent_alloc 1", + invalid: true, + }, + { + name: "extent_alloc OK", + s: "extent_alloc 1 2 3 4", + stats: &xfs.Stats{ + ExtentAllocation: xfs.ExtentAllocationStats{ + ExtentsAllocated: 1, + BlocksAllocated: 2, + ExtentsFreed: 3, + BlocksFreed: 4, + }, + }, + }, + { + name: "abt bad", + s: "abt 1", + invalid: true, + }, + { + name: "abt OK", + s: "abt 1 2 3 4", + stats: &xfs.Stats{ + AllocationBTree: xfs.BTreeStats{ + Lookups: 1, + Compares: 2, + RecordsInserted: 3, + RecordsDeleted: 4, + }, + }, + }, + { + name: "blk_map bad", + s: "blk_map 1", + invalid: true, + }, + { + name: "blk_map OK", + s: "blk_map 1 2 3 4 5 6 7", + stats: &xfs.Stats{ + BlockMapping: xfs.BlockMappingStats{ + Reads: 1, + Writes: 2, + Unmaps: 3, + ExtentListInsertions: 4, + ExtentListDeletions: 5, + ExtentListLookups: 6, + ExtentListCompares: 7, + }, + }, + }, + { + name: "bmbt bad", + s: "bmbt 1", + invalid: true, + }, + { + name: "bmbt OK", + s: "bmbt 1 2 3 4", + stats: &xfs.Stats{ + BlockMapBTree: xfs.BTreeStats{ + Lookups: 1, + Compares: 2, + RecordsInserted: 3, + RecordsDeleted: 4, + }, + }, + }, + { + name: "dir bad", + s: "dir 1", + invalid: true, + }, + { + name: "dir OK", + s: "dir 1 2 3 4", + stats: &xfs.Stats{ + DirectoryOperation: xfs.DirectoryOperationStats{ + Lookups: 1, + Creates: 2, + Removes: 3, + Getdents: 4, + }, + }, + }, + { + name: "trans bad", + s: "trans 1", + invalid: true, + }, + { + name: "trans OK", + s: "trans 1 2 3", + stats: &xfs.Stats{ + Transaction: xfs.TransactionStats{ + Sync: 1, + Async: 2, + Empty: 3, + }, + }, + }, + { + name: "ig bad", + s: "ig 1", + invalid: true, + }, + { + name: "ig OK", + s: "ig 1 2 3 4 5 6 7", + stats: &xfs.Stats{ + InodeOperation: xfs.InodeOperationStats{ + Attempts: 1, + Found: 2, + Recycle: 3, + Missed: 4, + Duplicate: 5, + Reclaims: 6, + AttributeChange: 7, + }, + }, + }, + { + name: "log bad", + s: "log 1", + invalid: true, + }, + { + name: "log OK", + s: "log 1 2 3 4 5", + stats: &xfs.Stats{ + LogOperation: xfs.LogOperationStats{ + Writes: 1, + Blocks: 2, + NoInternalBuffers: 3, + Force: 4, + ForceSleep: 5, + }, + }, + }, + { + name: "rw bad", + s: "rw 1", + invalid: true, + }, + { + name: "rw OK", + s: "rw 1 2", + stats: &xfs.Stats{ + ReadWrite: xfs.ReadWriteStats{ + Read: 1, + Write: 2, + }, + }, + }, + { + name: "attr bad", + s: "attr 1", + invalid: true, + }, + { + name: "attr OK", + s: "attr 1 2 3 4", + stats: &xfs.Stats{ + AttributeOperation: xfs.AttributeOperationStats{ + Get: 1, + Set: 2, + Remove: 3, + List: 4, + }, + }, + }, + { + name: "icluster bad", + s: "icluster 1", + invalid: true, + }, + { + name: "icluster OK", + s: "icluster 1 2 3", + stats: &xfs.Stats{ + InodeClustering: xfs.InodeClusteringStats{ + Iflush: 1, + Flush: 2, + FlushInode: 3, + }, + }, + }, + { + name: "vnodes bad", + s: "vnodes 1", + invalid: true, + }, + { + name: "vnodes (missing free) OK", + s: "vnodes 1 2 3 4 5 6 7", + stats: &xfs.Stats{ + Vnode: xfs.VnodeStats{ + Active: 1, + Allocate: 2, + Get: 3, + Hold: 4, + Release: 5, + Reclaim: 6, + Remove: 7, + }, + }, + }, + { + name: "vnodes (with free) OK", + s: "vnodes 1 2 3 4 5 6 7 8", + stats: &xfs.Stats{ + Vnode: xfs.VnodeStats{ + Active: 1, + Allocate: 2, + Get: 3, + Hold: 4, + Release: 5, + Reclaim: 6, + Remove: 7, + Free: 8, + }, + }, + }, + { + name: "buf bad", + s: "buf 1", + invalid: true, + }, + { + name: "buf OK", + s: "buf 1 2 3 4 5 6 7 8 9", + stats: &xfs.Stats{ + Buffer: xfs.BufferStats{ + Get: 1, + Create: 2, + GetLocked: 3, + GetLockedWaited: 4, + BusyLocked: 5, + MissLocked: 6, + PageRetries: 7, + PageFound: 8, + GetRead: 9, + }, + }, + }, + { + name: "xpc bad", + s: "xpc 1", + invalid: true, + }, + { + name: "xpc OK", + s: "xpc 1 2 3", + stats: &xfs.Stats{ + ExtendedPrecision: xfs.ExtendedPrecisionStats{ + FlushBytes: 1, + WriteBytes: 2, + ReadBytes: 3, + }, + }, + }, + { + name: "fixtures OK", + fs: true, + stats: &xfs.Stats{ + ExtentAllocation: xfs.ExtentAllocationStats{ + ExtentsAllocated: 92447, + BlocksAllocated: 97589, + ExtentsFreed: 92448, + BlocksFreed: 93751, + }, + AllocationBTree: xfs.BTreeStats{ + Lookups: 0, + Compares: 0, + RecordsInserted: 0, + RecordsDeleted: 0, + }, + BlockMapping: xfs.BlockMappingStats{ + Reads: 1767055, + Writes: 188820, + Unmaps: 184891, + ExtentListInsertions: 92447, + ExtentListDeletions: 92448, + ExtentListLookups: 2140766, + ExtentListCompares: 0, + }, + BlockMapBTree: xfs.BTreeStats{ + Lookups: 0, + Compares: 0, + RecordsInserted: 0, + RecordsDeleted: 0, + }, + DirectoryOperation: xfs.DirectoryOperationStats{ + Lookups: 185039, + Creates: 92447, + Removes: 92444, + Getdents: 136422, + }, + Transaction: xfs.TransactionStats{ + Sync: 706, + Async: 944304, + Empty: 0, + }, + InodeOperation: xfs.InodeOperationStats{ + Attempts: 185045, + Found: 58807, + Recycle: 0, + Missed: 126238, + Duplicate: 0, + Reclaims: 33637, + AttributeChange: 22, + }, + LogOperation: xfs.LogOperationStats{ + Writes: 2883, + Blocks: 113448, + NoInternalBuffers: 9, + Force: 17360, + ForceSleep: 739, + }, + ReadWrite: xfs.ReadWriteStats{ + Read: 107739, + Write: 94045, + }, + AttributeOperation: xfs.AttributeOperationStats{ + Get: 4, + Set: 0, + Remove: 0, + List: 0, + }, + InodeClustering: xfs.InodeClusteringStats{ + Iflush: 8677, + Flush: 7849, + FlushInode: 135802, + }, + Vnode: xfs.VnodeStats{ + Active: 92601, + Allocate: 0, + Get: 0, + Hold: 0, + Release: 92444, + Reclaim: 92444, + Remove: 92444, + Free: 0, + }, + Buffer: xfs.BufferStats{ + Get: 2666287, + Create: 7122, + GetLocked: 2659202, + GetLockedWaited: 3599, + BusyLocked: 2, + MissLocked: 7085, + PageRetries: 0, + PageFound: 10297, + GetRead: 7085, + }, + ExtendedPrecision: xfs.ExtendedPrecisionStats{ + FlushBytes: 399724544, + WriteBytes: 92823103, + ReadBytes: 86219234, + }, + }, + }, + } + + for _, tt := range tests { + var ( + stats *xfs.Stats + err error + ) + + if tt.s != "" { + stats, err = xfs.ParseStats(strings.NewReader(tt.s)) + } + if tt.fs { + stats, err = procfs.FS("../fixtures").XFSStats() + } + + if tt.invalid && err == nil { + t.Error("expected an error, but none occurred") + } + if !tt.invalid && err != nil { + t.Errorf("unexpected error: %v", err) + } + + if want, have := tt.stats, stats; !reflect.DeepEqual(want, have) { + t.Errorf("unexpected XFS stats:\nwant:\n%v\nhave:\n%v", want, have) + } + } +}