Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit 3895811

Browse files
authored
bundle analysis: sentry->prometheus metrics for upload view (#899)
1 parent 15f9614 commit 3895811

File tree

2 files changed

+146
-24
lines changed

2 files changed

+146
-24
lines changed

upload/tests/views/test_bundle_analysis.py

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
@pytest.mark.django_db(databases={"default", "timeseries"})
1919
def test_upload_bundle_analysis_success(db, client, mocker, mock_redis):
2020
upload = mocker.patch.object(TaskService, "upload")
21-
mock_sentry_metrics = mocker.patch(
22-
"upload.views.bundle_analysis.sentry_metrics.incr"
21+
mock_metrics = mocker.patch(
22+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
2323
)
2424
create_presigned_put = mocker.patch(
2525
"services.archive.StorageService.create_presigned_put",
@@ -89,9 +89,8 @@ def test_upload_bundle_analysis_success(db, client, mocker, mock_redis):
8989
report_code=None,
9090
report_type="bundle_analysis",
9191
)
92-
mock_sentry_metrics.assert_called_with(
93-
"upload",
94-
tags={
92+
mock_metrics.assert_called_with(
93+
**{
9594
"agent": "cli",
9695
"version": "0.4.7",
9796
"action": "bundle_analysis",
@@ -107,8 +106,8 @@ def test_upload_bundle_analysis_success(db, client, mocker, mock_redis):
107106
@override_settings(SHELTER_SHARED_SECRET="shelter-shared-secret")
108107
def test_upload_bundle_analysis_success_shelter(db, client, mocker, mock_redis):
109108
upload = mocker.patch.object(TaskService, "upload")
110-
mock_sentry_metrics = mocker.patch(
111-
"upload.views.bundle_analysis.sentry_metrics.incr"
109+
mock_metrics = mocker.patch(
110+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
112111
)
113112
create_presigned_put = mocker.patch(
114113
"services.archive.StorageService.create_presigned_put",
@@ -180,9 +179,8 @@ def test_upload_bundle_analysis_success_shelter(db, client, mocker, mock_redis):
180179
report_code=None,
181180
report_type="bundle_analysis",
182181
)
183-
mock_sentry_metrics.assert_called_with(
184-
"upload",
185-
tags={
182+
mock_metrics.assert_called_with(
183+
**{
186184
"agent": "cli",
187185
"version": "0.4.7",
188186
"action": "bundle_analysis",
@@ -201,6 +199,9 @@ def test_upload_bundle_analysis_org_token(db, client, mocker, mock_redis):
201199
"services.archive.StorageService.create_presigned_put",
202200
return_value="test-presigned-put",
203201
)
202+
mock_metrics = mocker.patch(
203+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
204+
)
204205

205206
repository = RepositoryFactory.create()
206207
org_token = OrganizationLevelTokenFactory.create(owner=repository.author)
@@ -217,6 +218,17 @@ def test_upload_bundle_analysis_org_token(db, client, mocker, mock_redis):
217218
format="json",
218219
)
219220
assert res.status_code == 201
221+
mock_metrics.assert_called_with(
222+
**{
223+
"agent": "unknown-user-agent",
224+
"version": "unknown-user-agent",
225+
"action": "bundle_analysis",
226+
"endpoint": "bundle_analysis",
227+
"repo_visibility": "private",
228+
"is_using_shelter": "no",
229+
"position": "end",
230+
},
231+
)
220232

221233

222234
@pytest.mark.django_db(databases={"default", "timeseries"})
@@ -226,6 +238,9 @@ def test_upload_bundle_analysis_existing_commit(db, client, mocker, mock_redis):
226238
"services.archive.StorageService.create_presigned_put",
227239
return_value="test-presigned-put",
228240
)
241+
mock_metrics = mocker.patch(
242+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
243+
)
229244

230245
repository = RepositoryFactory.create()
231246
commit = CommitFactory.create(repository=repository)
@@ -250,6 +265,17 @@ def test_upload_bundle_analysis_existing_commit(db, client, mocker, mock_redis):
250265
report_code=None,
251266
report_type="bundle_analysis",
252267
)
268+
mock_metrics.assert_called_with(
269+
**{
270+
"agent": "unknown-user-agent",
271+
"version": "unknown-user-agent",
272+
"action": "bundle_analysis",
273+
"endpoint": "bundle_analysis",
274+
"repo_visibility": "private",
275+
"is_using_shelter": "no",
276+
"position": "end",
277+
},
278+
)
253279

254280

255281
def test_upload_bundle_analysis_missing_args(db, client, mocker, mock_redis):
@@ -258,6 +284,9 @@ def test_upload_bundle_analysis_missing_args(db, client, mocker, mock_redis):
258284
"services.archive.StorageService.create_presigned_put",
259285
return_value="test-presigned-put",
260286
)
287+
mock_metrics = mocker.patch(
288+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
289+
)
261290

262291
repository = RepositoryFactory.create()
263292
commit = CommitFactory.create(repository=repository)
@@ -286,6 +315,16 @@ def test_upload_bundle_analysis_missing_args(db, client, mocker, mock_redis):
286315
assert res.status_code == 400
287316
assert res.json() == {"commit": ["This field is required."]}
288317
assert not upload.called
318+
mock_metrics.assert_called_with(
319+
**{
320+
"agent": "unknown-user-agent",
321+
"version": "unknown-user-agent",
322+
"action": "bundle_analysis",
323+
"endpoint": "bundle_analysis",
324+
"is_using_shelter": "no",
325+
"position": "start",
326+
},
327+
)
289328

290329

291330
def test_upload_bundle_analysis_invalid_token(db, client, mocker, mock_redis):
@@ -324,6 +363,9 @@ def test_upload_bundle_analysis_github_oidc_auth(
324363
"services.archive.StorageService.create_presigned_put",
325364
return_value="test-presigned-put",
326365
)
366+
mock_metrics = mocker.patch(
367+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
368+
)
327369
repository = RepositoryFactory()
328370
mock_jwt_decode.return_value = {
329371
"repository": f"url/{repository.name}",
@@ -344,18 +386,31 @@ def test_upload_bundle_analysis_github_oidc_auth(
344386
format="json",
345387
)
346388
assert res.status_code == 201
389+
mock_metrics.assert_called_with(
390+
**{
391+
"agent": "unknown-user-agent",
392+
"version": "unknown-user-agent",
393+
"action": "bundle_analysis",
394+
"endpoint": "bundle_analysis",
395+
"repo_visibility": "private",
396+
"is_using_shelter": "no",
397+
"position": "end",
398+
},
399+
)
347400

348401

349402
@pytest.mark.django_db(databases={"default", "timeseries"})
350403
def test_upload_bundle_analysis_measurement_datasets_created(
351404
db, client, mocker, mock_redis
352405
):
353406
mocker.patch.object(TaskService, "upload")
354-
mocker.patch("upload.views.bundle_analysis.sentry_metrics.incr")
355407
mocker.patch(
356408
"services.archive.StorageService.create_presigned_put",
357409
return_value="test-presigned-put",
358410
)
411+
mock_metrics = mocker.patch(
412+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
413+
)
359414

360415
repository = RepositoryFactory.create()
361416
commit_sha = "6fd5b89357fc8cdf34d6197549ac7c6d7e5977ef"
@@ -392,18 +447,32 @@ def test_upload_bundle_analysis_measurement_datasets_created(
392447
repository_id=repository.pk,
393448
).exists()
394449

450+
mock_metrics.assert_called_with(
451+
**{
452+
"agent": "cli",
453+
"version": "0.4.7",
454+
"action": "bundle_analysis",
455+
"endpoint": "bundle_analysis",
456+
"repo_visibility": "private",
457+
"is_using_shelter": "no",
458+
"position": "end",
459+
},
460+
)
461+
395462

396463
@override_settings(TIMESERIES_ENABLED=False)
397464
@pytest.mark.django_db(databases={"default", "timeseries"})
398465
def test_upload_bundle_analysis_measurement_timeseries_disabled(
399466
db, client, mocker, mock_redis
400467
):
401468
mocker.patch.object(TaskService, "upload")
402-
mocker.patch("upload.views.bundle_analysis.sentry_metrics.incr")
403469
mocker.patch(
404470
"services.archive.StorageService.create_presigned_put",
405471
return_value="test-presigned-put",
406472
)
473+
mock_metrics = mocker.patch(
474+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
475+
)
407476

408477
repository = RepositoryFactory.create()
409478
commit_sha = "6fd5b89357fc8cdf34d6197549ac7c6d7e5977ef"
@@ -440,6 +509,18 @@ def test_upload_bundle_analysis_measurement_timeseries_disabled(
440509
repository_id=repository.pk,
441510
).exists()
442511

512+
mock_metrics.assert_called_with(
513+
**{
514+
"agent": "cli",
515+
"version": "0.4.7",
516+
"action": "bundle_analysis",
517+
"endpoint": "bundle_analysis",
518+
"repo_visibility": "private",
519+
"is_using_shelter": "no",
520+
"position": "end",
521+
},
522+
)
523+
443524

444525
@pytest.mark.django_db(databases={"default", "timeseries"})
445526
def test_upload_bundle_analysis_no_repo(db, client, mocker, mock_redis):
@@ -449,6 +530,9 @@ def test_upload_bundle_analysis_no_repo(db, client, mocker, mock_redis):
449530
"services.archive.StorageService.create_presigned_put",
450531
return_value="test-presigned-put",
451532
)
533+
mock_metrics = mocker.patch(
534+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
535+
)
452536

453537
repository = RepositoryFactory.create()
454538
org_token = OrganizationLevelTokenFactory.create(owner=repository.author)
@@ -468,10 +552,24 @@ def test_upload_bundle_analysis_no_repo(db, client, mocker, mock_redis):
468552
assert res.json() == {"detail": "Repository not found."}
469553
assert not upload.called
470554

555+
mock_metrics.assert_called_with(
556+
**{
557+
"agent": "unknown-user-agent",
558+
"version": "unknown-user-agent",
559+
"action": "bundle_analysis",
560+
"endpoint": "bundle_analysis",
561+
"is_using_shelter": "no",
562+
"position": "start",
563+
},
564+
)
565+
471566

472567
@pytest.mark.django_db(databases={"default", "timeseries"})
473568
def test_upload_bundle_analysis_tokenless_success(db, client, mocker, mock_redis):
474569
upload = mocker.patch.object(TaskService, "upload")
570+
mock_metrics = mocker.patch(
571+
"upload.views.bundle_analysis.BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels"
572+
)
475573

476574
create_presigned_put = mocker.patch(
477575
"services.archive.StorageService.create_presigned_put",
@@ -508,6 +606,18 @@ def test_upload_bundle_analysis_tokenless_success(db, client, mocker, mock_redis
508606
assert upload.called
509607
create_presigned_put.assert_called_once_with("bundle-analysis", ANY, 30)
510608

609+
mock_metrics.assert_called_with(
610+
**{
611+
"agent": "cli",
612+
"version": "0.4.7",
613+
"action": "bundle_analysis",
614+
"endpoint": "bundle_analysis",
615+
"repo_visibility": "public",
616+
"is_using_shelter": "no",
617+
"position": "end",
618+
},
619+
)
620+
511621

512622
@pytest.mark.django_db(databases={"default", "timeseries"})
513623
def test_upload_bundle_analysis_tokenless_no_repo(db, client, mocker, mock_redis):

upload/views/bundle_analysis.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from rest_framework.permissions import BasePermission
1010
from rest_framework.response import Response
1111
from rest_framework.views import APIView
12-
from sentry_sdk import metrics as sentry_metrics
1312
from shared.bundle_analysis.storage import StoragePaths, get_bucket_name
13+
from shared.metrics import Counter
1414

1515
from codecov_auth.authentication.repo_auth import (
1616
BundleAnalysisTokenlessAuthentication,
@@ -33,6 +33,21 @@
3333
log = logging.getLogger(__name__)
3434

3535

36+
BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER = Counter(
37+
"bundle_analysis_upload_views_runs",
38+
"Number of times a raw report processor was run and with what result",
39+
[
40+
"agent",
41+
"version",
42+
"action",
43+
"endpoint",
44+
"is_using_shelter",
45+
"repo_visibility",
46+
"position",
47+
],
48+
)
49+
50+
3651
class UploadBundleAnalysisPermission(BasePermission):
3752
def has_permission(self, request: HttpRequest, view: Any) -> bool:
3853
return request.auth is not None and "upload" in request.auth.get_scopes()
@@ -66,16 +81,15 @@ def get_exception_handler(self) -> Callable:
6681
return repo_auth_custom_exception_handler
6782

6883
def post(self, request: HttpRequest) -> Response:
69-
sentry_metrics.incr(
70-
"upload",
71-
tags=generate_upload_sentry_metrics_tags(
84+
BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels(
85+
**generate_upload_sentry_metrics_tags(
7286
action="bundle_analysis",
7387
endpoint="bundle_analysis",
7488
request=self.request,
7589
is_shelter_request=self.is_shelter_request(),
7690
position="start",
77-
),
78-
)
91+
)
92+
).inc()
7993
serializer = UploadSerializer(data=request.data)
8094
if not serializer.is_valid():
8195
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@@ -154,18 +168,16 @@ def post(self, request: HttpRequest) -> Response:
154168
task_arguments=task_arguments,
155169
),
156170
)
157-
158-
sentry_metrics.incr(
159-
"upload",
160-
tags=generate_upload_sentry_metrics_tags(
171+
BUNDLE_ANALYSIS_UPLOAD_VIEWS_COUNTER.labels(
172+
**generate_upload_sentry_metrics_tags(
161173
action="bundle_analysis",
162174
endpoint="bundle_analysis",
163175
request=self.request,
164176
repository=repo,
165177
is_shelter_request=self.is_shelter_request(),
166178
position="end",
167-
),
168-
)
179+
)
180+
).inc()
169181

170182
dispatch_upload_task(
171183
task_arguments,

0 commit comments

Comments
 (0)