Projet

Général

Profil

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

root / plugins / puppet / puppetdb @ a7139bca

Historique | Voir | Annoter | Télécharger (6,12 ko)

1 a7139bca Lars Kruse
#!/usr/bin/env python3
2 d4188712 Gabriel Filion
"""
3
=head1 NAME
4
5
puppetdb - Create a graph out of PuppetDB's JVM memory usage.
6
7
=head1 CONFIGURATION
8
9
This plugin does not need to run with a privileged user.
10
11
By default, the plugin will send requests to a PuppetDB instance on localhost.
12
13
Plugin configuration parameters:
14
15
  * pdburl:
16
    Set the URL to your PuppetDB instance. This url should point to the mbeans
17
    endpoint. By default this has a value of
18
    http://localhost:8080/metrics/v1/mbeans
19
20
  * timeout:
21
    Time in seconds (int) to wait for a result when querying the REST API. By
22
    default, wait for 2 seconds
23
24 70f565c5 Gabriel Filion
  * ca:
25
    Path to the Certificate Authority used for verifying a cert received from
26
    the PuppetDB server during an https connection. This can be useful if the
27
    cert used by PuppetDB was signed by the puppetmaster's CA. This option is
28
    not necessary if a plaintext connection is used (e.g. if pdburl starts
29
    with 'http://').
30
31
  * cert:
32
    Path to the TLS certificate file used for establishing client
33
    communication for an https connection. This option should be paired with
34
    the `key` option. This option is not necessary if a plaintext connection
35
    is used (e.g. if pdburl starts with 'http://').
36
37
  * key:
38
    Path to the TLS private key used for establishing client communication for
39
    an https connection. This option should be paired with the `cert` option.
40
    This option is not necessary if a plaintext connection is used (e.g. if
41
    pdburl starts with 'http://').
42
43 d4188712 Gabriel Filion
Example:
44
45
  [puppetdb]
46
    env.pdburl https://puppetdb.example.com:8080/metrics/v1/mbeans
47
    env.timeout 5
48 70f565c5 Gabriel Filion
    env.ca /etc/puppetboard/ca.pem
49
    env.cert /etc/puppetboard/client_cert.pem
50
    env.key /etc/puppetboard/client_key.pem
51 d4188712 Gabriel Filion
52
=head1 DEPENDENCIES
53
54
python3-requests
55
56
=head1 COMPATIBILITY
57
58
  * PuppetDB 6.x: https://puppet.com/docs/puppetdb/6.0/api/metrics/v1/mbeans.html#jvm-metrics
59
60
=head1 AUTHOR
61
62
Copyright (c) 2020, Gabriel Filion, gabster@lelutin.ca
63
64
=head1 LICENSE
65
66
This code is licensed under GPLv3+
67
68 c6f88968 Lars Kruse
=cut
69 d4188712 Gabriel Filion
"""
70
71
import os
72
import sys
73
import requests
74
75
76
class WrongStatusCode(Exception):
77
    pass
78
79
80 70f565c5 Gabriel Filion
def rest_request(url, timeout, ca, key_pair):
81 d4188712 Gabriel Filion
    """Make a GET request to URL. We expect a 200 response.
82
    This function will let exceptions from requests raise through to indicate
83
    request failure.
84
    If response code is not 200, it will raise a WrongStatusCode exception.
85
    """
86
    headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
87 70f565c5 Gabriel Filion
88
    ssl_options = {}
89
    if ca:
90
        ssl_options['verify'] = ca
91
    if key_pair:
92
        ssl_options['cert'] = key_pair
93
94
    resp = requests.get(url, headers=headers, timeout=timeout, **ssl_options)
95 d4188712 Gabriel Filion
    if resp.status_code != 200:
96
        err = f"GET Request to '{url}' returned code {resp.status_code}; expected 200."  # noqa: E501
97
        raise WrongStatusCode(err)
98
    return resp
99
100
101
def config():
102
    """Print all graph configuration for munin."""
103
    print("graph_title PuppetDB JVM Memory usage")
104
    print("graph_args --base 1024")
105
    print("graph_vlabel Bytes")
106
    print("graph_info This graph shows how much memory from the JVM "
107
          + "Heapspace is being used by PuppetDB")
108 6a8fbf3b Gabriel Filion
    print("graph_category other")
109 d4188712 Gabriel Filion
    print("graph_order jvm_mem_max jvm_mem_committed jvm_mem_used")
110
111
    # Fields
112
    print("jvm_mem_max.min 0")
113
    print("jvm_mem_max.label JVM Max mem")
114
    print("jvm_mem_max.info Maximum memory allocated to the JVM")
115
116
    print("jvm_mem_committed.label JVM Committed mem")
117
    print("jvm_mem_committed.min 0")
118
    print("jvm_mem_committed.info Memory currently committed by the JVM")
119
120
    print("jvm_mem_used.label JVM Used mem")
121
    print("jvm_mem_used.min 0")
122
    print("jvm_mem_used.info Memory currently used by objects in the JVM")
123
    print("jvm_mem_used.draw AREA")
124
125
126 70f565c5 Gabriel Filion
def fetch_field_values(mbeans_url, timeout, ca, key_pair):
127 d4188712 Gabriel Filion
    """Get values from PuppetDB and print them out."""
128
    memory_url = f"{mbeans_url}/java.lang:type=Memory"
129
130
    try:
131 70f565c5 Gabriel Filion
        mem_req = rest_request(memory_url, timeout, ca, key_pair)
132 d4188712 Gabriel Filion
    except Exception as e:
133
        print(f"HTTP Request did not complete successfully: {e}",
134
              file=sys.stderr)
135
        exit(1)
136
137
    try:
138
        memory = mem_req.json()
139
    except Exception as e:
140
        print(f"Could not parse JSON, can't find the info we need: {e}",
141
              file=sys.stderr)
142
        exit(1)
143
144
    try:
145
        heap = memory['HeapMemoryUsage']
146
        mem_max = heap['max']
147
        mem_committed = heap['committed']
148
        mem_used = heap['used']
149
    except Exception as e:
150
        print(f"Memory values were not found in the reply JSON: {e}",
151
              file=sys.stderr)
152
        exit(1)
153
154
    print(f"jvm_mem_max.value {mem_max}")
155
    print(f"jvm_mem_committed.value {mem_committed}")
156
    print(f"jvm_mem_used.value {mem_used}")
157
158
159
if __name__ == '__main__':
160
    mbeans_url = os.environ.get('pdburl', 'http://localhost:8080/metrics/v1/mbeans')
161
    try:
162
        timeout = int(os.environ.get('timeout', '2'))
163
    except ValueError as e:
164
        print(f"Invalid value for timeout: {e}", file=sys.stderr)
165
        exit(1)
166
167 70f565c5 Gabriel Filion
    ca = os.environ.get('ca', None)
168
    if ca:
169
        if not os.path.exists(ca):
170
            print(f"CA file '{ca}' not found.", file=sys.stderr)
171
            exit(1)
172
173
    cert = os.environ.get('cert', None)
174
    key = os.environ.get('key', None)
175
    if cert or key:
176
        if cert and key:
177
            if not os.path.exists(cert):
178
                print(f"Certificate file '{cert}' not found.", file=sys.stderr)
179
                exit(1)
180
            if not os.path.exists(key):
181
                print(f"Key file '{key}' not found.", file=sys.stderr)
182
                exit(1)
183
        else:
184
            print("Only one of 'cert' and 'key' supplied. "
185
                  "Both are needed for client authentication.",
186
                  file=sys.stderr)
187
            exit(1)
188
189 d4188712 Gabriel Filion
    if len(sys.argv) > 1 and sys.argv[1] == 'autoconf':
190
        try:
191 70f565c5 Gabriel Filion
            dummy = rest_request(mbeans_url, timeout, ca, (cert, key))
192 d4188712 Gabriel Filion
        except Exception as e:
193
            print(f"no ({e})")
194
            exit(0)
195
196
        print("yes")
197
        exit(0)
198
199
    if len(sys.argv) > 1 and sys.argv[1] == 'config':
200
        config()
201
        exit(0)
202
203 70f565c5 Gabriel Filion
    fetch_field_values(mbeans_url, timeout, ca, (cert, key))