3434#include "opentelemetry_utils.h"
3535
3636#define RESOURCE_LOGS_INITIAL_CAPACITY 256
37+ #define SCOPE_LOGS_INITIAL_CAPACITY 100
3738
3839static 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
10761100start_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