Browse Source

Add memcache plugin

This patch adds a memcache plugin along with tests and documentation.

Implements: blueprint monitorstack
Change-Id: Iefb0c0912078713c26387e02e135d70d7a96a7dc
Major Hayden 2 years ago
parent
commit
a30fe1d79d
No account linked to committer's email address

+ 105
- 0
doc/source/plugins-base/plugin-memcache.rst View File

@@ -0,0 +1,105 @@
1
+``memcache`` - get statistics from a memcache server
2
+====================================================
3
+
4
+The memcache plugin connects to a memcache server to retrieve statistics.
5
+
6
+Usage
7
+-----
8
+
9
+The plugin has two optional arguments:
10
+
11
+* ``host`` - the hostname or IP address of the memcache server
12
+* ``port`` - the port number of the memcache server
13
+
14
+.. code-block:: console
15
+
16
+    Usage: monitorstack memcache [OPTIONS]
17
+
18
+      Get memcached stats.
19
+
20
+    Options:
21
+      --host TEXT     memcached host to query
22
+      --port INTEGER  memcached server port
23
+      --help          Show this message and exit.
24
+
25
+
26
+Example
27
+-------
28
+
29
+Run the plugin:
30
+
31
+.. code-block:: console
32
+
33
+    $ monitorstack memcache
34
+
35
+Example output in JSON format:
36
+
37
+.. code-block:: json
38
+
39
+    {
40
+      "variables": {
41
+        "auth_cmds": 0,
42
+        "crawler_items_checked": 0,
43
+        "reclaimed": 0,
44
+        "get_expired": 0,
45
+        "curr_items": 0,
46
+        "pid": 24627,
47
+        "malloc_fails": 0,
48
+        "time_in_listen_disabled_us": 0,
49
+        "expired_unfetched": 0,
50
+        "hash_is_expanding": false,
51
+        "cas_hits": 0,
52
+        "uptime": 8,
53
+        "touch_hits": 0,
54
+        "delete_misses": 0,
55
+        "listen_disabled_num": 0,
56
+        "cas_misses": 0,
57
+        "decr_hits": 0,
58
+        "cmd_touch": 0,
59
+        "incr_hits": 0,
60
+        "version": "1.4.33",
61
+        "limit_maxbytes": 67108864,
62
+        "total_items": 0,
63
+        "bytes_written": 0,
64
+        "incr_misses": 0,
65
+        "accepting_conns": 1,
66
+        "rusage_system": 0.014981,
67
+        "log_watcher_sent": 0,
68
+        "get_flushed": 0,
69
+        "cmd_get": 0,
70
+        "curr_connections": 4,
71
+        "log_worker_written": 0,
72
+        "log_watcher_skipped": 0,
73
+        "touch_misses": 0,
74
+        "threads": 4,
75
+        "total_connections": 5,
76
+        "cmd_set": 0,
77
+        "libevent": "2.0.22-stable",
78
+        "conn_yields": 0,
79
+        "get_misses": 0,
80
+        "reserved_fds": 20,
81
+        "bytes_read": 8,
82
+        "hash_bytes": 524288,
83
+        "evicted_unfetched": 0,
84
+        "cas_badval": 0,
85
+        "cmd_flush": 0,
86
+        "lrutail_reflocked": 0,
87
+        "evictions": 0,
88
+        "bytes": 0,
89
+        "crawler_reclaimed": 0,
90
+        "connection_structures": 5,
91
+        "hash_power_level": 16,
92
+        "log_worker_dropped": 0,
93
+        "auth_errors": 0,
94
+        "rusage_user": 0.005598,
95
+        "time": 1493240773,
96
+        "delete_hits": 0,
97
+        "pointer_size": 64,
98
+        "decr_misses": 0,
99
+        "get_hits": 0
100
+      },
101
+      "message": "memcached is ok",
102
+      "meta": {},
103
+      "exit_code": 0,
104
+      "measurement_name": "memcache"
105
+    }

+ 57
- 0
monitorstack/plugins/memcache.py View File

@@ -0,0 +1,57 @@
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 memcached stats."""
15
+import click
16
+
17
+from monitorstack import utils
18
+from monitorstack.cli import pass_context
19
+
20
+from pymemcache.client.base import Client
21
+
22
+DOC = """Get memcached stats."""
23
+COMMAND_NAME = 'memcache'
24
+
25
+
26
+@click.command(COMMAND_NAME, short_help=DOC)
27
+@click.option('--host', help='memcached host to query', default='127.0.0.1')
28
+@click.option('--port', help='memcached server port', default=11211)
29
+@pass_context
30
+def cli(ctx, host, port):
31
+    """Get memcached stats."""
32
+    output = {
33
+        'exit_code': 0,
34
+        'message': 'memcached is ok',
35
+        'measurement_name': 'memcache',
36
+        'meta': {},
37
+        'variables': {}
38
+    }
39
+
40
+    # Connect to memcache and retrieve our stats
41
+    try:
42
+        stats = get_memcached_stats(host, port)
43
+        output['variables'] = stats
44
+    except Exception as exp:
45
+        output['exit_code'] = 1
46
+        output['message'] = '{} failed -- {}'.format(
47
+            COMMAND_NAME,
48
+            utils.log_exception(exp=exp)
49
+        )
50
+
51
+    return output
52
+
53
+
54
+def get_memcached_stats(host, port):
55
+    """Connect to memcache server for stats."""
56
+    conn = Client((host, port))
57
+    return conn.stats()

+ 1
- 0
requirements.txt View File

@@ -1,6 +1,7 @@
1 1
 click
2 2
 diskcache
3 3
 openstacksdk>=0.9.14
4
+pymemcache>=1.2.9,!=1.3.0  # Apache 2.0 License
4 5
 psutil>=5.2.0
5 6
 six
6 7
 stevedore

+ 78
- 0
tests/test_plugin_memcache.py View File

@@ -0,0 +1,78 @@
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 memcache plugin."""
15
+from monitorstack.plugins import memcache as monitorstack_memcache
16
+
17
+import pymemcache
18
+
19
+import tests
20
+
21
+
22
+class TestMemcache(object):
23
+    """Tests for the memcache plugin."""
24
+
25
+    def test_success(self, monkeypatch):
26
+        """Ensure the run() method works."""
27
+        def mock_get_memcached_stats(host, port):
28
+            """Mock the get_memcached_stats() method."""
29
+            return {'parameter': 'value'}
30
+
31
+        monkeypatch.setattr(
32
+            monitorstack_memcache,
33
+            'get_memcached_stats',
34
+            mock_get_memcached_stats
35
+        )
36
+        result = tests.runner('memcache')
37
+        assert result['variables']['parameter'] == 'value'
38
+        assert result['measurement_name'] == "memcache"
39
+        assert result['exit_code'] == 0
40
+
41
+    def test_failure(self, monkeypatch):
42
+        """Ensure the run() method works."""
43
+        def mock_get_memcached_stats(host, port):
44
+            """Mock the get_memcached_stats() method."""
45
+            raise Exception('Connection failed')
46
+
47
+        monkeypatch.setattr(
48
+            monitorstack_memcache,
49
+            'get_memcached_stats',
50
+            mock_get_memcached_stats
51
+        )
52
+        result = tests.runner('memcache')
53
+        assert 'Connection failed' in result['message']
54
+        assert result['measurement_name'] == "memcache"
55
+        assert result['exit_code'] == 1
56
+
57
+    def test_get_memcached_stats(self, monkeypatch):
58
+        """Ensure that get_memcached_stats() works."""
59
+        def mock_memcache_client(cls, (conn_tuple)):
60
+            """Mock a memcache client class."""
61
+            return None
62
+
63
+        def mock_memcache_stats(toot):
64
+            """Mock a memcache client class."""
65
+            return {'parameter': 'value'}
66
+
67
+        monkeypatch.setattr(
68
+            pymemcache.client.base.Client,
69
+            '__init__',
70
+            mock_memcache_client
71
+        )
72
+        monkeypatch.setattr(
73
+            pymemcache.client.base.Client,
74
+            'stats',
75
+            mock_memcache_stats
76
+        )
77
+        result = monitorstack_memcache.get_memcached_stats('localhost', 11211)
78
+        assert result['parameter'] == 'value'

Loading…
Cancel
Save