Merge lp:~blake-rouse/maas/maas-prometheus into lp:~maas-committers/maas/trunk

Proposed by Blake Rouse
Status: Rejected
Rejected by: MAAS Lander
Proposed branch: lp:~blake-rouse/maas/maas-prometheus
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 273 lines (+83/-14)
14 files modified
buildout.cfg (+1/-0)
requirements.txt (+1/-0)
src/maasserver/config.py (+16/-1)
src/maasserver/djangosettings/development.py (+4/-1)
src/maasserver/djangosettings/settings.py (+19/-0)
src/maasserver/models/event.py (+2/-1)
src/maasserver/models/node.py (+2/-1)
src/maasserver/models/regioncontrollerprocess.py (+6/-3)
src/maasserver/models/regioncontrollerprocessendpoint.py (+6/-3)
src/maasserver/models/regionrackrpcconnection.py (+6/-3)
src/maasserver/models/staticipaddress.py (+3/-1)
src/maasserver/utils/prometheus.py (+14/-0)
utilities/check-imports (+1/-0)
versions.cfg (+2/-0)
To merge this branch: bzr merge lp:~blake-rouse/maas/maas-prometheus
Reviewer Review Type Date Requested Status
Lee Trager (community) Needs Information
Mike Pontillo (community) Needs Fixing
Review via email: mp+322484@code.launchpad.net

Commit message

Add the ability to enable basic prometheus metric collections.

Description of the change

This allow very basic prometheus metric collection. To enable this on an installed system you have to install django-prometheus, its not something we will require in packaging. It is included in the snap so enabling there is much easier.

Each working runs on the ports:

5260 - worker 1
5261 - worker 2
5262 - worker 3
5263 - worker 4

Only very basic metrics are collected at the moment, but we can expand on this easily to get more information on the load of MAAS and its internals.

To post a comment you must log in.
Revision history for this message
Mike Pontillo (mpontillo) wrote :

This is really cool. I tested the branch (with Blake's help) by doing the following:

 - sudo snap install prometheus
 - verified prometheus was running by hitting http://localhost:9090/
 - Installed the Prometheus Django plugin on the MAAS server
    sudo apt install python3-pip
    sudo pip3 install django-prometheus
 - Changed the configuration of the snap to be like the following[1]:
    http://paste.ubuntu.com/24375943/
    http://paste.ubuntu.com/24375947/
 - Changed /etc/maas/regiond.conf to add the following[2]:
    prometheus_export: true
    prometheus_export_address: 192.168.0.2

The good news is, I begun seeing metrics on the Prometheus dashboard. The bad news is, we found a couple of issues:

 - Due to what looks like a bug in the Prometheus Django plugin[3], a crash can occur which causes the dashboard not to appear.

 - Observed an "OSError: [Errno 98] Address already in use" error while running database migrations. Probably need a way to prevent Prometheus from running except on the "real" region (i.e., not in a script, etc.).

---

[1]: Except that I was running the MAAS region on a different machine than prometheus, so used the following for target config, where 192.168.0.2 is the MAAS IP address:
  - targets:
    - 192.168.0.2:5260
    - 192.168.0.2:5261
    - 192.168.0.2:5262
    - 192.168.0.2:5263

[2]: Blake and I agreed that these options should be renamed as follows:

    prometheus: true
    prometheus_listen_address: 172.16.42.2

[3]:
http://paste.ubuntu.com/24376097/

review: Needs Fixing
Revision history for this message
Lee Trager (ltrager) wrote :

You mentioned that django-prometheus will ship with the Snap. Does that mean prometheus will also be on in the Snap? I think even if django-prometheus is installed there should be some additional user action to get metrics.

Also, it looks like there is some additional configuration and setup to get metrics from this. It'd be helpful to have those steps documented in trunk.

review: Needs Information
Revision history for this message
Mike Pontillo (mpontillo) wrote :

@ltrager, prometheus must be installed separately.

Revision history for this message
MAAS Lander (maas-lander) wrote :

Transitioned to Git.

lp:maas has now moved from Bzr to Git.
Please propose your branches with Launchpad using Git.

git clone https://git.launchpad.net/maas

Unmerged revisions

5968. By Blake Rouse

Add the ability to enable prometheus metric collections.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'buildout.cfg'
2--- buildout.cfg 2017-03-31 09:35:11 +0000
3+++ buildout.cfg 2017-04-12 21:37:46 +0000
4@@ -106,6 +106,7 @@
5 recipe = zc.recipe.egg
6 test-eggs =
7 ${common:test-eggs}
8+ django-prometheus
9 selenium
10 eggs =
11 ${region:test-eggs}
12
13=== modified file 'requirements.txt'
14--- requirements.txt 2017-03-30 20:42:36 +0000
15+++ requirements.txt 2017-04-12 21:37:46 +0000
16@@ -2,6 +2,7 @@
17 convoy==0.4.4
18 crochet==1.5.0
19 django==1.8
20+django-prometheus==1.0.8
21 formencode==1.3.1
22 httplib2==0.9.2
23 jsonschema==2.5.1
24
25=== modified file 'src/maasserver/config.py'
26--- src/maasserver/config.py 2017-03-30 19:40:18 +0000
27+++ src/maasserver/config.py 2017-04-12 21:37:46 +0000
28@@ -7,7 +7,10 @@
29 "RegionConfiguration",
30 ]
31
32-from formencode.validators import Int
33+from formencode.validators import (
34+ Int,
35+ StringBool,
36+)
37 from provisioningserver.config import (
38 Configuration,
39 ConfigurationFile,
40@@ -51,3 +54,15 @@
41 database_pass = ConfigurationOption(
42 "database_pass", "The password for the PostgreSQL user.",
43 UnicodeString(if_missing="", accept_python=False))
44+
45+ # Prometheus
46+ prometheus_export = ConfigurationOption(
47+ "prometheus_export",
48+ "Enable exporting of prometheus metrics. A port will be selected "
49+ "for each worker from 5260+.",
50+ StringBool(if_missing=False, accept_python=False))
51+ prometheus_export_address = ConfigurationOption(
52+ "prometheus_export_address",
53+ "Address that prometheus should export metrics on. "
54+ "(Default: localhost)",
55+ UnicodeString(if_missing="localhost", accept_python=False))
56
57=== modified file 'src/maasserver/djangosettings/development.py'
58--- src/maasserver/djangosettings/development.py 2017-03-30 18:47:16 +0000
59+++ src/maasserver/djangosettings/development.py 2017-04-12 21:37:46 +0000
60@@ -49,7 +49,10 @@
61 DATABASES = {
62 'default': {
63 # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' etc.
64- 'ENGINE': 'django.db.backends.postgresql_psycopg2',
65+ 'ENGINE': (
66+ 'django_prometheus.db.backends.postgresql'
67+ if PROMETHEUS_EXPORT else # noqa
68+ 'django.db.backends.postgresql_psycopg2'),
69 'NAME': 'maas',
70 # For PostgreSQL, a "hostname" starting with a slash indicates a
71 # Unix socket directory.
72
73=== modified file 'src/maasserver/djangosettings/settings.py'
74--- src/maasserver/djangosettings/settings.py 2017-03-30 18:47:16 +0000
75+++ src/maasserver/djangosettings/settings.py 2017-04-12 21:37:46 +0000
76@@ -360,3 +360,22 @@
77
78 # Fix crooked settings.
79 fix_up_databases(DATABASES)
80+
81+# Enable prometheus metrics and exporting if enabled.
82+with RegionConfiguration.open() as config:
83+ PROMETHEUS_EXPORT = config.prometheus_export
84+ PROMETHEUS_METRICS_EXPORT_ADDRESS = config.prometheus_export_address
85+if PROMETHEUS_EXPORT:
86+ INSTALLED_APPS += (
87+ 'django_prometheus',
88+ )
89+ MIDDLEWARE_CLASSES = (
90+ 'django_prometheus.middleware.PrometheusBeforeMiddleware',
91+ ) + MIDDLEWARE_CLASSES + (
92+ 'django_prometheus.middleware.PrometheusAfterMiddleware',
93+ )
94+ if 'default' in DATABASES:
95+ DATABASES['default']['ENGINE'] = (
96+ 'django_prometheus.db.backends.postgresql')
97+ PROMETHEUS_METRICS_EXPORT_PORT = (
98+ 5259 + int(os.environ.get('MAAS_REGIOND_WORKER_ID', 1)))
99
100=== modified file 'src/maasserver/models/event.py'
101--- src/maasserver/models/event.py 2017-03-02 00:22:23 +0000
102+++ src/maasserver/models/event.py 2017-04-12 21:37:46 +0000
103@@ -19,6 +19,7 @@
104 from maasserver.models.eventtype import EventType
105 from maasserver.models.node import Node
106 from maasserver.models.timestampedmodel import TimestampedModel
107+from maasserver.utils.prometheus import ExportModelOperationsMixin
108 from provisioningserver.events import EVENT_DETAILS
109 from provisioningserver.logger import get_maas_logger
110 from provisioningserver.utils.env import get_maas_id
111@@ -65,7 +66,7 @@
112 event_description=event_description)
113
114
115-class Event(CleanSave, TimestampedModel):
116+class Event(ExportModelOperationsMixin("event"), CleanSave, TimestampedModel):
117 """An `Event` represents a MAAS event.
118
119 :ivar type: The event's type.
120
121=== modified file 'src/maasserver/models/node.py'
122--- src/maasserver/models/node.py 2017-04-04 21:07:13 +0000
123+++ src/maasserver/models/node.py 2017-04-12 21:37:46 +0000
124@@ -152,6 +152,7 @@
125 post_commit_do,
126 transactional,
127 )
128+from maasserver.utils.prometheus import ExportModelOperationsMixin
129 from maasserver.utils.threads import (
130 callOutToDatabase,
131 deferToDatabase,
132@@ -789,7 +790,7 @@
133 ]
134
135
136-class Node(CleanSave, TimestampedModel):
137+class Node(ExportModelOperationsMixin("node"), CleanSave, TimestampedModel):
138 """A `Node` represents a physical machine used by the MAAS Server.
139
140 :ivar system_id: The unique identifier for this `Node`.
141
142=== modified file 'src/maasserver/models/regioncontrollerprocess.py'
143--- src/maasserver/models/regioncontrollerprocess.py 2016-03-28 13:54:47 +0000
144+++ src/maasserver/models/regioncontrollerprocess.py 2017-04-12 21:37:46 +0000
145@@ -15,9 +15,12 @@
146 from maasserver.models.cleansave import CleanSave
147 from maasserver.models.node import Node
148 from maasserver.models.timestampedmodel import TimestampedModel
149-
150-
151-class RegionControllerProcess(CleanSave, TimestampedModel):
152+from maasserver.utils.prometheus import ExportModelOperationsMixin
153+
154+
155+class RegionControllerProcess(
156+ ExportModelOperationsMixin("region_process"),
157+ CleanSave, TimestampedModel):
158 """A `RegionControllerProcess` that is running on a `RegionController` or
159 `RegionRackController`.
160
161
162=== modified file 'src/maasserver/models/regioncontrollerprocessendpoint.py'
163--- src/maasserver/models/regioncontrollerprocessendpoint.py 2016-03-28 13:54:47 +0000
164+++ src/maasserver/models/regioncontrollerprocessendpoint.py 2017-04-12 21:37:46 +0000
165@@ -20,9 +20,12 @@
166 from maasserver.models.cleansave import CleanSave
167 from maasserver.models.regioncontrollerprocess import RegionControllerProcess
168 from maasserver.models.timestampedmodel import TimestampedModel
169-
170-
171-class RegionControllerProcessEndpoint(CleanSave, TimestampedModel):
172+from maasserver.utils.prometheus import ExportModelOperationsMixin
173+
174+
175+class RegionControllerProcessEndpoint(
176+ ExportModelOperationsMixin("region_process_endpoint"),
177+ CleanSave, TimestampedModel):
178 """`RegionControllerProcessEndpoint` is a RPC endpoint on the
179 `RegionControllerProcess` one endpoint is created per IP address on the
180 `RegionControllerProcess`.
181
182=== modified file 'src/maasserver/models/regionrackrpcconnection.py'
183--- src/maasserver/models/regionrackrpcconnection.py 2016-03-28 13:54:47 +0000
184+++ src/maasserver/models/regionrackrpcconnection.py 2017-04-12 21:37:46 +0000
185@@ -15,9 +15,12 @@
186 RegionControllerProcessEndpoint,
187 )
188 from maasserver.models.timestampedmodel import TimestampedModel
189-
190-
191-class RegionRackRPCConnection(CleanSave, TimestampedModel):
192+from maasserver.utils.prometheus import ExportModelOperationsMixin
193+
194+
195+class RegionRackRPCConnection(
196+ ExportModelOperationsMixin("rack_rpc_connection"),
197+ CleanSave, TimestampedModel):
198 """`RegionRackRPCConnection` records a connection between a region
199 controller and rack controller within the MAAS communication strucutre.
200
201
202=== modified file 'src/maasserver/models/staticipaddress.py'
203--- src/maasserver/models/staticipaddress.py 2017-04-06 18:19:08 +0000
204+++ src/maasserver/models/staticipaddress.py 2017-04-12 21:37:46 +0000
205@@ -52,6 +52,7 @@
206 from maasserver.models.timestampedmodel import TimestampedModel
207 from maasserver.utils import orm
208 from maasserver.utils.dns import get_ip_based_hostname
209+from maasserver.utils.prometheus import ExportModelOperationsMixin
210 from netaddr import IPAddress
211 from provisioningserver.utils.enum import map_enum_reverse
212
213@@ -663,7 +664,8 @@
214 ], params=[family])
215
216
217-class StaticIPAddress(CleanSave, TimestampedModel):
218+class StaticIPAddress(
219+ ExportModelOperationsMixin("ip_address"), CleanSave, TimestampedModel):
220
221 class Meta(DefaultMeta):
222 verbose_name = "Static IP Address"
223
224=== added file 'src/maasserver/utils/prometheus.py'
225--- src/maasserver/utils/prometheus.py 1970-01-01 00:00:00 +0000
226+++ src/maasserver/utils/prometheus.py 2017-04-12 21:37:46 +0000
227@@ -0,0 +1,14 @@
228+# Copyright 2017 Canonical Ltd. This software is licensed under the
229+# GNU Affero General Public License version 3 (see the file LICENSE).
230+
231+"""Prometheus utilities."""
232+
233+__all__ = [
234+ "ExportModelOperationsMixin"
235+]
236+
237+
238+try:
239+ from django_prometheus.models import ExportModelOperationsMixin
240+except ImportError:
241+ ExportModelOperationsMixin = object
242
243=== modified file 'utilities/check-imports'
244--- utilities/check-imports 2017-02-17 14:23:04 +0000
245+++ utilities/check-imports 2017-04-12 21:37:46 +0000
246@@ -244,6 +244,7 @@
247 Allow("curtin|curtin.**"),
248 Allow("distro_info|distro_info.*"),
249 Allow("django|django.**"),
250+ Allow("django_prometheus|django_prometheus.**"),
251 Allow("docutils.core"),
252 Allow("formencode|formencode.**"),
253 Allow("jsonschema|jsonschema.**"),
254
255=== modified file 'versions.cfg'
256--- versions.cfg 2017-02-17 14:23:04 +0000
257+++ versions.cfg 2017-04-12 21:37:46 +0000
258@@ -14,6 +14,7 @@
259 coverage = 4.3.1
260 decorator = 4.0.10
261 django-nose = 1.4.2
262+django-prometheus = 1.0.8
263 extras = 1.0.0
264 fixtures = 3.0.0
265 hypothesis = 3.6.1
266@@ -27,6 +28,7 @@
267 pbr = 1.10.0
268 pickleshare = 0.7.4
269 postgresfixture = 0.4.0
270+prometheus-client = 0.0.19
271 prompt-toolkit = 1.0.9
272 python-mimeparse = 1.6.0
273 python-subunit = 1.2.0