Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / monit / monit_parser @ a7139bca

Historique | Voir | Annoter | Télécharger (3,52 ko)

1 a7139bca Lars Kruse
#!/usr/bin/env python3
2 23409cd6 Todd Troxell
3 8d78e459 Lars Kruse
"""
4
=head1 NAME
5 23409cd6 Todd Troxell
6 8d78e459 Lars Kruse
monit_parser -  Monit status parser plugin for munin.
7 23409cd6 Todd Troxell
8 8d78e459 Lars Kruse
9
=head1 APPLICABLE SYSTEMS
10
11 ef6cedf7 Lars Kruse
Any system being able to query monit servers via http.
12 8d78e459 Lars Kruse
13
Monit needs to be configured with the httpd port enabled, e.g.:
14
15
    set httpd port 2812
16
17 4fa3811c Gerald Turner
Optionally monit authentication can be configured, e.g.:
18 ef6cedf7 Lars Kruse
19 4fa3811c Gerald Turner
    set httpd port 2812
20
      allow munin:s3cr3t read-only
21 8d78e459 Lars Kruse
22
23
=head1 CONFIGURATION
24
25 ef6cedf7 Lars Kruse
By default the monit instance at localhost is queried:
26 8d78e459 Lars Kruse
27
  [monit_parser]
28 ef6cedf7 Lars Kruse
  env.port 2812
29
  env.host localhost
30 8d78e459 Lars Kruse
31 4fa3811c Gerald Turner
Optionally monit authentication can be configured, e.g.:
32
33
  [monit_parser]
34
  env.username munin
35
  env.password s3cr3t
36
37 8d78e459 Lars Kruse
38
=head1 AUTHOR
39
40
  Todd Troxell <ttroxell@debian.org>
41
  Lars Kruse <devel@sumpfralle.de>
42
43
44
=head1 MAGIC MARKERS
45
46
  family=auto
47
  capabilities=autoconf
48
49
=cut
50
"""
51 23409cd6 Todd Troxell
52 ef6cedf7 Lars Kruse
import xml.dom.minidom
53
import os
54 9d62e558 Lars Kruse
import sys
55 ef6cedf7 Lars Kruse
import urllib.request
56 4fa3811c Gerald Turner
import base64
57 ef6cedf7 Lars Kruse
58
MONIT_XML_URL = ("http://{host}:{port}/_status?format=xml"
59
                 .format(host=os.getenv("host", "localhost"),
60
                         port=os.getenv("port", "2812")))
61 9d62e558 Lars Kruse
62 23409cd6 Todd Troxell
63
def sanitize(s):
64 7f3ce966 Lars Kruse
    ok_chars = "abcdefghijklmnopqrstuvwxyz0123456789"
65
    return "".join([char for char in s if char in ok_chars])
66 e5fbbaea Lars Kruse
67
68 ef6cedf7 Lars Kruse
def get_monit_status_xml():
69 e5fbbaea Lars Kruse
    try:
70 4fa3811c Gerald Turner
        req = urllib.request.Request(url=MONIT_XML_URL)
71
        if os.getenv("password"):
72
            auth_str = "%s:%s" % (os.getenv("username"), os.getenv("password"))
73
            auth_bytes = bytes(auth_str, "utf-8")
74
            auth_base64_bytes = base64.b64encode(auth_bytes)
75
            auth_base64_str = str(auth_base64_bytes, "ascii")
76
            auth_value = "Basic %s" % auth_base64_str
77
            req.add_header("Authorization", auth_value)
78
        conn = urllib.request.urlopen(req)
79 be192b52 Lars Kruse
    except urllib.error.URLError:
80 ef6cedf7 Lars Kruse
        conn = None
81
    if conn is None:
82
        raise RuntimeError("Failed to open monit status URL: {}".format(MONIT_XML_URL))
83
    else:
84
        return xml.dom.minidom.parse(conn)
85 e5fbbaea Lars Kruse
86
87
def parse_processes():
88 ef6cedf7 Lars Kruse
    dom = get_monit_status_xml()
89 e5fbbaea Lars Kruse
    procs = {}
90 ef6cedf7 Lars Kruse
    for item in dom.getElementsByTagName("service"):
91
        if item.getAttribute("type") == "3":
92
            # daemon with memory usage and CPU
93
            name = item.getElementsByTagName("name")[0].childNodes[0].data
94
            memory_usage = item.getElementsByTagName("memory")[0].getElementsByTagName(
95
                "kilobytetotal")[0].childNodes[0].data
96
            cpu_usage = item.getElementsByTagName("cpu")[0].getElementsByTagName(
97
                "percenttotal")[0].childNodes[0].data
98
            procs[name] = {}
99
            procs[name]["total_memory"] = memory_usage
100
            procs[name]["total_cpu"] = cpu_usage
101 e5fbbaea Lars Kruse
    return procs
102
103
104
action = sys.argv[1] if (len(sys.argv) > 1) else None
105
106
if action == 'autoconf':
107
    try:
108 ef6cedf7 Lars Kruse
        get_monit_status_xml()
109 e5fbbaea Lars Kruse
        print("yes")
110 ef6cedf7 Lars Kruse
    except RuntimeError:
111 e5fbbaea Lars Kruse
        print("no (failed to request monit status)")
112
elif action == 'config':
113
    procs = parse_processes()
114 dcd9434e Lars Kruse
    print('graph_title Per process stats from Monit')
115 ef6cedf7 Lars Kruse
    print('graph_vlabel usage of memory [kB] or cpu [%]')
116 f41b6861 dipohl
    print('graph_category munin')
117 23409cd6 Todd Troxell
    for process in procs:
118
        for stat in procs[process]:
119 ef6cedf7 Lars Kruse
            print("monit_%s_%s.label %s.%s" % (sanitize(process), stat, process, stat))
120 25a1a06a Viktor Szépe
            if stat == 'total_memory':
121 e5fbbaea Lars Kruse
                # the allocated memory may never be zero
122 ef6cedf7 Lars Kruse
                print("monit_%s_%s.warning 1:" % (sanitize(process), stat))
123 e5fbbaea Lars Kruse
else:
124
    for process, stats in parse_processes().items():
125
        for stat_key, stat_value in stats.items():
126 ef6cedf7 Lars Kruse
            print("monit_%s_%s.value %s" % (sanitize(process), stat_key, stat_value))