@@ -38,6 +38,8 @@ MemMonitor::MemMonitor(const rclcpp::NodeOptions & options)
38
38
available_size_(declare_parameter<int >(" available_size" , 1024 ) * 1024 * 1024),
39
39
usage_timeout_(declare_parameter<int >(" usage_timeout" , 5 )),
40
40
ecc_timeout_(declare_parameter<int >(" ecc_timeout" , 5 )),
41
+ swap_usage_warn_(declare_parameter<float >(" swap_usage_warn" , 0.25 )),
42
+ swap_usage_error_(declare_parameter<float >(" swap_usage_error" , 0.75 )),
41
43
usage_elapsed_ms_(0.0 ),
42
44
ecc_elapsed_ms_(0.0 ),
43
45
use_edac_util_(false )
@@ -47,6 +49,7 @@ MemMonitor::MemMonitor(const rclcpp::NodeOptions & options)
47
49
gethostname (hostname_, sizeof (hostname_));
48
50
updater_.setHardwareID (hostname_);
49
51
updater_.add (" Memory Usage" , this , &MemMonitor::checkUsage);
52
+ updater_.add (" Swap Usage" , this , &MemMonitor::checkSwapUsage);
50
53
51
54
// Start timer to execute checkUsage and checkEcc
52
55
timer_callback_group_ = this ->create_callback_group (rclcpp::CallbackGroupType::MutuallyExclusive);
@@ -116,6 +119,54 @@ void MemMonitor::checkUsage(diagnostic_updater::DiagnosticStatusWrapper & stat)
116
119
stat.addf (" execution time" , " %f ms" , elapsed_ms);
117
120
}
118
121
122
+ void MemMonitor::checkSwapUsage (diagnostic_updater::DiagnosticStatusWrapper & stat)
123
+ {
124
+ std::string error_str;
125
+ std::map<std::string, size_t > map;
126
+ double elapsed_ms;
127
+
128
+ // thread-safe copy
129
+ {
130
+ std::lock_guard<std::mutex> lock (usage_mutex_);
131
+ error_str = usage_error_str_;
132
+ map = usage_map_;
133
+ elapsed_ms = usage_elapsed_ms_;
134
+ }
135
+
136
+ if (!error_str.empty ()) {
137
+ stat.summary (DiagStatus::ERROR, " readUsage error" );
138
+ stat.add (" readUsage" , error_str);
139
+ return ;
140
+ }
141
+
142
+ // Check if Swap Usage
143
+ const auto swap_usage = static_cast <double >(map[" Swap: usage" ]) / 1e+2 ;
144
+ int level = DiagStatus::OK;
145
+
146
+ if (swap_usage >= swap_usage_error_) {
147
+ level = std::max (level, static_cast <int >(DiagStatus::ERROR));
148
+ } else if (swap_usage >= swap_usage_warn_) {
149
+ level = std::max (level, static_cast <int >(DiagStatus::WARN));
150
+ }
151
+
152
+ stat.addf (" Swap: usage" , " %.2f%%" , static_cast <double >(map[" Swap: usage" ]));
153
+ stat.add (" Swap: total" , toHumanReadable (std::to_string (map[" Swap: total" ])));
154
+ stat.add (" Swap: used" , toHumanReadable (std::to_string (map[" Swap: used" ])));
155
+ stat.add (" Swap: free" , toHumanReadable (std::to_string (map[" Swap: free" ])));
156
+
157
+ if (level == DiagStatus::ERROR) {
158
+ stat.summary (level, usage_dict_.at (level));
159
+ } else if (elapsed_ms == 0.0 ) {
160
+ stat.summary (DiagStatus::WARN, " do not execute readUsage yet" );
161
+ } else if (elapsed_ms > usage_timeout_ * 1000 ) {
162
+ stat.summary (DiagStatus::WARN, " readUsage timeout expired" );
163
+ } else {
164
+ stat.summary (level, usage_dict_.at (level));
165
+ }
166
+
167
+ stat.addf (" execution time" , " %f ms" , elapsed_ms);
168
+ }
169
+
119
170
void MemMonitor::checkEcc (diagnostic_updater::DiagnosticStatusWrapper & stat)
120
171
{
121
172
std::string error_str;
@@ -252,6 +303,7 @@ std::string MemMonitor::readUsage(std::map<std::string, size_t> & map)
252
303
map[" Swap: total" ] = swap_total;
253
304
map[" Swap: used" ] = swap_used;
254
305
map[" Swap: free" ] = swap_free;
306
+ map[" Swap: usage" ] = (swap_total > 0 ) ? static_cast <double >(swap_used) / swap_total * 1e+2 : 0.0 ;
255
307
256
308
size_t total_total = mem_total + swap_total;
257
309
size_t total_used = mem_used + swap_used;
0 commit comments