Browse Source

Add process check (#23)

This patch adds a check for running processes along with tests.
Major Hayden 2 years ago
parent
commit
79d23cd713

+ 1
- 0
monitorstack/cli.py View File

@@ -113,6 +113,7 @@ def process_result(result, output_format, verbose):
113 113
         method_name
114 114
     )
115 115
     output_formatter(result)
116
+    sys.exit(result['exit_code'])
116 117
 
117 118
 
118 119
 if __name__ == '__main__':

+ 79
- 0
monitorstack/plugins/process.py View File

@@ -0,0 +1,79 @@
1
+# Copyright 2017, Major Hayden <major@mhtx.net>
2
+#
3
+# Licensed under the Apache License, Version 2.0 (the "License");
4
+# you may not use this file except in compliance with the License.
5
+# You may obtain a copy of the License at
6
+#
7
+#     http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+# Unless required by applicable law or agreed to in writing, software
10
+# distributed under the License is distributed on an "AS IS" BASIS,
11
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+# See the License for the specific language governing permissions and
13
+# limitations under the License.
14
+"""Get system uptime."""
15
+import os
16
+import platform
17
+
18
+import click
19
+
20
+from monitorstack.cli import pass_context
21
+
22
+import psutil
23
+
24
+DOC = """Check if a process is running."""
25
+COMMAND_NAME = 'process'
26
+
27
+
28
+@click.command(COMMAND_NAME, short_help=DOC)
29
+@click.argument('process_name', nargs=1, type=str, required=True)
30
+@pass_context
31
+def cli(ctx, process_name):
32
+    """Check if a process is running."""
33
+    setattr(cli, '__doc__', DOC)
34
+
35
+    output = {
36
+        'exit_code': 0,
37
+        'message': 'process check is ok',
38
+        'measurement_name': 'process',
39
+        'meta': {
40
+            'platform': platform.platform(),
41
+        },
42
+        'variables': {}
43
+    }
44
+
45
+    if check_process(process_name):
46
+        output['variables'] = {process_name: 1}
47
+    else:
48
+        output['exit_code'] = 1
49
+        output['message'] = '{} failed -- Process {} not found'.format(
50
+            COMMAND_NAME,
51
+            process_name
52
+        )
53
+        output['variables'] = {process_name: 0}
54
+
55
+    return output
56
+
57
+
58
+def check_process(process_name):
59
+    """Check if a process is in the list of cmdlines."""
60
+    matches = [x for x in get_cmdlines() if process_name in x]
61
+    return True if len(matches) > 0 else False
62
+
63
+
64
+def get_cmdlines():
65
+    """Retrieve the cmdline of each process running on the system."""
66
+    processes = []
67
+
68
+    # Get our current PID as well as the parent so we can exclude them.
69
+    current_pid = os.getpid()
70
+    parent_pid = os.getppid()
71
+
72
+    for proc in psutil.process_iter():
73
+        try:
74
+            if proc.pid not in [current_pid, parent_pid]:
75
+                processes.append(' '.join(proc.cmdline()))
76
+        except psutil.NoSuchProcess:
77
+            pass
78
+
79
+    return processes

+ 1
- 0
requirements.txt View File

@@ -1,4 +1,5 @@
1 1
 click
2 2
 openstacksdk>=0.9.14
3
+psutil>=5.2.0
3 4
 six
4 5
 stevedore

tests/test_os_vm.py → tests/test_plugin_os_vm.py View File

@@ -48,7 +48,6 @@ def mock_get_consumer_usage(self):
48 48
             'id': 1,
49 49
             'name': 'flavor_one',
50 50
         }
51
-
52 51
     }]
53 52
 
54 53
 

+ 61
- 0
tests/test_plugin_process.py View File

@@ -0,0 +1,61 @@
1
+# Copyright 2017, Major Hayden <major@mhtx.net>
2
+#
3
+# Licensed under the Apache License, Version 2.0 (the "License");
4
+# you may not use this file except in compliance with the License.
5
+# You may obtain a copy of the License at
6
+#
7
+#     http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+# Unless required by applicable law or agreed to in writing, software
10
+# distributed under the License is distributed on an "AS IS" BASIS,
11
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+# See the License for the specific language governing permissions and
13
+# limitations under the License.
14
+"""Tests for the process plugin."""
15
+
16
+import json
17
+
18
+from click.testing import CliRunner
19
+
20
+from monitorstack.cli import cli
21
+from monitorstack.plugins import process
22
+
23
+
24
+class TestUptime(object):
25
+    """Tests for the uptime monitor class."""
26
+
27
+    def test_run_failure(self):
28
+        """Ensure the run() method works."""
29
+        runner = CliRunner()
30
+        process_name = 'dont-go-chasing-waterfalls'
31
+        result = runner.invoke(cli, [
32
+            '-f', 'json',
33
+            'process', process_name])
34
+        result_json = json.loads(result.output)
35
+        assert result_json['variables'] == {process_name: 0}
36
+        assert result.exit_code == 1
37
+
38
+    def test_run_success(self):
39
+        """Ensure the run() method works."""
40
+        runner = CliRunner()
41
+        process_name = '/'
42
+        result = runner.invoke(cli, [
43
+            '-f', 'json',
44
+            'process', process_name])
45
+        result_json = json.loads(result.output)
46
+        assert result_json['variables'] == {process_name: 1}
47
+        assert result.exit_code == 0
48
+
49
+    def test_check_process_success(self, monkeypatch):
50
+        """Ensure the check_process() method works."""
51
+        def mock_get_cmdlines():
52
+            return ['process1', 'process2']
53
+
54
+        monkeypatch.setattr(process, 'get_cmdlines', mock_get_cmdlines)
55
+        result = process.check_process('process2')
56
+        assert result
57
+
58
+    def test_get_cmdlines(self):
59
+        """Ensure the get_cmdlines() method works."""
60
+        cmdlines = process.get_cmdlines()
61
+        assert isinstance(cmdlines, list)

Loading…
Cancel
Save