Skip to content

Commit 6f87531

Browse files
committed
Add configurable max send queue size (#1441)
1 parent 4b164b7 commit 6f87531

24 files changed

+572
-9
lines changed

agent/native/ext/ConfigManager.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ typedef struct DurationOptionAdditionalMetadata DurationOptionAdditionalMetadata
117117
struct SizeOptionAdditionalMetadata
118118
{
119119
SizeUnits defaultUnits = sizeUnits_byte;
120+
Int64 minValidValueInBytes = INT64_MIN;
120121
};
121122
typedef struct SizeOptionAdditionalMetadata SizeOptionAdditionalMetadata;
122123

@@ -427,7 +428,14 @@ static ResultCode parseSizeValue( const OptionMetadata* optMeta, String rawValue
427428
ResultCode parseResultCode = parseSize( stringToView( rawValue )
428429
, optMeta->additionalData.sizeData.defaultUnits
429430
, /* out */ &parsedValue->u.sizeValue );
430-
if ( parseResultCode == resultSuccess ) parsedValue->type = parsedOptionValueType_size;
431+
if ( parseResultCode == resultSuccess )
432+
{
433+
if ( sizeToBytes( parsedValue->u.sizeValue ) < optMeta->additionalData.sizeData.minValidValueInBytes )
434+
{
435+
return resultParsingFailed;
436+
}
437+
parsedValue->type = parsedOptionValueType_size;
438+
}
431439
return parseResultCode;
432440
}
433441

@@ -667,7 +675,7 @@ static OptionMetadata buildDurationOptionMetadata(
667675
};
668676
}
669677

670-
[[maybe_unused]] static OptionMetadata buildSizeOptionMetadata(
678+
static OptionMetadata buildSizeOptionMetadata(
671679
String name
672680
, StringView iniName
673681
, bool isSecret
@@ -676,6 +684,7 @@ static OptionMetadata buildDurationOptionMetadata(
676684
, SetConfigSnapshotFieldFunc setFieldFunc
677685
, GetConfigSnapshotFieldFunc getFieldFunc
678686
, SizeUnits defaultUnits
687+
, Int64 minValidValueInBytes
679688
)
680689
{
681690
return (OptionMetadata)
@@ -692,7 +701,7 @@ static OptionMetadata buildDurationOptionMetadata(
692701
.setField = setFieldFunc,
693702
.getField = getFieldFunc,
694703
.parsedValueToZval = &parsedSizeValueToZval,
695-
.additionalData = (OptionAdditionalMetadata){ .sizeData = (SizeOptionAdditionalMetadata){ .defaultUnits = defaultUnits } }
704+
.additionalData = (OptionAdditionalMetadata){ .sizeData = (SizeOptionAdditionalMetadata){ .defaultUnits = defaultUnits, .minValidValueInBytes = minValidValueInBytes } }
696705
};
697706
}
698707

@@ -827,6 +836,7 @@ ELASTIC_APM_DEFINE_ENUM_FIELD_ACCESS_FUNCS( LogLevel, logLevelSyslog )
827836
# ifdef PHP_WIN32
828837
ELASTIC_APM_DEFINE_ENUM_FIELD_ACCESS_FUNCS( LogLevel, logLevelWinSysDebug )
829838
# endif
839+
ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( sizeValue, maxSendQueueSize )
830840
# if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 )
831841
ELASTIC_APM_DEFINE_ENUM_FIELD_ACCESS_FUNCS( MemoryTrackingLevel, memoryTrackingLevel )
832842
# endif
@@ -882,6 +892,9 @@ ELASTIC_APM_DEFINE_FIELD_ACCESS_FUNCS( stringValue, debugDiagnosticsFile )
882892
#define ELASTIC_APM_INIT_DURATION_METADATA( fieldName, optName, defaultValue, defaultUnits, isNegativeValid ) \
883893
ELASTIC_APM_INIT_METADATA_EX( buildDurationOptionMetadata, fieldName, optName, /* isSecret */ false, /* isDynamic */ false, defaultValue, defaultUnits, isNegativeValid )
884894

895+
#define ELASTIC_APM_INIT_SIZE_METADATA( fieldName, optName, defaultValue, defaultUnits, minValidValueInBytes ) \
896+
ELASTIC_APM_INIT_METADATA_EX( buildSizeOptionMetadata, fieldName, optName, /* isSecret */ false, /* isDynamic */ false, defaultValue, defaultUnits, minValidValueInBytes )
897+
885898
#define ELASTIC_APM_INIT_SECRET_METADATA( buildFunc, fieldName, optName, defaultValue ) \
886899
ELASTIC_APM_INIT_METADATA_EX( buildFunc, fieldName, optName, /* isSecret */ true, /* isDynamic */ false, defaultValue )
887900

@@ -1115,6 +1128,13 @@ static void initOptionsMetadata( OptionMetadata* optsMeta )
11151128
ELASTIC_APM_CFG_OPT_NAME_LOG_LEVEL_WIN_SYS_DEBUG );
11161129
#endif
11171130

1131+
ELASTIC_APM_INIT_SIZE_METADATA(
1132+
maxSendQueueSize,
1133+
ELASTIC_APM_CFG_OPT_NAME_MAX_SEND_QUEUE_SIZE,
1134+
/* defaultValue: */ makeSize( 10, sizeUnits_mebibyte ),
1135+
/* defaultUnits: */ sizeUnits_mebibyte,
1136+
/* minValidValueInBytes: */ 1 );
1137+
11181138
#if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 )
11191139
ELASTIC_APM_ENUM_INIT_METADATA(
11201140
/* fieldName: */ memoryTrackingLevel,

agent/native/ext/ConfigManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ enum OptionId
9696
#ifdef PHP_WIN32
9797
optionId_logLevelWinSysDebug,
9898
#endif
99+
optionId_maxSendQueueSize,
99100
#if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 )
100101
optionId_memoryTrackingLevel,
101102
#endif
@@ -303,6 +304,8 @@ const ConfigSnapshot* getGlobalCurrentConfigSnapshot();
303304
#define ELASTIC_APM_CFG_OPT_NAME_LOG_LEVEL_WIN_SYS_DEBUG "log_level_win_sys_debug"
304305
# endif
305306

307+
#define ELASTIC_APM_CFG_OPT_NAME_MAX_SEND_QUEUE_SIZE "max_send_queue_size"
308+
306309
/**
307310
* Internal configuration option (not included in public documentation)
308311
*/

agent/native/ext/ConfigSnapshot.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "LogLevel.h"
2626
#include "OptionalBool.h"
2727
#include "time_util.h" // Duration
28+
#include "util.h" // Size
2829
#include "elastic_apm_assert_enabled.h"
2930

3031
struct ConfigSnapshot
@@ -68,6 +69,7 @@ struct ConfigSnapshot
6869
#ifdef PHP_WIN32
6970
LogLevel logLevelWinSysDebug = logLevel_off;
7071
#endif
72+
Size maxSendQueueSize;
7173
#if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 )
7274
MemoryTrackingLevel memoryTrackingLevel = memoryTrackingLevel_off;
7375
#endif

agent/native/ext/backend_comm.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -660,15 +660,14 @@ static void freeDataToSendQueue( DataToSendQueue* dataQueue )
660660
}
661661
}
662662

663-
#define ELASTIC_APM_MAX_QUEUE_SIZE_IN_BYTES (10 * 1024 * 1024)
664-
665663
struct BackgroundBackendComm
666664
{
667665
Mutex* mutex;
668666
ConditionVariable* condVar;
669667
Thread* thread;
670668
DataToSendQueue dataToSendQueue;
671669
size_t dataToSendTotalSize;
670+
UInt64 maxQueueSizeInBytes;
672671
size_t nextEventsBatchId;
673672
bool shouldExit;
674673
TimeSpec shouldExitBy;
@@ -1051,13 +1050,17 @@ ResultCode newBackgroundBackendComm( const ConfigSnapshot* config, BackgroundBac
10511050

10521051
ResultCode resultCode;
10531052
BackgroundBackendComm* backgroundBackendComm = NULL;
1053+
Int64 maxQueueSizeInBytes = sizeToBytes( config->maxSendQueueSize );
1054+
1055+
ELASTIC_APM_ASSERT( maxQueueSizeInBytes > 0, "maxQueueSizeInBytes: %" PRId64, maxQueueSizeInBytes );
10541056

10551057
ELASTIC_APM_MALLOC_INSTANCE_IF_FAILED_GOTO( BackgroundBackendComm, /* out */ backgroundBackendComm );
10561058
backgroundBackendComm->condVar = NULL;
10571059
backgroundBackendComm->mutex = NULL;
10581060
backgroundBackendComm->thread = NULL;
10591061
initDataToSendQueue( &( backgroundBackendComm->dataToSendQueue ) );
10601062
backgroundBackendComm->dataToSendTotalSize = 0;
1063+
backgroundBackendComm->maxQueueSizeInBytes = (UInt64) maxQueueSizeInBytes;
10611064
backgroundBackendComm->nextEventsBatchId = 1;
10621065
backgroundBackendComm->shouldExit = false;
10631066
ELASTIC_APM_CALL_IF_FAILED_GOTO( newMutex( &( backgroundBackendComm->mutex ), /* dbgDesc */ "Background backend communications" ) );
@@ -1179,15 +1182,21 @@ ResultCode enqueueEventsToSendToApmServer( StringView userAgentHttpHeader, Strin
11791182
bool shouldUnlockMutex = false;
11801183
UInt64 id;
11811184
BackgroundBackendComm* backgroundBackendComm = g_backgroundBackendComm;
1185+
UInt64 totalSizeAfterEnqueue;
11821186

11831187
ELASTIC_APM_CALL_IF_FAILED_GOTO( lockMutex( backgroundBackendComm->mutex, &shouldUnlockMutex, __FUNCTION__ ) );
11841188

1185-
if ( backgroundBackendComm->dataToSendTotalSize >= ELASTIC_APM_MAX_QUEUE_SIZE_IN_BYTES )
1189+
totalSizeAfterEnqueue = (UInt64) backgroundBackendComm->dataToSendTotalSize + (UInt64) serializedEvents.length;
1190+
if ( totalSizeAfterEnqueue > backgroundBackendComm->maxQueueSizeInBytes )
11861191
{
11871192
ELASTIC_APM_LOG_ERROR(
1188-
"Already queued events are above max queue size - dropping these events"
1193+
"Queueing these events would exceed max queue size - dropping these events"
11891194
"; size of already queued events: %" PRIu64
1190-
, (UInt64) backgroundBackendComm->dataToSendTotalSize );
1195+
"; size of events to queue: %" PRIu64
1196+
"; max queue size: %" PRIu64
1197+
, (UInt64) backgroundBackendComm->dataToSendTotalSize
1198+
, (UInt64) serializedEvents.length
1199+
, backgroundBackendComm->maxQueueSizeInBytes );
11911200
ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE();
11921201
}
11931202

agent/native/ext/elastic_apm.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ PHP_INI_BEGIN()
173173
#ifdef PHP_WIN32
174174
ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_LOG_LEVEL_WIN_SYS_DEBUG )
175175
#endif
176+
ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_MAX_SEND_QUEUE_SIZE )
176177
#if ( ELASTIC_APM_MEMORY_TRACKING_ENABLED_01 != 0 )
177178
ELASTIC_APM_INI_ENTRY( ELASTIC_APM_CFG_OPT_NAME_MEMORY_TRACKING_LEVEL )
178179
#endif

agent/native/ext/tests/config_defaults.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ ELASTIC_APM_LOG_LEVEL=
88
ELASTIC_APM_LOG_LEVEL_FILE=
99
ELASTIC_APM_LOG_LEVEL_SYSLOG=
1010
ELASTIC_APM_LOG_LEVEL_WIN_SYS_DEBUG=
11+
ELASTIC_APM_MAX_SEND_QUEUE_SIZE=
1112
ELASTIC_APM_SECRET_TOKEN=
1213
ELASTIC_APM_SERVER_URL=
1314
ELASTIC_APM_SERVICE_NAME=
@@ -78,6 +79,15 @@ if (elasticApmIsOsWindows()) {
7879
elasticApmAssertSame("elastic_apm_get_config_option_by_name('log_level_win_sys_debug')", elastic_apm_get_config_option_by_name('log_level_win_sys_debug'), ELASTIC_APM_LOG_LEVEL_NOT_SET);
7980
}
8081

82+
//////////////////////////////////////////////
83+
/////////////// max_send_queue_size
84+
85+
elasticApmAssertSame("getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE')", getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE'), false);
86+
87+
elasticApmAssertEqual("ini_get('elastic_apm.max_send_queue_size')", ini_get('elastic_apm.max_send_queue_size'), false);
88+
89+
elasticApmAssertSame("elastic_apm_get_config_option_by_name('max_send_queue_size')", elastic_apm_get_config_option_by_name('max_send_queue_size'), 10.0 * 1024 * 1024);
90+
8191
//////////////////////////////////////////////
8292
/////////////// secret_token
8393

agent/native/ext/tests/config_ini_has_higher_precedence_than_env_vars.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ Configuration in ini file has higher precedence than environment variables
44
ELASTIC_APM_LOG_LEVEL_STDERR=CRITICAL
55
ELASTIC_APM_LOG_FILE=log_file_from_env_vars.txt
66
ELASTIC_APM_LOG_LEVEL_FILE=off
7+
ELASTIC_APM_MAX_SEND_QUEUE_SIZE=123MB
78
--INI--
89
elastic_apm.log_file=log_file_from_ini.txt
10+
elastic_apm.max_send_queue_size=456MB
911
elastic_apm.bootstrap_php_part_file=../../php/bootstrap_php_part.php
1012
--FILE--
1113
<?php
@@ -18,6 +20,12 @@ elasticApmAssertSame("ini_get('elastic_apm.log_file')", ini_get('elastic_apm.log
1820

1921
elasticApmAssertSame("elastic_apm_get_config_option_by_name('log_file')", elastic_apm_get_config_option_by_name('log_file'), 'log_file_from_ini.txt');
2022

23+
elasticApmAssertSame("getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE')", getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE'), '123MB');
24+
25+
elasticApmAssertSame("ini_get('elastic_apm.max_send_queue_size')", ini_get('elastic_apm.max_send_queue_size'), '456MB');
26+
27+
elasticApmAssertSame("elastic_apm_get_config_option_by_name('max_send_queue_size')", elastic_apm_get_config_option_by_name('max_send_queue_size'), 456.0 * 1024 * 1024);
28+
2129
echo 'Test completed'
2230
?>
2331
--EXPECT--

agent/native/ext/tests/config_invalid_ini_fallback_default_not_env_var.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ When value in ini is invalid the fallback is the default and not environment var
33
--ENV--
44
ELASTIC_APM_LOG_LEVEL_STDERR=CRITICAL
55
ELASTIC_APM_ASSERT_LEVEL=O_n
6+
ELASTIC_APM_MAX_SEND_QUEUE_SIZE=123MB
67
ELASTIC_APM_MEMORY_TRACKING_LEVEL=ALL
78
ELASTIC_APM_VERIFY_SERVER_CERT=false
89
--INI--
10+
elastic_apm.max_send_queue_size=0
911
elastic_apm.memory_tracking_level=not a valid memory tracking level
1012
elastic_apm.verify_server_cert=not a valid bool
1113
elastic_apm.bootstrap_php_part_file=../../php/bootstrap_php_part.php
@@ -18,6 +20,10 @@ require __DIR__ . '/../tests_util/tests_util.php';
1820
elasticApmAssertSame("elastic_apm_get_config_option_by_name('assert_level')", elastic_apm_get_config_option_by_name('assert_level'), ELASTIC_APM_ASSERT_LEVEL_O_N);
1921
elasticApmAssertSame("getenv('ELASTIC_APM_ASSERT_LEVEL')", getenv('ELASTIC_APM_ASSERT_LEVEL'), 'O_n');
2022

23+
// max_send_queue_size is set in ini but the value is invalid so it falls back on default (which is `10MB`) and not the value set by env vars (which is `123MB`)
24+
elasticApmAssertSame("elastic_apm_get_config_option_by_name('max_send_queue_size')", elastic_apm_get_config_option_by_name('max_send_queue_size'), 10.0 * 1024 * 1024);
25+
elasticApmAssertSame("getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE')", getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE'), '123MB');
26+
2127
// memory_tracking_level is set in ini but the value is invalid so it falls back on default (which is `ELASTIC_APM_MEMORY_TRACKING_LEVEL_NOT_SET) and not the value set by env vars (which is ELASTIC_APM_MEMORY_TRACKING_LEVEL_ALL)
2228
elasticApmAssertSame("elastic_apm_get_config_option_by_name('memory_tracking_level')", elastic_apm_get_config_option_by_name('memory_tracking_level'), ELASTIC_APM_MEMORY_TRACKING_LEVEL_NOT_SET);
2329
elasticApmAssertSame("getenv('ELASTIC_APM_MEMORY_TRACKING_LEVEL')", getenv('ELASTIC_APM_MEMORY_TRACKING_LEVEL'), 'ALL');

agent/native/ext/tests/config_setting_to_invalid_values_using_env_vars.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Setting configuration option to invalid value via environment variables
44
ELASTIC_APM_LOG_LEVEL_STDERR=CRITICAL
55
ELASTIC_APM_ENABLED=not_valid_boolean_value
66
ELASTIC_APM_ASSERT_LEVEL=|:/:\:|
7+
ELASTIC_APM_MAX_SEND_QUEUE_SIZE=0
78
ELASTIC_APM_SECRET_TOKEN=\|<>|/
89
ELASTIC_APM_SERVER_URL=<\/\/>
910
ELASTIC_APM_SERVICE_NAME=/\><\/
@@ -30,6 +31,13 @@ elasticApmAssertSame("getenv('ELASTIC_APM_ASSERT_LEVEL')", getenv('ELASTIC_APM_A
3031

3132
elasticApmAssertSame("elastic_apm_get_config_option_by_name('assert_level')", elastic_apm_get_config_option_by_name('assert_level'), ELASTIC_APM_ASSERT_LEVEL_NOT_SET);
3233

34+
//////////////////////////////////////////////
35+
/////////////// max_send_queue_size
36+
37+
elasticApmAssertSame("getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE')", getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE'), '0');
38+
39+
elasticApmAssertSame("elastic_apm_get_config_option_by_name('max_send_queue_size')", elastic_apm_get_config_option_by_name('max_send_queue_size'), 10.0 * 1024 * 1024);
40+
3341
//////////////////////////////////////////////
3442
/////////////// secret_token
3543

agent/native/ext/tests/config_setting_to_non-defaults_using_env_vars.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ ELASTIC_APM_LOG_LEVEL=CRITICAL
88
ELASTIC_APM_LOG_LEVEL_FILE=TRACE
99
ELASTIC_APM_LOG_LEVEL_SYSLOG=TRACE
1010
ELASTIC_APM_LOG_LEVEL_WIN_SYS_DEBUG=CRITICAL
11+
ELASTIC_APM_MAX_SEND_QUEUE_SIZE=123MB
1112
ELASTIC_APM_SECRET_TOKEN=non-default_secret_token_123
1213
ELASTIC_APM_SERVER_URL=https://non-default_server_url:4321/some/path
1314
ELASTIC_APM_SERVICE_NAME=Non-default Service Name
@@ -66,6 +67,13 @@ if (elasticApmIsOsWindows()) {
6667
elasticApmAssertSame("elastic_apm_get_config_option_by_name('log_level_win_sys_debug')", elastic_apm_get_config_option_by_name('log_level_win_sys_debug'), ELASTIC_APM_LOG_LEVEL_CRITICAL);
6768
}
6869

70+
//////////////////////////////////////////////
71+
/////////////// max_send_queue_size
72+
73+
elasticApmAssertSame("getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE')", getenv('ELASTIC_APM_MAX_SEND_QUEUE_SIZE'), '123MB');
74+
75+
elasticApmAssertSame("elastic_apm_get_config_option_by_name('max_send_queue_size')", elastic_apm_get_config_option_by_name('max_send_queue_size'), 123.0 * 1024 * 1024);
76+
6977
//////////////////////////////////////////////
7078
/////////////// secret_token
7179

0 commit comments

Comments
 (0)