Skip to content

Commit f849c79

Browse files
committed
out_opentelemetry: add configurable log scope limits
Before this patch we had a hard-coded maximum of 100 log scopes per resource. The change in question introduces a new configurable option called 'logs_max_scopes' to control the maximum limit, the default value is: 0 (unlimited). Signed-off-by: Eduardo Silva <[email protected]>
1 parent 7fcec9d commit f849c79

File tree

4 files changed

+101
-10
lines changed

4 files changed

+101
-10
lines changed

plugins/out_opentelemetry/opentelemetry.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,12 @@ static struct flb_config_map config_map[] = {
975975
"Set the maximum number of OTLP log resources per export request (0 disables the limit; default: 0)"
976976
},
977977

978+
{
979+
FLB_CONFIG_MAP_INT, "logs_max_scopes", DEFAULT_MAX_SCOPE_EXPORT,
980+
0, FLB_TRUE, offsetof(struct opentelemetry_context, max_scopes),
981+
"Set the maximum number of OTLP log scopes per resource (0 disables the limit; default: 0)"
982+
},
983+
978984
{
979985
FLB_CONFIG_MAP_STR, "logs_uri", "/v1/logs",
980986
0, FLB_TRUE, offsetof(struct opentelemetry_context, logs_uri),

plugins/out_opentelemetry/opentelemetry.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
*/
4343
#define DEFAULT_LOG_RECORD_BATCH_SIZE "1000"
4444
#define DEFAULT_MAX_RESOURCE_EXPORT "0" /* no resource limits */
45+
#define DEFAULT_MAX_SCOPE_EXPORT "0" /* no scope limits */
4546

4647
struct opentelemetry_body_key {
4748
flb_sds_t key;
@@ -143,6 +144,9 @@ struct opentelemetry_context {
143144
/* Maximum number of resources per OTLP export */
144145
int max_resources;
145146

147+
/* Maximum number of scopes per OTLP resource */
148+
int max_scopes;
149+
146150
/* Log the response payload */
147151
int log_response_payload;
148152

plugins/out_opentelemetry/opentelemetry_conf.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,12 @@ struct opentelemetry_context *flb_opentelemetry_context_create(struct flb_output
285285
return NULL;
286286
}
287287

288+
if (ctx->max_scopes < 0) {
289+
flb_plg_error(ins, "max_scopes must be greater than or equal to zero");
290+
flb_opentelemetry_context_destroy(ctx);
291+
return NULL;
292+
}
293+
288294
/* Parse 'add_label' */
289295
ret = config_add_labels(ins, ctx);
290296
if (ret == -1) {

plugins/out_opentelemetry/opentelemetry_logs.c

Lines changed: 85 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "opentelemetry_utils.h"
3535

3636
#define RESOURCE_LOGS_INITIAL_CAPACITY 256
37+
#define SCOPE_LOGS_INITIAL_CAPACITY 100
3738

3839
static int hex_to_int(char ch)
3940
{
@@ -947,12 +948,15 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
947948
int ret;
948949
int record_type;
949950
int log_record_count;
950-
int max_scopes;
951+
int max_scopes_limit;
951952
int max_resources;
952953
int native_otel = FLB_FALSE;
953954
size_t resource_logs_capacity;
954955
size_t i;
955956
size_t new_capacity;
957+
size_t resource_index = 0;
958+
size_t scope_capacity = 0;
959+
size_t new_scope_capacity = 0;
956960
int64_t resource_id = -1;
957961
int64_t scope_id = -1;
958962
int64_t tmp_resource_id = -1;
@@ -966,9 +970,12 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
966970
Opentelemetry__Proto__Logs__V1__ResourceLogs **tmp_resource_logs = NULL;
967971
Opentelemetry__Proto__Logs__V1__ResourceLogs *resource_log = NULL;
968972
Opentelemetry__Proto__Logs__V1__ScopeLogs **scope_logs = NULL;
973+
Opentelemetry__Proto__Logs__V1__ScopeLogs **tmp_scope_logs = NULL;
969974
Opentelemetry__Proto__Logs__V1__ScopeLogs *scope_log = NULL;
970975
Opentelemetry__Proto__Logs__V1__LogRecord **log_records = NULL;
971976
Opentelemetry__Proto__Logs__V1__LogRecord *log_record = NULL;
977+
size_t *resource_scope_capacities = NULL;
978+
size_t *tmp_scope_capacities = NULL;
972979

973980
ctx = (struct opentelemetry_context *) out_context;
974981

@@ -985,7 +992,7 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
985992

986993
/* local limits */
987994
max_resources = ctx->max_resources; /* maximum number of resources */
988-
max_scopes = 100; /* maximum number of scopes per resource */
995+
max_scopes_limit = ctx->max_scopes; /* maximum number of scopes per resource */
989996

990997
if (max_resources > 0) {
991998
resource_logs_capacity = max_resources;
@@ -1002,6 +1009,13 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
10021009
flb_log_event_decoder_destroy(decoder);
10031010
return -1;
10041011
}
1012+
resource_scope_capacities = flb_calloc(resource_logs_capacity, sizeof(size_t));
1013+
if (!resource_scope_capacities) {
1014+
flb_errno();
1015+
flb_free(resource_logs);
1016+
flb_log_event_decoder_destroy(decoder);
1017+
return -1;
1018+
}
10051019
export_logs.resource_logs = resource_logs;
10061020
export_logs.n_resource_logs = 0;
10071021

@@ -1062,15 +1076,25 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
10621076
ret = FLB_RETRY;
10631077
break;
10641078
}
1065-
10661079
resource_logs = tmp_resource_logs;
1080+
export_logs.resource_logs = resource_logs;
1081+
1082+
tmp_scope_capacities = flb_realloc(resource_scope_capacities,
1083+
new_capacity * sizeof(size_t));
1084+
if (!tmp_scope_capacities) {
1085+
flb_errno();
1086+
ret = FLB_RETRY;
1087+
break;
1088+
}
1089+
1090+
resource_scope_capacities = tmp_scope_capacities;
10671091

10681092
for (i = resource_logs_capacity; i < new_capacity; i++) {
10691093
resource_logs[i] = NULL;
1094+
resource_scope_capacities[i] = 0;
10701095
}
10711096

10721097
resource_logs_capacity = new_capacity;
1073-
export_logs.resource_logs = resource_logs;
10741098
}
10751099

10761100
start_resource:
@@ -1090,6 +1114,8 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
10901114
resource_logs[export_logs.n_resource_logs] = resource_log;
10911115
export_logs.n_resource_logs++;
10921116

1117+
resource_index = export_logs.n_resource_logs - 1;
1118+
10931119
resource_log->resource = flb_calloc(1, sizeof(Opentelemetry__Proto__Resource__V1__Resource));
10941120
if (!resource_log->resource) {
10951121
flb_errno();
@@ -1107,7 +1133,17 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
11071133

11081134
/* prepare the scopes */
11091135
if (!resource_log->scope_logs) {
1110-
scope_logs = flb_calloc(100, sizeof(Opentelemetry__Proto__Logs__V1__ScopeLogs *));
1136+
if (max_scopes_limit > 0) {
1137+
scope_capacity = (size_t) max_scopes_limit;
1138+
}
1139+
else {
1140+
scope_capacity = resource_scope_capacities[resource_index];
1141+
if (scope_capacity == 0) {
1142+
scope_capacity = SCOPE_LOGS_INITIAL_CAPACITY;
1143+
}
1144+
}
1145+
1146+
scope_logs = flb_calloc(scope_capacity, sizeof(Opentelemetry__Proto__Logs__V1__ScopeLogs *));
11111147
if (!scope_logs) {
11121148
flb_errno();
11131149
ret = FLB_RETRY;
@@ -1116,6 +1152,7 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
11161152

11171153
resource_log->scope_logs = scope_logs;
11181154
resource_log->n_scope_logs = 0;
1155+
resource_scope_capacities[resource_index] = scope_capacity;
11191156
}
11201157

11211158
/* update the current resource_id and reset scope_id */
@@ -1124,11 +1161,46 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
11241161
}
11251162

11261163
if (scope_id != tmp_scope_id) {
1164+
resource_index = export_logs.n_resource_logs - 1;
1165+
11271166
/* check limits */
1128-
if (resource_log->n_scope_logs >= max_scopes) {
1129-
flb_plg_error(ctx->ins, "max scopes limit reached");
1130-
ret = FLB_ERROR;
1131-
break;
1167+
if (max_scopes_limit > 0) {
1168+
if (resource_log->n_scope_logs >= max_scopes_limit) {
1169+
flb_plg_error(ctx->ins, "max scopes limit reached");
1170+
ret = FLB_ERROR;
1171+
break;
1172+
}
1173+
}
1174+
else {
1175+
if (resource_log->n_scope_logs >= resource_scope_capacities[resource_index]) {
1176+
new_scope_capacity = resource_scope_capacities[resource_index] * 2;
1177+
1178+
if (new_scope_capacity <= resource_scope_capacities[resource_index]) {
1179+
flb_plg_error(ctx->ins, "scope logs capacity overflow");
1180+
ret = FLB_ERROR;
1181+
break;
1182+
}
1183+
1184+
if (new_scope_capacity < SCOPE_LOGS_INITIAL_CAPACITY) {
1185+
new_scope_capacity = SCOPE_LOGS_INITIAL_CAPACITY;
1186+
}
1187+
1188+
tmp_scope_logs = flb_realloc(resource_log->scope_logs,
1189+
new_scope_capacity * sizeof(Opentelemetry__Proto__Logs__V1__ScopeLogs *));
1190+
if (!tmp_scope_logs) {
1191+
flb_errno();
1192+
ret = FLB_RETRY;
1193+
break;
1194+
}
1195+
1196+
for (i = resource_scope_capacities[resource_index];
1197+
i < new_scope_capacity; i++) {
1198+
tmp_scope_logs[i] = NULL;
1199+
}
1200+
1201+
resource_log->scope_logs = tmp_scope_logs;
1202+
resource_scope_capacities[resource_index] = new_scope_capacity;
1203+
}
11321204
}
11331205

11341206
/* process the scope */
@@ -1155,7 +1227,8 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
11551227
flb_errno();
11561228
flb_free(scope_log->scope);
11571229
flb_free(scope_log);
1158-
return -2;
1230+
ret = FLB_RETRY;
1231+
break;
11591232
}
11601233
log_record_count = 0;
11611234

@@ -1274,5 +1347,7 @@ int otel_process_logs(struct flb_event_chunk *event_chunk,
12741347

12751348
/* release all protobuf resources */
12761349
free_resource_logs(export_logs.resource_logs, export_logs.n_resource_logs);
1350+
flb_free(resource_scope_capacities);
1351+
12771352
return ret;
12781353
}

0 commit comments

Comments
 (0)