Merge ~cjwatson/launchpad:statsd-implicit-env into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: dcb4e0d4e56b25935379a55894dc5a37dd00ace3
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:statsd-implicit-env
Merge into: launchpad:master
Diff against target: 264 lines (+39/-63)
9 files modified
lib/lp/buildmaster/manager.py (+3/-6)
lib/lp/buildmaster/model/buildfarmjobbehaviour.py (+2/-3)
lib/lp/services/job/runner.py (+4/-9)
lib/lp/services/statsd/model/statsd_client.py (+10/-7)
lib/lp/services/statsd/numbercruncher.py (+5/-12)
lib/lp/services/statsd/tests/__init__.py (+6/-3)
lib/lp/services/statsd/tests/test_statsd_client.py (+0/-10)
lib/lp/services/webapp/publication.py (+4/-8)
lib/lp/services/webapp/tests/test_publication.py (+5/-5)
Reviewer Review Type Date Requested Status
Tom Wardill (community) Approve
Review via email: mp+393792@code.launchpad.net

Commit message

StatsdClient: Automatically add env label

Description of the change

Having to add the appropriate env label manually at each call site is a bit too cumbersome and error-prone, and indeed we'd forgotten to include it for traversal and publication duration timings. Add it automatically in the StatsdClient wrapper instead.

To post a comment you must log in.
Revision history for this message
Tom Wardill (twom) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/buildmaster/manager.py b/lib/lp/buildmaster/manager.py
2index e9732ea..7bbe4aa 100644
3--- a/lib/lp/buildmaster/manager.py
4+++ b/lib/lp/buildmaster/manager.py
5@@ -532,13 +532,10 @@ class SlaveScanner:
6 if builder.current_build is not None:
7 builder.current_build.gotFailure()
8 self.statsd_client.incr(
9- 'builders.judged_failed,build=True,arch={},env={}'.format(
10- builder.current_build.processor.name,
11- self.statsd_client.lp_environment))
12+ 'builders.judged_failed,build=True,arch={}'.format(
13+ builder.current_build.processor.name))
14 else:
15- self.statsd_client.incr(
16- 'builders.judged_failed,build=False,env={}'.format(
17- self.statsd_client.lp_environment))
18+ self.statsd_client.incr('builders.judged_failed,build=False')
19 recover_failure(self.logger, vitals, builder, retry, failure.value)
20 transaction.commit()
21 except Exception:
22diff --git a/lib/lp/buildmaster/model/buildfarmjobbehaviour.py b/lib/lp/buildmaster/model/buildfarmjobbehaviour.py
23index 88ede6a..13a38d7 100644
24--- a/lib/lp/buildmaster/model/buildfarmjobbehaviour.py
25+++ b/lib/lp/buildmaster/model/buildfarmjobbehaviour.py
26@@ -158,10 +158,9 @@ class BuildFarmJobBehaviourBase:
27 job_type_name = job_type.name if job_type else 'UNKNOWN'
28 statsd_client = getUtility(IStatsdClient)
29 statsd_client.incr(
30- 'build.count,job_type={},builder_name={},env={}'.format(
31+ 'build.count,job_type={},builder_name={}'.format(
32 job_type_name,
33- self._builder.name,
34- statsd_client.lp_environment))
35+ self._builder.name))
36
37 logger.info(
38 "Job %s (%s) started on %s: %s %s"
39diff --git a/lib/lp/services/job/runner.py b/lib/lp/services/job/runner.py
40index b0b65a2..15ea4e9 100644
41--- a/lib/lp/services/job/runner.py
42+++ b/lib/lp/services/job/runner.py
43@@ -326,25 +326,20 @@ class BaseRunnableJob(BaseRunnableJobSource):
44 """See `IJob`."""
45 self.job.start(manage_transaction=manage_transaction)
46 statsd = getUtility(IStatsdClient)
47- statsd.incr('job.start_count,type={},env={}'.format(
48- self.__class__.__name__,
49- statsd.lp_environment))
50+ statsd.incr('job.start_count,type={}'.format(self.__class__.__name__))
51
52 def complete(self, manage_transaction=False):
53 """See `IJob`."""
54 self.job.complete(manage_transaction=manage_transaction)
55 statsd = getUtility(IStatsdClient)
56- statsd.incr('job.complete_count,type={},env={}'.format(
57- self.__class__.__name__,
58- statsd.lp_environment))
59+ statsd.incr('job.complete_count,type={}'.format(
60+ self.__class__.__name__))
61
62 def fail(self, manage_transaction=False):
63 """See `IJob`."""
64 self.job.fail(manage_transaction=manage_transaction)
65 statsd = getUtility(IStatsdClient)
66- statsd.incr('job.fail_count,type={},env={}'.format(
67- self.__class__.__name__,
68- statsd.lp_environment))
69+ statsd.incr('job.fail_count,type={}'.format(self.__class__.__name__))
70
71
72 class BaseJobRunner(LazrJobRunner):
73diff --git a/lib/lp/services/statsd/model/statsd_client.py b/lib/lp/services/statsd/model/statsd_client.py
74index 6ccf027..7d6c3c1 100644
75--- a/lib/lp/services/statsd/model/statsd_client.py
76+++ b/lib/lp/services/statsd/model/statsd_client.py
77@@ -43,14 +43,17 @@ class StatsdClient:
78 self._make_client()
79
80 def __getattr__(self, name):
81- # This is a convenience to keep all statsd client related
82- # items on the client. Having this separate from prefix
83- # allows us to use it as a label, rather than as part of the
84- # gauge name
85- if name == 'lp_environment':
86- return config.statsd.environment
87 if self._client is not None:
88- return getattr(self._client, name)
89+ wrapped = getattr(self._client, name)
90+ if name in ("timer", "timing", "incr", "decr", "gauge", "set"):
91+ def wrapper(stat, *args, **kwargs):
92+ return wrapped(
93+ "%s,env=%s" % (stat, config.statsd.environment),
94+ *args, **kwargs)
95+
96+ return wrapper
97+ else:
98+ return wrapped
99 else:
100 # Prevent unnecessary network traffic if this Launchpad instance
101 # has no statsd configuration.
102diff --git a/lib/lp/services/statsd/numbercruncher.py b/lib/lp/services/statsd/numbercruncher.py
103index 27c61a4..3f1a6e1 100644
104--- a/lib/lp/services/statsd/numbercruncher.py
105+++ b/lib/lp/services/statsd/numbercruncher.py
106@@ -88,8 +88,7 @@ class NumberCruncher(service.Service):
107 virt = queue_type == 'virt'
108 for arch, value in contents.items():
109 gauge_name = (
110- "buildqueue,virtualized={},arch={},env={}".format(
111- virt, arch, self.statsd_client.lp_environment))
112+ "buildqueue,virtualized={},arch={}".format(virt, arch))
113 self._sendGauge(gauge_name, value[0])
114 self.logger.debug("Build queue stats update complete.")
115 except Exception:
116@@ -122,8 +121,8 @@ class NumberCruncher(service.Service):
117 counts['idle'] += 1
118 for processor, counts in counts_by_processor.items():
119 for count_name, count_value in counts.items():
120- gauge_name = "builders,status={},arch={},env={}".format(
121- count_name, processor, self.statsd_client.lp_environment)
122+ gauge_name = "builders,status={},arch={}".format(
123+ count_name, processor)
124 self._sendGauge(gauge_name, count_value)
125 self.logger.debug("Builder stats update complete.")
126
127@@ -149,14 +148,8 @@ class NumberCruncher(service.Service):
128 store = IStore(LibraryFileContent)
129 total_files, total_filesize = store.find(
130 (Count(), Sum(LibraryFileContent.filesize))).one()
131- self._sendGauge(
132- "librarian.total_files,env={}".format(
133- self.statsd_client.lp_environment),
134- total_files)
135- self._sendGauge(
136- "librarian.total_filesize,env={}".format(
137- self.statsd_client.lp_environment),
138- total_filesize)
139+ self._sendGauge("librarian.total_files", total_files)
140+ self._sendGauge("librarian.total_filesize", total_filesize)
141 self.logger.debug("Librarian stats update complete.")
142 except Exception:
143 self.logger.exception("Failure while updating librarian stats:")
144diff --git a/lib/lp/services/statsd/tests/__init__.py b/lib/lp/services/statsd/tests/__init__.py
145index 23fb067..c9c9ef5 100644
146--- a/lib/lp/services/statsd/tests/__init__.py
147+++ b/lib/lp/services/statsd/tests/__init__.py
148@@ -8,9 +8,11 @@ from __future__ import absolute_import, print_function, unicode_literals
149 __metaclass__ = type
150 __all__ = ['StatsMixin']
151
152+from fixtures import MockPatchObject
153+from zope.component import getUtility
154+
155 from lp.services.compat import mock
156 from lp.services.statsd.interfaces.statsd_client import IStatsdClient
157-from lp.testing.fixture import ZopeUtilityFixture
158
159
160 class StatsMixin:
161@@ -18,7 +20,8 @@ class StatsMixin:
162 def setUpStats(self):
163 # Install a mock statsd client so we can assert against the call
164 # counts and args.
165+ self.pushConfig("statsd", environment="test")
166+ statsd_client = getUtility(IStatsdClient)
167 self.stats_client = mock.Mock()
168- self.stats_client.lp_environment = "test"
169 self.useFixture(
170- ZopeUtilityFixture(self.stats_client, IStatsdClient))
171+ MockPatchObject(statsd_client, "_client", self.stats_client))
172diff --git a/lib/lp/services/statsd/tests/test_statsd_client.py b/lib/lp/services/statsd/tests/test_statsd_client.py
173index 2e1a8e1..709b41c 100644
174--- a/lib/lp/services/statsd/tests/test_statsd_client.py
175+++ b/lib/lp/services/statsd/tests/test_statsd_client.py
176@@ -50,13 +50,3 @@ class TestClientConfiguration(TestCase):
177 "port: 9999\nprefix: test\nenvironment: test\n")
178 client.reload()
179 self.assertIsInstance(client._client, StatsClient)
180-
181- def test_lp_environment_is_available(self):
182- client = getUtility(IStatsdClient)
183- self.addCleanup(client.reload)
184- config.push(
185- 'statsd_test',
186- "[statsd]\nhost: 127.0.01\n"
187- "port: 9999\nprefix: test\nenvironment: test\n")
188- client.reload()
189- self.assertEqual(client.lp_environment, "test")
190diff --git a/lib/lp/services/webapp/publication.py b/lib/lp/services/webapp/publication.py
191index 9a9a0e3..7325d9f 100644
192--- a/lib/lp/services/webapp/publication.py
193+++ b/lib/lp/services/webapp/publication.py
194@@ -795,16 +795,13 @@ class LaunchpadBrowserPublication(
195 status = request.response.getStatus()
196 if status == 404: # Not Found
197 OpStats.stats['404s'] += 1
198- statsd_client.incr('errors.404,env={}'.format(
199- statsd_client.lp_environment))
200+ statsd_client.incr('errors.404')
201 elif status == 500: # Unhandled exceptions
202 OpStats.stats['500s'] += 1
203- statsd_client.incr('errors.500,env={}'.format(
204- statsd_client.lp_environment))
205+ statsd_client.incr('errors.500')
206 elif status == 503: # Timeouts
207 OpStats.stats['503s'] += 1
208- statsd_client.incr('errors.503,env={}'.format(
209- statsd_client.lp_environment))
210+ statsd_client.incr('errors.503')
211
212 # Increment counters for status code groups.
213 status_group = str(status)[0] + 'XXs'
214@@ -813,8 +810,7 @@ class LaunchpadBrowserPublication(
215 # Increment counter for 5XXs_b.
216 if is_browser(request) and status_group == '5XXs':
217 OpStats.stats['5XXs_b'] += 1
218- statsd_client.incr('errors.5XX,env={}'.format(
219- statsd_client.lp_environment))
220+ statsd_client.incr('errors.5XX')
221
222 # Make sure our databases are in a sane state for the next request.
223 thread_name = threading.current_thread().name
224diff --git a/lib/lp/services/webapp/tests/test_publication.py b/lib/lp/services/webapp/tests/test_publication.py
225index 245fc28..a2a4953 100644
226--- a/lib/lp/services/webapp/tests/test_publication.py
227+++ b/lib/lp/services/webapp/tests/test_publication.py
228@@ -326,11 +326,11 @@ class TestPublisherStats(StatsMixin, TestCaseWithFactory):
229 MatchesListwise(
230 [MatchesListwise(
231 (Equals('traversal_duration,success=True,'
232- 'pageid=RootObject-index-html'),
233+ 'pageid=RootObject-index-html,env=test'),
234 GreaterThan(0))),
235 MatchesListwise(
236 (Equals('publication_duration,success=True,'
237- 'pageid=RootObject-index-html'),
238+ 'pageid=RootObject-index-html,env=test'),
239 GreaterThan(0)))]))
240
241 def test_traversal_failure_stats(self):
242@@ -350,7 +350,7 @@ class TestPublisherStats(StatsMixin, TestCaseWithFactory):
243 MatchesListwise(
244 [MatchesListwise(
245 (Equals('traversal_duration,success=False,'
246- 'pageid=None'),
247+ 'pageid=None,env=test'),
248 GreaterThan(0)))]))
249
250 def test_publication_failure_stats(self):
251@@ -370,11 +370,11 @@ class TestPublisherStats(StatsMixin, TestCaseWithFactory):
252 MatchesListwise(
253 [MatchesListwise(
254 (Equals('traversal_duration,success=True,'
255- 'pageid=RootObject-index-html'),
256+ 'pageid=RootObject-index-html,env=test'),
257 GreaterThan(0))),
258 MatchesListwise(
259 (Equals('publication_duration,success=False,'
260- 'pageid=RootObject-index-html'),
261+ 'pageid=RootObject-index-html,env=test'),
262 GreaterThan(0)))]))
263
264 def test_prepPageIDForMetrics_none(self):

Subscribers

People subscribed via source and target branches

to status/vote changes: