From 5647a27a2974f9dde93d6c415424ad3589d5faf2 Mon Sep 17 00:00:00 2001 From: Joe Hoyle Date: Tue, 1 Oct 2024 14:57:20 +0000 Subject: [PATCH] Reduce number of API calls to PutMetricData This should reduce the calls to 1 from 9. --- .../namespace.php | 150 +++++++++++++++--- 1 file changed, 126 insertions(+), 24 deletions(-) diff --git a/inc/cavalcade_runner_to_cloudwatch/namespace.php b/inc/cavalcade_runner_to_cloudwatch/namespace.php index 51159b02..9aef3e5c 100644 --- a/inc/cavalcade_runner_to_cloudwatch/namespace.php +++ b/inc/cavalcade_runner_to_cloudwatch/namespace.php @@ -35,12 +35,6 @@ function bootstrap() { function on_job_started( Worker $worker, Job $job ) { global $job_start_times; $job_start_times[ $job->id ] = microtime( true ); - put_metric_data( 'Invocations', 1, [ - 'Application' => HM_ENV, - 'Job' => $job->hook, - ] ); - put_metric_data( 'Invocations', 1, [ 'Application' => HM_ENV ] ); - put_metric_data( 'Invocations', 1 ); } /** @@ -50,11 +44,6 @@ function on_job_started( Worker $worker, Job $job ) { * @param Job $job The current Cavalcade cron job. */ function on_job_failed( Worker $worker, Job $job ) { - put_metric_data( 'Failed', 1, [ - 'Application' => HM_ENV, - 'Job' => $job->hook, - ] ); - put_metric_data( 'Failed', 1, [ 'Application' => HM_ENV ] ); put_metric_data( 'Failed', 1 ); on_end_job( $worker, $job, 'fail' ); } @@ -66,12 +55,6 @@ function on_job_failed( Worker $worker, Job $job ) { * @param Job $job The current Cavalcade cron job. */ function on_job_completed( Worker $worker, Job $job ) { - put_metric_data( 'Completed', 1, [ - 'Application' => HM_ENV, - 'Job' => $job->hook, - ] ); - put_metric_data( 'Completed', 1, [ 'Application' => HM_ENV ] ); - put_metric_data( 'Completed', 1 ); on_end_job( $worker, $job, 'success' ); } @@ -80,18 +63,120 @@ function on_job_completed( Worker $worker, Job $job ) { * * @param Worker $worker The Cavalcade runner process. * @param Job $job The current Cavalcade cron job. - * @param string $status The job status. + * @param 'success'|'fail' $status The job status. */ function on_end_job( Worker $worker, Job $job, string $status ) { global $job_start_times; $duration = microtime( true ) - $job_start_times[ $job->id ]; unset( $job_start_times[ $job->id ] ); - put_metric_data( 'Duration', $duration, [ - 'Application' => HM_ENV, - 'Job' => $job->hook, - ], 'Seconds' ); - put_metric_data( 'Duration', $duration, [ 'Application' => HM_ENV ], 'Seconds' ); - put_metric_data( 'Duration', $duration, [], 'Seconds' ); + + $status_metric = $status === 'success' ? 'Completed' : 'Failed'; + + // Batch all the metrics together to avoid many API calls. + $data = []; + $data[] = [ + 'MetricName' => $status_metric, + 'Dimensions' => [ + [ + 'Name' => 'Application', + 'Value' => HM_ENV, + ], + [ + 'Name' => 'Job', + 'Value' => $job->hook, + ], + ], + 'Value' => 1, + ]; + $data[] = [ + 'MetricName' => $status_metric, + 'Dimensions' => [ + [ + 'Name' => 'Application', + 'Value' => HM_ENV, + ], + ], + 'Value' => 1, + ]; + $data[] = [ + 'MetricName' => $status_metric, + 'Value' => 1, + ]; + + $data[] = [ + 'MetricName' => 'Invocations', + 'Dimensions' => [ + [ + 'Name' => 'Application', + 'Value' => HM_ENV, + ], + [ + 'Name' => 'Job', + 'Value' => $job->hook, + ], + ], + 'Value' => 1, + ]; + $data[] = [ + 'MetricName' => 'Invocations', + 'Dimensions' => [ + [ + 'Name' => 'Application', + 'Value' => HM_ENV, + ], + ], + 'Value' => 1, + ]; + $data[] = [ + 'MetricName' => 'Invocations', + 'Value' => 1, + ]; + $data[] = [ + 'MetricName' => 'Duration', + 'Dimensions' => [ + [ + 'Name' => 'Application', + 'Value' => HM_ENV, + ], + [ + 'Name' => 'Job', + 'Value' => $job->hook, + ], + ], + 'Value' => $duration, + ]; + $data[] = [ + 'MetricName' => 'Duration', + 'Unit' => 'Seconds', + 'Dimensions' => [ + [ + 'Name' => 'Application', + 'Value' => HM_ENV, + ], + [ + 'Name' => 'Job', + 'Value' => $job->hook, + ], + ], + 'Value' => $duration, + ]; + $data[] = [ + 'MetricName' => 'Duration', + 'Unit' => 'Seconds', + 'Dimensions' => [ + [ + 'Name' => 'Application', + 'Value' => HM_ENV, + ], + ], + 'Value' => $duration, + ]; + $data[] = [ + 'MetricName' => 'Duration', + 'Unit' => 'Seconds', + 'Value' => $duration, + ]; + put_metric_data_multiple( $data ); // Workaround to get the stdout / stderr for the job. $reflection = new ReflectionClass( $worker ); @@ -152,6 +237,23 @@ function ( $name, $value ) { } } +/** + * Save metric data to CloudWatch. + * + * @param array{ MetricName: string, ?Unit: string, ?Dimensions: { Name: string, value: int}[], Value: float }[] $data The metric data to save. + */ +function put_metric_data_multiple( array $data ) { + try { + cloudwatch_client()->putMetricData([ + 'MetricData' => $data, + 'Namespace' => 'Cavalcade', + ]); + } catch ( Exception $e ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + trigger_error( sprintf( 'Error from CloudWatch API: %s', $e->getMessage() ), E_USER_WARNING ); + } +} + /** * Get a configured CloudWatchClient client. *