1
- use procfs:: process:: Process ;
1
+ use std:: time:: { Instant , SystemTime , UNIX_EPOCH } ;
2
+
3
+ use procfs:: process:: { LimitValue , Process } ;
2
4
use prometheus_client:: {
3
5
collector:: Collector ,
4
6
encoding:: { DescriptorEncoder , EncodeMetric } ,
5
- metrics:: counter:: ConstCounter ,
7
+ metrics:: { counter:: ConstCounter , gauge :: ConstGauge } ,
6
8
registry:: Unit ,
7
9
} ;
8
10
@@ -14,45 +16,100 @@ pub struct ProcessCollector {
14
16
impl Collector for ProcessCollector {
15
17
fn encode ( & self , mut encoder : DescriptorEncoder ) -> Result < ( ) , std:: fmt:: Error > {
16
18
let tps = procfs:: ticks_per_second ( ) ;
17
- // process_cpu_seconds_total Total user and system CPU time spent in seconds.
18
- // process_max_fds Maximum number of open file descriptors.
19
- // process_open_fds Number of open file descriptors.
20
- // process_virtual_memory_bytes Virtual memory size in bytes.
21
- // process_resident_memory_bytes Resident memory size in bytes.
22
- // process_virtual_memory_max_bytes Maximum amount of virtual memory available in bytes.
23
- // process_start_time_seconds Start time of the process since unix epoch in seconds.
24
- // process_network_receive_bytes_total Number of bytes received by the process over the network.
25
- // process_network_transmit_bytes_total Number of bytes sent by the process over the network.
26
19
27
- if let Ok ( proc) = Process :: myself ( ) {
28
- if let Ok ( stat) = proc. stat ( ) {
29
- let cpu_time = ( stat. stime + stat. utime ) / tps as u64 ;
30
- let counter = ConstCounter :: new ( cpu_time) ;
31
- let metric_encoder = encoder. encode_descriptor (
32
- "process_cpu_seconds_total" ,
33
- "Total user and system CPU time spent in seconds." ,
34
- Some ( & Unit :: Seconds ) ,
35
- counter. metric_type ( ) ,
36
- ) ?;
37
- counter. encode ( metric_encoder) ?;
20
+ // TODO: handle errors
21
+ let proc = match Process :: myself ( ) {
22
+ Ok ( proc) => proc,
23
+ Err ( _) => {
24
+ return Ok ( ( ) ) ;
38
25
}
39
-
40
- if let Ok ( limits) = proc. limits ( ) {
41
- let max_fds = match limits. max_open_files . soft_limit {
42
- procfs:: process:: LimitValue :: Value ( v) => v,
43
- procfs:: process:: LimitValue :: Unlimited => 0 ,
44
- } ;
45
- let counter = ConstCounter :: new ( max_fds) ;
46
- let metric_encoder = encoder. encode_descriptor (
47
- "process_max_fds" ,
48
- "Maximum number of open file descriptors." ,
49
- None ,
50
- counter. metric_type ( ) ,
51
- ) ?;
52
- counter. encode ( metric_encoder) ?;
26
+ } ;
27
+ let stat = match proc. stat ( ) {
28
+ Ok ( stat) => stat,
29
+ Err ( _) => {
30
+ return Ok ( ( ) ) ;
53
31
}
32
+ } ;
33
+
34
+ let cpu_time = ( stat. stime + stat. utime ) / tps;
35
+ let counter = ConstCounter :: new ( cpu_time) ;
36
+ let metric_encoder = encoder. encode_descriptor (
37
+ "process_cpu_seconds_total" ,
38
+ "Total user and system CPU time spent in seconds." ,
39
+ Some ( & Unit :: Seconds ) ,
40
+ counter. metric_type ( ) ,
41
+ ) ?;
42
+ counter. encode ( metric_encoder) ?;
43
+
44
+ if let Ok ( limits) = proc. limits ( ) {
45
+ let max_open_files = limits. max_open_files ;
46
+ let max_fds = match max_open_files. soft_limit {
47
+ LimitValue :: Unlimited => match max_open_files. hard_limit {
48
+ LimitValue :: Unlimited => 0 ,
49
+ LimitValue :: Value ( hard) => hard,
50
+ } ,
51
+ LimitValue :: Value ( soft) => soft,
52
+ } ;
53
+ let gauge = ConstGauge :: new ( max_fds as i64 ) ;
54
+ let metric_encoder = encoder. encode_descriptor (
55
+ "process_max_fds" ,
56
+ "Maximum number of open file descriptors." ,
57
+ None ,
58
+ gauge. metric_type ( ) ,
59
+ ) ?;
60
+ gauge. encode ( metric_encoder) ?;
61
+
62
+ let max_address_space = limits. max_address_space ;
63
+ let max_virtual_memory = match max_address_space. soft_limit {
64
+ LimitValue :: Unlimited => match max_address_space. hard_limit {
65
+ LimitValue :: Unlimited => 0 ,
66
+ LimitValue :: Value ( hard) => hard,
67
+ } ,
68
+ LimitValue :: Value ( soft) => soft,
69
+ } ;
70
+ let gauge = ConstGauge :: new ( max_fds as i64 ) ;
71
+ let metric_encoder = encoder. encode_descriptor (
72
+ "process_virtual_memory_max_bytes" ,
73
+ "Maximum amount of virtual memory available in bytes." ,
74
+ None ,
75
+ gauge. metric_type ( ) ,
76
+ ) ?;
77
+ gauge. encode ( metric_encoder) ?;
54
78
}
55
79
80
+ let vm_bytes = ConstGauge :: new ( stat. vsize as i64 ) ;
81
+ let vme = encoder. encode_descriptor (
82
+ "process_virtual_memory_bytes" ,
83
+ "Virtual memory size in bytes" ,
84
+ Some ( & Unit :: Bytes ) ,
85
+ vm_bytes. metric_type ( ) ,
86
+ ) ?;
87
+ vm_bytes. encode ( vme) ?;
88
+
89
+ // TODO: add rss_bytes (fix self.page_size)
90
+ //
91
+ // let rss_bytes = ConstGauge::new((stat.rss * self.page_size) as i64);
92
+ // let rsse = encoder.encode_descriptor(
93
+ // "process_resident_memory_bytes",
94
+ // "Resident memory size in bytes.",
95
+ // Some(&Unit::Bytes),
96
+ // rss_bytes.metric_type(),
97
+ // )?;
98
+ // rss_bytes.encode(rsse)?;
99
+
100
+ let start_time_from_epoch = SystemTime :: now ( )
101
+ . duration_since ( UNIX_EPOCH )
102
+ // TODO: remove expect
103
+ . expect ( "process start time" ) ;
104
+ let start_time = ConstGauge :: new ( start_time_from_epoch. as_secs_f64 ( ) ) ;
105
+ let start_time_metric = encoder. encode_descriptor (
106
+ "process_start_time_seconds" ,
107
+ "Start time of the process since unix epoch in seconds." ,
108
+ Some ( & Unit :: Seconds ) ,
109
+ start_time. metric_type ( ) ,
110
+ ) ?;
111
+ start_time. encode ( start_time_metric) ?;
112
+
56
113
Ok ( ( ) )
57
114
}
58
115
}
0 commit comments