Skip to content

Commit 928c254

Browse files
committed
out_splunk: reduce noise and fix hec_token handling (fix #8859)
The following patch perform 2 changes in the code that helps to fix the problems found with Splunk hec token handling: 1. In the recent PR #8793, when using the record accessor API flb_ra_translate_check() to validate if the hec_token field exists, leads to noisy log messages since that function warns the issue if the field is not found. Most of users are not using hec_token set by Splunk input plugin, so their logging gets noisy. This patch replaces that call with flb_ra_translate() which fixes the problem. 2. If hec_token was set in the record metadata, it was being store in the main context of the plugin, however the flush callbacks that formats and deliver the data runs in separate/parallel threads that could lead to a race condition if more than onen thread tries to manipulate the value. This patch adds protection to the context value so it becomes thread safe. Signed-off-by: Eduardo Silva <[email protected]>
1 parent 9100098 commit 928c254

File tree

3 files changed

+61
-15
lines changed

3 files changed

+61
-15
lines changed

plugins/out_splunk/splunk.c

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -354,12 +354,27 @@ static flb_sds_t extract_hec_token(struct flb_splunk *ctx, msgpack_object map,
354354

355355
/* Extract HEC token (map which is from metadata lookup) */
356356
if (ctx->metadata_auth_key) {
357-
hec_token = flb_ra_translate_check(ctx->ra_metadata_auth_key, tag, tag_len,
358-
map, NULL, FLB_TRUE);
359-
if (hec_token) {
357+
hec_token = flb_ra_translate(ctx->ra_metadata_auth_key, tag, tag_len,
358+
map, NULL);
359+
/*
360+
* record accessor translation can return an empty string buffer if the
361+
* translation was not successfull or the value was not found. We consider
362+
* a valid token any string which length is greater than 0.
363+
*
364+
* note: flb_ra_translate_check() is not used here because it will print
365+
* an error message if the translation fails:
366+
*
367+
* ref: https://github.com/fluent/fluent-bit/issues/8859
368+
*/
369+
if (hec_token && flb_sds_len(hec_token) > 0) {
360370
return hec_token;
361371
}
362372

373+
/* destroy empty string */
374+
if (hec_token) {
375+
flb_sds_destroy(hec_token);
376+
}
377+
363378
flb_plg_debug(ctx->ins, "Could not find hec_token in metadata");
364379
return NULL;
365380
}
@@ -368,21 +383,45 @@ static flb_sds_t extract_hec_token(struct flb_splunk *ctx, msgpack_object map,
368383
return NULL;
369384
}
370385

386+
static void set_metadata_auth_header(struct flb_splunk *ctx, flb_sds_t hec_token)
387+
{
388+
pthread_mutex_lock(&ctx->mutex_hec_token);
389+
390+
if (ctx->metadata_auth_header != NULL) {
391+
flb_sds_destroy(ctx->metadata_auth_header);
392+
}
393+
ctx->metadata_auth_header = hec_token;
394+
395+
pthread_mutex_unlock(&ctx->mutex_hec_token);
396+
}
397+
398+
static flb_sds_t get_metadata_auth_header(struct flb_splunk *ctx)
399+
{
400+
flb_sds_t auth_header = NULL;
401+
402+
pthread_mutex_lock(&ctx->mutex_hec_token);
403+
auth_header = flb_sds_create(ctx->metadata_auth_header);
404+
pthread_mutex_unlock(&ctx->mutex_hec_token);
405+
406+
return auth_header;
407+
}
408+
371409
static inline int splunk_format(const void *in_buf, size_t in_bytes,
372410
char *tag, int tag_len,
373411
char **out_buf, size_t *out_size,
374412
struct flb_splunk *ctx)
375413
{
376414
int ret;
415+
char *err;
377416
msgpack_object map;
378417
msgpack_object metadata;
379418
msgpack_sbuffer mp_sbuf;
380419
msgpack_packer mp_pck;
381-
char *err;
382420
flb_sds_t tmp;
383421
flb_sds_t record;
384422
flb_sds_t json_out;
385423
flb_sds_t metadata_hec_token = NULL;
424+
386425
struct flb_log_event_decoder log_decoder;
387426
struct flb_log_event log_event;
388427

@@ -403,8 +442,6 @@ static inline int splunk_format(const void *in_buf, size_t in_bytes,
403442
return -1;
404443
}
405444

406-
ctx->metadata_auth_header = NULL;
407-
408445
while ((ret = flb_log_event_decoder_next(
409446
&log_decoder,
410447
&log_event)) == FLB_EVENT_DECODER_SUCCESS) {
@@ -422,10 +459,7 @@ static inline int splunk_format(const void *in_buf, size_t in_bytes,
422459
* specify only one splunk token per one instance.
423460
* So, it should be valid if storing only last value of
424461
* splunk token per one chunk. */
425-
if (ctx->metadata_auth_header != NULL) {
426-
cfl_sds_destroy(ctx->metadata_auth_header);
427-
}
428-
ctx->metadata_auth_header = metadata_hec_token;
462+
set_metadata_auth_header(ctx, metadata_hec_token);
429463
}
430464

431465
if (ctx->event_key) {
@@ -598,6 +632,7 @@ static void cb_splunk_flush(struct flb_event_chunk *event_chunk,
598632
size_t payload_size;
599633
(void) i_ins;
600634
(void) config;
635+
flb_sds_t metadata_auth_header = NULL;
601636

602637
/* Get upstream connection */
603638
u_conn = flb_upstream_conn_get(ctx->u);
@@ -677,16 +712,19 @@ static void cb_splunk_flush(struct flb_event_chunk *event_chunk,
677712
flb_http_buffer_size(c, resp_size);
678713
}
679714

715+
metadata_auth_header = get_metadata_auth_header(ctx);
716+
680717
/* HTTP Client */
681718
flb_http_add_header(c, "User-Agent", 10, "Fluent-Bit", 10);
682719

683720
/* Try to use http_user and http_passwd if not, fallback to auth_header */
684721
if (ctx->http_user && ctx->http_passwd) {
685722
flb_http_basic_auth(c, ctx->http_user, ctx->http_passwd);
686723
}
687-
else if (ctx->metadata_auth_header) {
724+
else if (metadata_auth_header) {
688725
flb_http_add_header(c, "Authorization", 13,
689-
ctx->metadata_auth_header, flb_sds_len(ctx->metadata_auth_header));
726+
metadata_auth_header,
727+
flb_sds_len(metadata_auth_header));
690728
}
691729
else if (ctx->auth_header) {
692730
flb_http_add_header(c, "Authorization", 13,
@@ -754,10 +792,10 @@ static void cb_splunk_flush(struct flb_event_chunk *event_chunk,
754792
flb_sds_destroy(buf_data);
755793
}
756794

757-
/* Cleanup */
758-
if (ctx->metadata_auth_header != NULL) {
759-
cfl_sds_destroy(ctx->metadata_auth_header);
795+
if (metadata_auth_header) {
796+
flb_sds_destroy(metadata_auth_header);
760797
}
798+
761799
flb_http_client_destroy(c);
762800
flb_upstream_conn_release(u_conn);
763801
FLB_OUTPUT_RETURN(ret);

plugins/out_splunk/splunk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ struct flb_splunk {
120120

121121
/* Plugin instance */
122122
struct flb_output_instance *ins;
123+
124+
pthread_mutex_t mutex_hec_token;
123125
};
124126

125127
#endif

plugins/out_splunk/splunk_conf.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ struct flb_splunk *flb_splunk_conf_create(struct flb_output_instance *ins,
262262
}
263263
}
264264

265+
pthread_mutex_init(&ctx->mutex_hec_token, NULL);
266+
265267
/* Currently, Splunk HEC token is stored in a fixed key, hec_token. */
266268
ctx->metadata_auth_key = "$hec_token";
267269
if (ctx->metadata_auth_key) {
@@ -325,6 +327,10 @@ int flb_splunk_conf_destroy(struct flb_splunk *ctx)
325327
flb_ra_destroy(ctx->ra_metadata_auth_key);
326328
}
327329

330+
if (ctx->metadata_auth_header) {
331+
flb_sds_destroy(ctx->metadata_auth_header);
332+
}
333+
328334
event_fields_destroy(ctx);
329335

330336
flb_free(ctx);

0 commit comments

Comments
 (0)