Merge ~twom/launchpad:stats-upload-numbers-with-your-uploads into launchpad:master

Proposed by Tom Wardill
Status: Merged
Approved by: Tom Wardill
Approved revision: f0e82b1097c4ecb16a698c74907dc2213b3b0e68
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~twom/launchpad:stats-upload-numbers-with-your-uploads
Merge into: launchpad:master
Prerequisite: ~twom/launchpad:stats-can-the-builders-count
Diff against target: 167 lines (+65/-2)
3 files modified
lib/lp/oci/tests/test_ocirecipebuildjob.py (+21/-1)
lib/lp/services/job/runner.py (+26/-0)
lib/lp/services/job/tests/test_runner.py (+18/-1)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+391628@code.launchpad.net

This proposal supersedes a proposal from 2020-09-30.

Commit message

Add stats reporting to various UploadJobs

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) :
review: Needs Information
2862122... by Tom Wardill

Move stats generation to the base job

33ed7fd... by Tom Wardill

Add comments

Revision history for this message
Colin Watson (cjwatson) :
review: Needs Information
e4fba93... by Tom Wardill

Move stats counting to BaseRunnableJob

f0e82b1... by Tom Wardill

Tidy imports

Revision history for this message
Colin Watson (cjwatson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/oci/tests/test_ocirecipebuildjob.py b/lib/lp/oci/tests/test_ocirecipebuildjob.py
2index 598940f..59554e6 100644
3--- a/lib/lp/oci/tests/test_ocirecipebuildjob.py
4+++ b/lib/lp/oci/tests/test_ocirecipebuildjob.py
5@@ -57,6 +57,7 @@ from lp.services.job.tests import (
6 block_on_job,
7 pop_remote_notifications,
8 )
9+from lp.services.statsd.tests import StatsMixin
10 from lp.services.webapp import canonical_url
11 from lp.services.webhooks.testing import LogsScheduledWebhooks
12 from lp.testing import (
13@@ -201,7 +202,8 @@ class MultiArchRecipeMixin:
14 return build_request
15
16
17-class TestOCIRegistryUploadJob(TestCaseWithFactory, MultiArchRecipeMixin):
18+class TestOCIRegistryUploadJob(TestCaseWithFactory, MultiArchRecipeMixin,
19+ StatsMixin):
20
21 layer = LaunchpadZopelessLayer
22
23@@ -212,6 +214,7 @@ class TestOCIRegistryUploadJob(TestCaseWithFactory, MultiArchRecipeMixin):
24 OCI_RECIPE_WEBHOOKS_FEATURE_FLAG: 'on',
25 OCI_RECIPE_ALLOW_CREATE: 'on'
26 }))
27+ self.setUpStats()
28
29 def makeOCIRecipeBuild(self, **kwargs):
30 ocibuild = self.factory.makeOCIRecipeBuild(
31@@ -291,6 +294,14 @@ class TestOCIRegistryUploadJob(TestCaseWithFactory, MultiArchRecipeMixin):
32 self.assertIsNone(job.errors)
33 self.assertEqual([], pop_notifications())
34 self.assertWebhookDeliveries(ocibuild, ["Pending", "Uploaded"], logger)
35+ self.assertEqual(4, self.stats_client.incr.call_count)
36+ calls = [x[0][0] for x in self.stats_client.incr.call_args_list]
37+ self.assertThat(calls, MatchesListwise([
38+ Equals('job.start_count,type=OCIRecipeRequestBuildsJob,env=test'),
39+ Equals(
40+ 'job.complete_count,type=OCIRecipeRequestBuildsJob,env=test'),
41+ Equals('job.start_count,type=OCIRegistryUploadJob,env=test'),
42+ Equals('job.complete_count,type=OCIRegistryUploadJob,env=test')]))
43
44 def test_run_multiple_architectures(self):
45 build_request = self.makeBuildRequest()
46@@ -323,6 +334,15 @@ class TestOCIRegistryUploadJob(TestCaseWithFactory, MultiArchRecipeMixin):
47 [((build_request, set(builds[:1])), {}),
48 ((build_request, set(builds)), {})],
49 client.uploadManifestList.calls)
50+ calls = [x[0][0] for x in self.stats_client.incr.call_args_list]
51+ self.assertThat(calls, MatchesListwise([
52+ Equals('job.start_count,type=OCIRecipeRequestBuildsJob,env=test'),
53+ Equals(
54+ 'job.complete_count,type=OCIRecipeRequestBuildsJob,env=test'),
55+ Equals('job.start_count,type=OCIRegistryUploadJob,env=test'),
56+ Equals('job.complete_count,type=OCIRegistryUploadJob,env=test'),
57+ Equals('job.start_count,type=OCIRegistryUploadJob,env=test'),
58+ Equals('job.complete_count,type=OCIRegistryUploadJob,env=test')]))
59
60 def test_failing_upload_does_not_retries_automatically(self):
61 build_request = self.makeBuildRequest(include_i386=False)
62diff --git a/lib/lp/services/job/runner.py b/lib/lp/services/job/runner.py
63index 9ac7863..b0b65a2 100644
64--- a/lib/lp/services/job/runner.py
65+++ b/lib/lp/services/job/runner.py
66@@ -61,6 +61,7 @@ from twisted.python import (
67 failure,
68 log,
69 )
70+from zope.component import getUtility
71 from zope.security.proxy import removeSecurityProxy
72
73 from lp.services import scripts
74@@ -78,6 +79,7 @@ from lp.services.mail.sendmail import (
75 MailController,
76 set_immediate_mail_delivery,
77 )
78+from lp.services.statsd.interfaces.statsd_client import IStatsdClient
79 from lp.services.timeout import (
80 get_default_timeout_function,
81 set_default_timeout_function,
82@@ -320,6 +322,30 @@ class BaseRunnableJob(BaseRunnableJobSource):
83 manage_transaction, abort_transaction,
84 add_commit_hook=self.celeryRunOnCommit)
85
86+ def start(self, manage_transaction=False):
87+ """See `IJob`."""
88+ self.job.start(manage_transaction=manage_transaction)
89+ statsd = getUtility(IStatsdClient)
90+ statsd.incr('job.start_count,type={},env={}'.format(
91+ self.__class__.__name__,
92+ statsd.lp_environment))
93+
94+ def complete(self, manage_transaction=False):
95+ """See `IJob`."""
96+ self.job.complete(manage_transaction=manage_transaction)
97+ statsd = getUtility(IStatsdClient)
98+ statsd.incr('job.complete_count,type={},env={}'.format(
99+ self.__class__.__name__,
100+ statsd.lp_environment))
101+
102+ def fail(self, manage_transaction=False):
103+ """See `IJob`."""
104+ self.job.fail(manage_transaction=manage_transaction)
105+ statsd = getUtility(IStatsdClient)
106+ statsd.incr('job.fail_count,type={},env={}'.format(
107+ self.__class__.__name__,
108+ statsd.lp_environment))
109+
110
111 class BaseJobRunner(LazrJobRunner):
112 """Runner of Jobs."""
113diff --git a/lib/lp/services/job/tests/test_runner.py b/lib/lp/services/job/tests/test_runner.py
114index 9827f1c..ec8dd11 100644
115--- a/lib/lp/services/job/tests/test_runner.py
116+++ b/lib/lp/services/job/tests/test_runner.py
117@@ -45,6 +45,7 @@ from lp.services.job.runner import (
118 )
119 from lp.services.log.logger import BufferLogger
120 from lp.services.scripts.logger import OopsHandler
121+from lp.services.statsd.tests import StatsMixin
122 from lp.services.timeline.requesttimeline import get_request_timeline
123 from lp.services.timeout import (
124 get_default_timeout_function,
125@@ -158,11 +159,15 @@ class RaisingRetryJob(NullJob):
126 raise RetryError()
127
128
129-class TestJobRunner(TestCaseWithFactory):
130+class TestJobRunner(StatsMixin, TestCaseWithFactory):
131 """Ensure JobRunner behaves as expected."""
132
133 layer = LaunchpadZopelessLayer
134
135+ def setUp(self):
136+ super(TestJobRunner, self).setUp()
137+ self.setUpStats()
138+
139 def makeTwoJobs(self):
140 """Test fixture. Create two jobs."""
141 return NullJob("job 1"), NullJob("job 2")
142@@ -174,6 +179,12 @@ class TestJobRunner(TestCaseWithFactory):
143 runner.runJob(job_1, None)
144 self.assertEqual(JobStatus.COMPLETED, job_1.job.status)
145 self.assertEqual([job_1], runner.completed_jobs)
146+ self.assertEqual(
147+ self.stats_client.incr.call_args_list[0][0],
148+ ('job.start_count,type=NullJob,env=test',))
149+ self.assertEqual(
150+ self.stats_client.incr.call_args_list[1][0],
151+ ('job.complete_count,type=NullJob,env=test',))
152
153 def test_runAll(self):
154 """Ensure runAll works in the normal case."""
155@@ -219,6 +230,12 @@ class TestJobRunner(TestCaseWithFactory):
156 oops = self.oopses[-1]
157 self.assertIn('Fake exception. Foobar, I say!', oops['tb_text'])
158 self.assertEqual(["{'foo': 'bar'}"], oops['req_vars'].values())
159+ self.assertEqual(
160+ self.stats_client.incr.call_args_list[0][0],
161+ ('job.start_count,type=NullJob,env=test',))
162+ self.assertEqual(
163+ self.stats_client.incr.call_args_list[1][0],
164+ ('job.fail_count,type=NullJob,env=test',))
165
166 def test_oops_messages_used_when_handling(self):
167 """Oops messages should appear even when exceptions are handled."""

Subscribers

People subscribed via source and target branches

to status/vote changes: