From c1a5ed34203f4f944f2f1b3de591021635a6742f Mon Sep 17 00:00:00 2001 From: Carsten Grohmann Date: Sat, 9 Oct 2021 22:06:16 +0200 Subject: [PATCH] Add support for systems w/o swap Suggested-by: Mikko Rantalainen --- OOMAnalyser.html | 50 ++++++++++++++++++++++++++++++++++-------------- OOMAnalyser.py | 50 ++++++++++++++++++++++++++++++++++++------------ test.py | 28 +++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 26 deletions(-) diff --git a/OOMAnalyser.html b/OOMAnalyser.html index 671bcd0..c7cec77 100644 --- a/OOMAnalyser.html +++ b/OOMAnalyser.html @@ -69,6 +69,13 @@ /* empty - used to show sections for manually triggered OOMs */ } + .js-swap-active--show { + /* empty - used to show if the swap space is activated */ + } + .js-swap-inactive--show { + /* empty - used to show if the swap space is not activated */ + } + .result__table { border-collapse: collapse; padding: 10px; @@ -317,14 +324,25 @@ window.onerror = function (msg, url, lineNo, columnNo, error) { has been terminated. It uses () of the resident memory.

-

- The system has physical memory and - swap space. That's total. - - ( out of ) physical - memory and - ( out of ) swap space are in use. -

+ +
+

+ The system has physical memory and + swap space. That's + total. + ( out of ) + physical memory and + ( out of ) swap space are in use. +

+
+
+

+ The system has physical memory and no swap space. + + ( out of ) + physical memory are in use. +

+

Details of analysis

@@ -445,31 +463,34 @@ window.onerror = function (msg, url, lineNo, columnNo, error) { RAM Summary
- + > Swap Summary
- + Swap Usage - + + No swap space available + + Swap Total Total amount of swap space available. [1] - + Swap Free Amount of swap space that is currently unused. [1] - + Swap Cached Memory that once was swapped out, is swapped back in @@ -480,7 +501,7 @@ window.onerror = function (msg, url, lineNo, columnNo, error) { [1] - + Swap Used Amount of used swap space w/o cached swap
@@ -862,6 +883,7 @@ window.onerror = function (msg, url, lineNo, columnNo, error) {
  • Rework removal of unused information
  • Report uncaught errors to the user
  • Add support for manually triggered OOM (suggested by Mikko Rantalainen)
  • +
  • Add support for systems w/o swap (suggested by Mikko Rantalainen)
  • ...
  • diff --git a/OOMAnalyser.py b/OOMAnalyser.py index c943847..fa3bcff 100644 --- a/OOMAnalyser.py +++ b/OOMAnalyser.py @@ -467,6 +467,13 @@ class OOMResult: @type: str """ + swap_active = False + """ + Swap space active or inactive + + @type: bool + """ + class OOMAnalyser: """Analyse an OOM object and calculate additional values""" @@ -531,7 +538,7 @@ class OOMAnalyser: r'^Free swap = (?P\d+)kB' r'(?:\n)' r'^Total swap = (?P\d+)kB', - True, + False, ), 'Page information': ( r'^(?P\d+) pages RAM' @@ -697,7 +704,7 @@ class OOMAnalyser: self.oom_result.details.update(match.groupdict()) elif is_mandatory: error('Failed to extract information from OOM text. The regular expression "{}" (pattern "{}") ' - 'does not find anything. This will cause subsequent errors.'.format(k, pattern)) + 'does not find anything. This can lead to errors later on.'.format(k, pattern)) # __pragma__ ('nojsiter') if self.oom_result.details['trigger_proc_order'] == "-1": @@ -891,6 +898,14 @@ class OOMAnalyser: def _calc_swap_values(self): """Calculate all swap related values""" + try: + self.oom_result.swap_active = self.oom_result.details['swap_total_kb'] > 0 + except KeyError: + self.oom_result.swap_active = False + + if not self.oom_result.swap_active: + return + self.oom_result.details['swap_cache_kb'] = self.oom_result.details['swap_cache_pages'] * self.oom_result.details['page_size_kb'] del self.oom_result.details['swap_cache_pages'] @@ -909,7 +924,11 @@ class OOMAnalyser: # calculate remaining explanation values self.oom_result.details['system_total_ram_kb'] = self.oom_result.details['ram_pages'] * self.oom_result.details['page_size_kb'] - self.oom_result.details['system_total_ramswap_kb'] = self.oom_result.details['system_total_ram_kb'] + self.oom_result.details['swap_total_kb'] + if self.oom_result.swap_active: + self.oom_result.details['system_total_ramswap_kb'] = self.oom_result.details['system_total_ram_kb'] + \ + self.oom_result.details['swap_total_kb'] + else: + self.oom_result.details['system_total_ramswap_kb'] = self.oom_result.details['system_total_ram_kb'] total_rss_pages = 0 for pid in self.oom_result.details['_ps'].keys(): total_rss_pages += self.oom_result.details['_ps'][pid]['rss_pages'] @@ -1534,15 +1553,22 @@ Killed process 6576 (mysqld) total-vm:33914892kB, anon-rss:20629004kB, file-rss: # generate process table self.update_process_table() - # generate swap usage diagram - svg_swap = self.svg_generate_bar_chart( - self.svg_colors_swap, - ('Swap Used', self.oom_result.details['swap_used_kb']), - ('Swap Free', self.oom_result.details['swap_free_kb']), - ('Swap Cached', self.oom_result.details['swap_cache_kb']), - ) - elem_svg_swap = document.getElementById('svg_swap') - elem_svg_swap.appendChild(svg_swap) + # show/hide swap space + if self.oom_result.swap_active: + # generate swap usage diagram + svg_swap = self.svg_generate_bar_chart( + self.svg_colors_swap, + ('Swap Used', self.oom_result.details['swap_used_kb']), + ('Swap Free', self.oom_result.details['swap_free_kb']), + ('Swap Cached', self.oom_result.details['swap_cache_kb']), + ) + elem_svg_swap = document.getElementById('svg_swap') + elem_svg_swap.appendChild(svg_swap) + show_elements('.js-swap-active--show') + hide_elements('.js-swap-inactive--show') + else: + hide_elements('.js-swap-active--show') + show_elements('.js-swap-inactive--show') # generate RAM usage diagram svg_ram = self.svg_generate_bar_chart( diff --git a/test.py b/test.py index 4d17f88..60b7803 100755 --- a/test.py +++ b/test.py @@ -193,6 +193,8 @@ class TestInBrowser(TestBase): explanation = self.driver.find_element_by_id('explanation') self.assertTrue('OOM killer was automatically triggered' in explanation.text, 'Missing text "OOM killer was automatically triggered"') + self.assertTrue('swap space are in use' in explanation.text, + 'Missing text "swap space are in use"') def test_010_load_page(self): """Test if the page is loading""" @@ -306,6 +308,32 @@ Killed process 6576 (java) total-vm:33914892kB, anon-rss:20629004kB, file-rss:0k self.assertTrue('OOM killer was manually triggered' in explanation.text, 'Missing text "OOM killer was manually triggered"') + def test_080_swap_deactivated(self): + """Test w/o swap or with deactivated swap""" + example = OOMAnalyser.OOMDisplay.example + example = example.replace('Total swap = 8388604kB', 'Total swap = 0kB') + self.analyse_oom(example) + self.assert_on_warn_error() + + explanation = self.driver.find_element_by_id('explanation') + self.assertFalse('swap space are in use' in explanation.text, + 'No swap space but text "swap space are in use"') + + self.click_reset() + + example = OOMAnalyser.OOMDisplay.example + example = re.sub(r'\d+ pages in swap cac.*\n*', '', example, re.MULTILINE) + example = re.sub(r'Swap cache stats.*\n*', '', example) + example = re.sub(r'Free swap.*\n*', '', example) + example = re.sub(r'Total swap.*\n*', '', example) + + self.analyse_oom(example) + self.assert_on_warn_error() + + explanation = self.driver.find_element_by_id('explanation') + self.assertFalse('swap space are in use' in explanation.text, + 'No swap space but text "swap space are in use"') + class TestPython(TestBase):