@@ -43,42 +43,85 @@ pub(crate) async fn get_path(pid: i32) -> Result<PathBuf, Error> {
43
43
}
44
44
45
45
/// Polls for any cgroup metrics that can be read, v2 version.
46
- pub ( crate ) async fn poll ( path : PathBuf , labels : & [ ( String , String ) ] ) -> Result < ( ) , Error > {
47
- let mut entries = fs:: read_dir ( & path) . await ?;
46
+ pub ( crate ) async fn poll ( file_path : PathBuf , labels : & [ ( String , String ) ] ) -> Result < ( ) , Error > {
47
+ // Read all files in the cgroup `path` and create metrics for them. If we
48
+ // lack permissions to read we skip the file. We do not use ? to allow for
49
+ // the maximal number of files to be read.
50
+ match fs:: read_dir ( & file_path) . await {
51
+ Ok ( mut entries) => {
52
+ match entries. next_entry ( ) . await {
53
+ Ok ( maybe_entry) => {
54
+ if let Some ( entry) = maybe_entry {
55
+ match entry. metadata ( ) . await {
56
+ Ok ( metadata) => {
57
+ if metadata. is_file ( ) {
58
+ let file_name = entry. file_name ( ) ;
59
+ let metric_prefix = match file_name. to_str ( ) {
60
+ Some ( s) => String :: from ( s) ,
61
+ None => {
62
+ // Skip files with non-UTF-8 names
63
+ return Ok ( ( ) ) ;
64
+ }
65
+ } ;
66
+ let file_path = entry. path ( ) ;
48
67
49
- while let Some ( entry) = entries. next_entry ( ) . await ? {
50
- let metadata = entry. metadata ( ) . await ?;
51
- if metadata. is_file ( ) {
52
- let file_name = entry. file_name ( ) ;
53
- let metric_prefix = match file_name. to_str ( ) {
54
- Some ( s) => String :: from ( s) ,
55
- None => {
56
- // Skip files with non-UTF-8 names
57
- continue ;
58
- }
59
- } ;
60
- let file_path = entry. path ( ) ;
61
-
62
- let content = fs:: read_to_string ( & file_path) . await ?;
63
- let content = content. trim ( ) ;
68
+ match fs:: read_to_string ( & file_path) . await {
69
+ Ok ( content) => {
70
+ let content = content. trim ( ) ;
64
71
65
- // Cgroup files that have values are either single-valued or
66
- // key-value pairs. For single-valued files, we create a single
67
- // metric and for key-value pairs, we create metrics with the same
68
- // scheme as single-valued files but tack on the key to the metric
69
- // name.
70
- if let Ok ( value) = content. parse :: < f64 > ( ) {
71
- // Single-valued
72
- gauge ! ( metric_prefix, labels) . set ( value) ;
73
- } else {
74
- // Key-value pairs
75
- if kv_pairs ( & file_path, content, & metric_prefix, labels) . is_err ( ) {
76
- // File may fail to parse, for instance cgroup.controllers
77
- // is a list of strings.
78
- continue ;
72
+ // Cgroup files that have values are either single-valued or
73
+ // key-value pairs. For single-valued files, we create a single
74
+ // metric and for key-value pairs, we create metrics with the same
75
+ // scheme as single-valued files but tack on the key to the metric
76
+ // name.
77
+ if let Ok ( value) = content. parse :: < f64 > ( ) {
78
+ // Single-valued
79
+ gauge ! ( metric_prefix, labels) . set ( value) ;
80
+ } else {
81
+ // Key-value pairs
82
+ if kv_pairs (
83
+ & file_path,
84
+ content,
85
+ & metric_prefix,
86
+ labels,
87
+ )
88
+ . is_err ( )
89
+ {
90
+ // File may fail to parse, for instance cgroup.controllers
91
+ // is a list of strings.
92
+ return Ok ( ( ) ) ;
93
+ }
94
+ }
95
+ }
96
+ Err ( err) => {
97
+ debug ! (
98
+ "[{path}] failed to read cgroup file contents: {err:?}" ,
99
+ path = file_path. to_string_lossy( )
100
+ ) ;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ Err ( err) => {
106
+ debug ! (
107
+ "[{path}] failed to read metadata for cgroup file: {err:?}" ,
108
+ path = file_path. to_string_lossy( )
109
+ ) ;
110
+ }
111
+ }
112
+ }
113
+ }
114
+ Err ( err) => {
115
+ debug ! (
116
+ "[{path}] failed to read entry in cgroup directory: {err:?}" ,
117
+ path = file_path. to_string_lossy( )
118
+ ) ;
79
119
}
80
120
}
81
121
}
122
+ Err ( err) => {
123
+ debug ! ( "Failed to read cgroup directory: {err:?}" , ) ;
124
+ }
82
125
}
83
126
84
127
Ok ( ( ) )
@@ -99,13 +142,13 @@ fn kv_pairs(
99
142
gauge ! ( metric_name, labels) . set ( value) ;
100
143
} else {
101
144
debug ! (
102
- "[{path}] missing value in key/value pair: {content} " ,
145
+ "[{path}] missing value in key/value pair, skipping " ,
103
146
path = file_path. to_string_lossy( ) ,
104
147
) ;
105
148
}
106
149
} else {
107
150
debug ! (
108
- "[{path} missing key in key/value pair: {content} " ,
151
+ "[{path} missing key in key/value pair, skipping " ,
109
152
path = file_path. to_string_lossy( ) ,
110
153
) ;
111
154
}
0 commit comments