Skip to content

Commit c46d537

Browse files
authored
Build retrieval improvements (#4412)
### Motivation Small changes for the build retrieval metric, as requested per Chrome folks after initially using the feature: * Adding the time for listing fuzz targets as a step * Added the total retrieval duration * Tracking metric as minutes, for readability Part of #4271
1 parent 5cfd235 commit c46d537

File tree

2 files changed

+30
-35
lines changed

2 files changed

+30
-35
lines changed

src/clusterfuzz/_internal/build_management/build_manager.py

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,17 @@ def set_env_var(name, value):
299299
logs.error(f'Could not find app {app_name!r} in search directories.')
300300

301301

302+
def _emit_job_build_retrieval_metric(start_time, step, build_type):
303+
elapsed_minutes = (time.time() - start_time) / 60
304+
monitoring_metrics.JOB_BUILD_RETRIEVAL_TIME.add(
305+
elapsed_minutes, {
306+
'job': os.getenv('JOB_NAME'),
307+
'platform': environment.platform(),
308+
'step': step,
309+
'build_type': build_type,
310+
})
311+
312+
302313
class BaseBuild:
303314
"""Represents a build."""
304315

@@ -440,14 +451,7 @@ def _download_and_open_build_archive(self, base_build_dir: str,
440451
try:
441452
start_time = time.time()
442453
storage.copy_file_from(build_url, build_local_archive)
443-
build_download_duration = time.time() - start_time
444-
monitoring_metrics.JOB_BUILD_RETRIEVAL_TIME.add(
445-
build_download_duration, {
446-
'job': os.getenv('JOB_NAME'),
447-
'platform': environment.platform(),
448-
'step': 'download',
449-
'build_type': self._build_type,
450-
})
454+
_emit_job_build_retrieval_metric(start_time, 'download', self._build_type)
451455
except Exception as e:
452456
logs.error(f'Unable to download build from {build_url}: {e}')
453457
raise
@@ -522,7 +526,11 @@ def _unpack_build(self,
522526
if not self._unpack_everything:
523527
# We will never unpack the full build so we need to get the targets
524528
# from the build archive.
529+
list_fuzz_target_start_time = time.time()
525530
self._fuzz_targets = list(build.list_fuzz_targets())
531+
_emit_job_build_retrieval_metric(list_fuzz_target_start_time,
532+
'list_fuzz_targets',
533+
self._build_type)
526534
# We only want to unpack a single fuzz target if unpack_everything is
527535
# False.
528536
fuzz_target_to_unpack = self.fuzz_target
@@ -547,15 +555,8 @@ def _unpack_build(self,
547555
fuzz_target=fuzz_target_to_unpack,
548556
trusted=trusted)
549557

550-
unpack_elapsed_time = time.time() - unpack_start_time
551-
552-
monitoring_metrics.JOB_BUILD_RETRIEVAL_TIME.add(
553-
unpack_elapsed_time, {
554-
'job': os.getenv('JOB_NAME'),
555-
'platform': environment.platform(),
556-
'step': 'unpack',
557-
'build_type': self._build_type,
558-
})
558+
_emit_job_build_retrieval_metric(unpack_start_time, 'unpack',
559+
self._build_type)
559560

560561
except Exception as e:
561562
logs.error(f'Unable to unpack build archive {build_url}: {e}')
@@ -567,6 +568,7 @@ def _unpack_build(self,
567568
partial_build_file_path = os.path.join(build_dir, PARTIAL_BUILD_FILE)
568569
utils.write_data_to_file('', partial_build_file_path)
569570

571+
_emit_job_build_retrieval_metric(start_time, 'total', self._build_type)
570572
elapsed_time = time.time() - start_time
571573

572574
elapsed_mins = elapsed_time / 60.
@@ -598,7 +600,10 @@ def fuzz_targets(self):
598600
if not self._fuzz_targets and self._unpack_everything:
599601
# we can lazily compute that when unpacking the whole archive, since we
600602
# know all the fuzzers will be in the build directory.
603+
start_time = time.time()
601604
self._fuzz_targets = list(self._get_fuzz_targets_from_dir(self.build_dir))
605+
_emit_job_build_retrieval_metric(start_time, 'list_fuzz_targets',
606+
self._build_type)
602607
return self._fuzz_targets
603608

604609
def exists(self):
@@ -905,15 +910,8 @@ def _unpack_custom_build(self):
905910
build_local_archive):
906911
return False
907912

908-
build_download_time = time.time() - download_start_time
909-
monitoring_metrics.JOB_BUILD_RETRIEVAL_TIME.add(
910-
build_download_time, {
911-
'job': os.getenv('JOB_NAME'),
912-
'platform': environment.platform(),
913-
'step': 'download',
914-
'build_type': self._build_type,
915-
})
916-
913+
_emit_job_build_retrieval_metric(download_start_time, 'download',
914+
self._build_type)
917915
# If custom binary is an archive, then unpack it.
918916
if archive.is_archive(self.custom_binary_filename):
919917
try:
@@ -933,14 +931,8 @@ def _unpack_custom_build(self):
933931
# Unpack belongs to the BuildArchive class
934932
unpack_start_time = time.time()
935933
build.unpack(self.build_dir, trusted=True)
936-
build_unpack_time = time.time() - unpack_start_time
937-
monitoring_metrics.JOB_BUILD_RETRIEVAL_TIME.add(
938-
build_unpack_time, {
939-
'job': os.getenv('JOB_NAME'),
940-
'platform': environment.platform(),
941-
'step': 'unpack',
942-
'build_type': self._build_type,
943-
})
934+
_emit_job_build_retrieval_metric(unpack_start_time, 'unpack',
935+
self._build_type)
944936
except:
945937
build.close()
946938
logs.error('Unable to unpack build archive %s.' % build_local_archive)
@@ -949,6 +941,9 @@ def _unpack_custom_build(self):
949941
build.close()
950942
# Remove the archive.
951943
shell.remove_file(build_local_archive)
944+
945+
_emit_job_build_retrieval_metric(download_start_time, 'download',
946+
self._build_type)
952947
return True
953948

954949
def setup(self):

src/clusterfuzz/_internal/metrics/monitoring_metrics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
'task/build_retrieval_time',
4949
bucketer=monitor.FixedWidthBucketer(width=0.05, num_finite_buckets=20),
5050
description=('Distribution of fuzz task\'s build retrieval times. '
51-
'(grouped by fuzzer/job)'),
51+
'(grouped by fuzzer/job, in minutes).'),
5252
field_spec=[
5353
monitor.StringField('job'),
5454
monitor.StringField('step'),

0 commit comments

Comments
 (0)