-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
out_parseable: Plugin for sending logs to Parseable #9622
Closed
Closed
Changes from all commits
Commits
Show all changes
100 commits
Select commit
Hold shift + click to select a range
54041d2
bitbake: bump to v3.2.1
edsiper abe21b5
working http requests
AdheipSingh 7d24323
hacked code
AdheipSingh c5eba8e
add namespace_name filter
AdheipSingh 378393b
use stream dynamically
AdheipSingh 50a833e
update dockerfile
AdheipSingh b82245d
add debug
AdheipSingh c36f54c
add headers debug
AdheipSingh 0f9d637
add fix char size
AdheipSingh d271775
mutate body debug
AdheipSingh e7cfff0
add p_stream config and dynamic namespace action
AdheipSingh f0923c6
clean up log
AdheipSingh 43d2943
exclude namesapces support
AdheipSingh 733afb1
fix build
AdheipSingh a678706
remove example from cmakelists.txt
AdheipSingh 0d7f070
debug leak
AdheipSingh 4e7864d
release: update to 3.2.2 (#9610)
github-actions[bot] 718e714
signv4: added missing length calculation
leonardo-albertovich ee31a65
http_client: added missing exit path
leonardo-albertovich 070f7c8
http_common: added missing initializers
leonardo-albertovich 7d15c9e
out_opentelemetry: added missing result checks and fixed leaks
leonardo-albertovich 1eed94f
http_client: fixed potential memory corruption
leonardo-albertovich 1a6dd29
http_client: added missing exit path
leonardo-albertovich 2e1da5d
http_common: moved initializers to correct a bug introduced in PR 9608
leonardo-albertovich 81bc86a
ci: fixed script running tests to match requirements of test_flb_util…
mabrarov b16801e
in_forward: Plug a resource leak on exception (CID 508064)
cosmo0920 86a496b
node_exporter_metrics: Use real_path for complaining on glob error
cosmo0920 5b00e18
plugin: Plug a use-after-free issue (CID 514582)
cosmo0920 9d3f158
build: made FLB_DEV detectable from code
leonardo-albertovich 5393e1f
tls: openssl: added support for SSLKEYLOGFILE on DEV builds
leonardo-albertovich 3e34356
out_opentelemetry: decoupled HTTP/2 and gRPC
leonardo-albertovich e00931c
http_client: added per client temporary buffer
leonardo-albertovich d430d56
http_client_http2: improved protocol compliance
leonardo-albertovich cbad521
http_common: added guards to prevent leaks
leonardo-albertovich 1890898
http_client: added per session temporary buffer
leonardo-albertovich ab27ba5
http_client_http2: added missing header
leonardo-albertovich 4491bce
http_common: added pre-generated authority field
leonardo-albertovich 37a1912
out_azure_kusto : fix multiple files tail issue and timeout issue (#8…
tanmaya-panda1 eec1b70
in_opentelemetry: Propogate tag in http2 metrics and trace handlers
nuclearpidgeon d62ca38
processor_labels: Process operations for output purposed contexts of …
cosmo0920 b483230
filter_lua: expose env variables in FLB_ENV Lua table
edsiper a95e92a
custom_calyptia: added interval handling and tests
6ecb32f
in_calyptia_fleet: improved interval handling
0e75a94
out_stackdriver bug fix: return cached token when current_timestamp i…
shuaich 1a7aa21
http_client: Implement response testing framework
cosmo0920 4bbd07d
output: Add a capability to inject HTTP response testing environment
cosmo0920 b5ed7fa
lib: Implement injecting HTTP response mechanism
cosmo0920 ce227ca
out_es: tests: Add HTTP response testing
cosmo0920 17e308c
in_http: use 'tag_key' option when json array is received
imankurpatel000 fd27cd9
network: Update struct type for sock_addr
jomillerOpen 59dd67b
network: Update struct type being passed into accept
jomillerOpen 2adc537
release: update to 3.2.3 (#9665)
github-actions[bot] 97102e5
out_calyptia: retry agent registration on flush callback (#9656)
niedbalski 250b3ec
build: cmake: fix UNICODE-escaped characters on aarch64 (#8851)
RamaMalladiAWS 9efde0a
filter_parser: fix reserve data and preserve key handling (#9675)
niedbalski c713bda
out_prometheus_remote_write: Fix a typo (#9674)
baonq-me 6bbb7b4
wasm: Plug a resource leak on exception (CID 508177) (#9615)
cosmo0920 2d34b29
update exclude namespace logic
AdheipSingh 8b96eb3
update debug
AdheipSingh cc8fb1c
fix cm
AdheipSingh b90cbb6
debug inline check
AdheipSingh ee60adc
debug exclude
AdheipSingh faa0cf7
add debug statements
AdheipSingh e95413d
print config
AdheipSingh 7facebb
add debug to exclude namespaces list
AdheipSingh 1ed552d
debug exclude namespaces
AdheipSingh e3d11b1
update logic
AdheipSingh b998276
debug print out comparison
AdheipSingh 4c69573
revert debug change
AdheipSingh e92898f
Merge branch 'fluent:master' into master
AdheipSingh ecacc1d
remove P_ in config
AdheipSingh 84dda2f
Merge branch 'master' of github.com:AdheipSingh/fluent-bit
AdheipSingh 648e878
revert prof_info changes
AdheipSingh 30a7432
remove fluent-bit tgz
AdheipSingh f13ab68
debug port and server hostname
AdheipSingh 9c1725b
add debug ctx
AdheipSingh 2018767
hardcode port
AdheipSingh 98ed0a5
revert debug
AdheipSingh 2c9ba03
debug ports
AdheipSingh a7c5961
tweak configurations
AdheipSingh 6d1f0a2
Merge branch 'master' into master
AdheipSingh 8911f8a
review changes
AdheipSingh e1f8d91
fixes to build
AdheipSingh ff621b1
comment out unsupported log event
AdheipSingh 8fff3c4
update decoder
AdheipSingh ad25cf3
update ra
AdheipSingh b8fef4f
update record accessor and null checks
AdheipSingh 31b983e
update records
AdheipSingh cd81d6b
update records
AdheipSingh a1824d6
update records
AdheipSingh 0a75176
address comments
AdheipSingh 2e500ed
update
AdheipSingh b73c8cb
update
AdheipSingh e6f0aec
update
AdheipSingh 23e4245
update
AdheipSingh c872912
update
AdheipSingh fb0875b
Merge pull request #1 from AdheipSingh/review
AdheipSingh 83b6ef1
update
AdheipSingh 34fb8ca
update
AdheipSingh 3d1c021
Merge branch 'fluent:master' into master
AdheipSingh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
set(src | ||
parseable.c) | ||
|
||
FLB_PLUGIN(out_parseable "${src}" "") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,350 @@ | ||
#include <fluent-bit/flb_output_plugin.h> | ||
#include <fluent-bit/flb_utils.h> | ||
#include <fluent-bit/flb_slist.h> | ||
#include <fluent-bit/flb_time.h> | ||
#include <fluent-bit/flb_pack.h> | ||
#include <fluent-bit/flb_config_map.h> | ||
#include <fluent-bit/flb_metrics.h> | ||
#include <fluent-bit/flb_log_event_decoder.h> | ||
#include <fluent-bit/flb_event.h> | ||
#include <fluent-bit/flb_record_accessor.h> | ||
|
||
|
||
#include "parseable.h" | ||
|
||
static int cb_parseable_init(struct flb_output_instance *ins, | ||
struct flb_config *config, void *data) | ||
{ | ||
int ret; | ||
struct flb_out_parseable *ctx = NULL; | ||
(void) ins; | ||
(void) config; | ||
(void) data; | ||
|
||
ctx = flb_calloc(1, sizeof(struct flb_out_parseable)); | ||
if (!ctx) { | ||
flb_errno(); | ||
return -1; | ||
} | ||
ctx->ins = ins; | ||
|
||
/* Read in config values */ | ||
ret = flb_output_config_map_set(ins, (void *) ctx); | ||
if (ret == -1) { | ||
flb_free(ctx); | ||
return -1; | ||
} | ||
|
||
flb_plg_info(ctx->ins, "Configured port: %d", ctx->server_port); | ||
|
||
ctx->upstream = flb_upstream_create(config, | ||
ctx->server_host, | ||
ctx->server_port, | ||
FLB_IO_TCP, | ||
NULL); | ||
|
||
if (!ctx->upstream) { | ||
flb_free(ctx); | ||
return -1; | ||
} | ||
|
||
/* Export context */ | ||
flb_output_set_context(ins, ctx); | ||
|
||
return 0; | ||
} | ||
|
||
/* Main flush callback */ | ||
static void cb_parseable_flush(struct flb_event_chunk *event_chunk, | ||
struct flb_output_flush *out_flush, | ||
struct flb_input_instance *i_ins, | ||
void *out_context, | ||
struct flb_config *config) | ||
{ | ||
struct flb_out_parseable *ctx = out_context; | ||
struct flb_log_event_decoder log_decoder; | ||
struct flb_log_event log_event; | ||
struct flb_record_accessor *ra = NULL; | ||
struct flb_record_accessor *ns_ra = NULL; // For checking namespace | ||
(void) config; | ||
struct flb_http_client *client; | ||
struct flb_connection *u_conn; | ||
flb_sds_t body; | ||
flb_sds_t x_p_stream_value = NULL; | ||
int ret; | ||
int i; | ||
size_t b_sent; | ||
msgpack_sbuffer sbuf; | ||
msgpack_packer pk; | ||
|
||
/* Initialize event decoder */ | ||
flb_plg_info(ctx->ins, "Initializing event decoder..."); | ||
ret = flb_log_event_decoder_init(&log_decoder, (char *) event_chunk->data, event_chunk->size); | ||
if (ret != FLB_EVENT_DECODER_SUCCESS) { | ||
flb_plg_error(ctx->ins, "Failed to initialize event decoder"); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
|
||
/* Create record accessor if stream is set to $NAMESPACE */ | ||
if (ctx->stream && strcmp(ctx->stream, "$NAMESPACE") == 0) { | ||
ra = flb_ra_create("$kubernetes['namespace_name']", FLB_TRUE); | ||
if (!ra) { | ||
flb_plg_error(ctx->ins, "Failed to create record accessor"); | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
} | ||
|
||
/* Create record accessor for namespace exclusion check */ | ||
if (ctx->exclude_namespaces) { | ||
ns_ra = flb_ra_create("$kubernetes['namespace_name']", FLB_TRUE); | ||
if (!ns_ra) { | ||
flb_plg_error(ctx->ins, "Failed to create namespace record accessor"); | ||
if (ra) { | ||
flb_ra_destroy(ra); | ||
} | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
} | ||
|
||
/* Process each event */ | ||
flb_plg_info(ctx->ins, "Processing events..."); | ||
while (flb_log_event_decoder_next(&log_decoder, &log_event) == FLB_EVENT_DECODER_SUCCESS) { | ||
/* Check if namespace is in exclusion list */ | ||
if (ns_ra && ctx->exclude_namespaces) { | ||
flb_sds_t current_ns = flb_ra_translate(ns_ra, NULL, -1, *log_event.body, NULL); | ||
if (current_ns) { | ||
struct cfl_list *head; | ||
struct flb_slist_entry *entry; | ||
int skip = 0; | ||
|
||
cfl_list_foreach(head, ctx->exclude_namespaces) { | ||
entry = cfl_list_entry(head, struct flb_slist_entry, _head); | ||
if (strcmp(current_ns, entry->str) == 0) { | ||
flb_plg_debug(ctx->ins, "Skipping excluded namespace: %s", current_ns); | ||
skip = 1; | ||
break; | ||
} | ||
} | ||
|
||
flb_sds_destroy(current_ns); | ||
if (skip) { | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
/* Initialize the packer and buffer */ | ||
msgpack_sbuffer_init(&sbuf); | ||
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); | ||
|
||
/* Pack the map with one additional field */ | ||
msgpack_pack_map(&pk, log_event.body->via.map.size + 1); | ||
|
||
/* Pack original map content */ | ||
for (i = 0; i < log_event.body->via.map.size; i++) { | ||
msgpack_pack_object(&pk, log_event.body->via.map.ptr[i].key); | ||
msgpack_pack_object(&pk, log_event.body->via.map.ptr[i].val); | ||
} | ||
|
||
/* Add source field */ | ||
msgpack_pack_str_with_body(&pk, "source", 6); | ||
msgpack_pack_str_with_body(&pk, "fluent bit parseable plugin", 25); | ||
|
||
/* Convert to JSON */ | ||
body = flb_msgpack_raw_to_json_sds(sbuf.data, sbuf.size); | ||
if (!body) { | ||
flb_plg_error(ctx->ins, "Failed to convert msgpack to JSON"); | ||
msgpack_sbuffer_destroy(&sbuf); | ||
if (ra) { | ||
flb_ra_destroy(ra); | ||
} | ||
if (ns_ra) { | ||
flb_ra_destroy(ns_ra); | ||
} | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
|
||
/* Determine X-P-Stream value */ | ||
if (ra) { | ||
/* Use record accessor to get namespace_name */ | ||
flb_sds_t ns = flb_ra_translate(ra, NULL, -1, *log_event.body, NULL); | ||
if (!ns) { | ||
flb_plg_error(ctx->ins, "Failed to extract namespace_name using record accessor"); | ||
flb_sds_destroy(body); | ||
msgpack_sbuffer_destroy(&sbuf); | ||
flb_ra_destroy(ra); | ||
if (ns_ra) { | ||
flb_ra_destroy(ns_ra); | ||
} | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
x_p_stream_value = ns; | ||
} | ||
else if (ctx->stream) { | ||
x_p_stream_value = flb_sds_create(ctx->stream); | ||
if (!x_p_stream_value) { | ||
flb_plg_error(ctx->ins, "Failed to set X-P-Stream header"); | ||
flb_sds_destroy(body); | ||
msgpack_sbuffer_destroy(&sbuf); | ||
if (ra) { | ||
flb_ra_destroy(ra); | ||
} | ||
if (ns_ra) { | ||
flb_ra_destroy(ns_ra); | ||
} | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
} | ||
else { | ||
flb_plg_error(ctx->ins, "Stream is not set"); | ||
flb_sds_destroy(body); | ||
msgpack_sbuffer_destroy(&sbuf); | ||
if (ra) { | ||
flb_ra_destroy(ra); | ||
} | ||
if (ns_ra) { | ||
flb_ra_destroy(ns_ra); | ||
} | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
|
||
/* Get upstream connection */ | ||
u_conn = flb_upstream_conn_get(ctx->upstream); | ||
if (!u_conn) { | ||
flb_plg_error(ctx->ins, "Connection initialization error"); | ||
flb_sds_destroy(body); | ||
flb_sds_destroy(x_p_stream_value); | ||
msgpack_sbuffer_destroy(&sbuf); | ||
if (ra) { | ||
flb_ra_destroy(ra); | ||
} | ||
if (ns_ra) { | ||
flb_ra_destroy(ns_ra); | ||
} | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
|
||
/* Create HTTP client */ | ||
client = flb_http_client(u_conn, | ||
FLB_HTTP_POST, "/api/v1/ingest", | ||
body, flb_sds_len(body), | ||
ctx->server_host, ctx->server_port, | ||
NULL, 0); | ||
if (!client) { | ||
flb_plg_error(ctx->ins, "Could not create HTTP client"); | ||
flb_sds_destroy(body); | ||
flb_sds_destroy(x_p_stream_value); | ||
msgpack_sbuffer_destroy(&sbuf); | ||
flb_upstream_conn_release(u_conn); | ||
if (ra) { | ||
flb_ra_destroy(ra); | ||
} | ||
if (ns_ra) { | ||
flb_ra_destroy(ns_ra); | ||
} | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_ERROR); | ||
} | ||
|
||
/* Set headers */ | ||
flb_http_add_header(client, "Content-Type", 12, "application/json", 16); | ||
flb_http_add_header(client, "X-P-Stream", 10, x_p_stream_value, flb_sds_len(x_p_stream_value)); | ||
flb_http_basic_auth(client, ctx->username, ctx->password); | ||
|
||
/* Perform request */ | ||
ret = flb_http_do(client, &b_sent); | ||
flb_plg_info(ctx->ins, "HTTP request sent. Status=%i", client->resp.status); | ||
|
||
/* Clean up resources for this iteration */ | ||
flb_sds_destroy(body); | ||
flb_sds_destroy(x_p_stream_value); | ||
flb_http_client_destroy(client); | ||
flb_upstream_conn_release(u_conn); | ||
msgpack_sbuffer_destroy(&sbuf); | ||
} | ||
|
||
/* Final cleanup */ | ||
if (ra) { | ||
flb_ra_destroy(ra); | ||
} | ||
if (ns_ra) { | ||
flb_ra_destroy(ns_ra); | ||
} | ||
flb_log_event_decoder_destroy(&log_decoder); | ||
FLB_OUTPUT_RETURN(FLB_OK); | ||
} | ||
|
||
static int cb_parseable_exit(void *data, struct flb_config *config) | ||
{ | ||
struct flb_out_parseable *ctx = data; | ||
|
||
if (!ctx) { | ||
return 0; | ||
} | ||
|
||
if (ctx->exclude_namespaces) { | ||
flb_slist_destroy((struct mk_list *)ctx->exclude_namespaces); | ||
} | ||
|
||
/* Free up resources */ | ||
if (ctx->upstream) { | ||
flb_upstream_destroy(ctx->upstream); | ||
} | ||
flb_free(ctx); | ||
return 0; | ||
} | ||
|
||
/* Configuration properties map */ | ||
static struct flb_config_map config_map[] = { | ||
{ | ||
FLB_CONFIG_MAP_STR, "server_host", NULL, | ||
0, FLB_TRUE, offsetof(struct flb_out_parseable, server_host), | ||
"The host of the server to send logs to." | ||
}, | ||
{ | ||
FLB_CONFIG_MAP_STR, "username", NULL, | ||
0, FLB_TRUE, offsetof(struct flb_out_parseable, username), | ||
"The parseable server username." | ||
}, | ||
{ | ||
FLB_CONFIG_MAP_STR, "password", NULL, | ||
0, FLB_TRUE, offsetof(struct flb_out_parseable, password), | ||
"The parseable server password." | ||
}, | ||
{ | ||
FLB_CONFIG_MAP_STR, "stream", NULL, | ||
0, FLB_TRUE, offsetof(struct flb_out_parseable, stream), | ||
"The stream name to send logs to. Using $NAMESPACE will dynamically create a namespace." | ||
}, | ||
{ | ||
FLB_CONFIG_MAP_INT, "server_port", NULL, | ||
0, FLB_TRUE, offsetof(struct flb_out_parseable, server_port), | ||
"The port on the host to send logs to." | ||
}, | ||
{ | ||
FLB_CONFIG_MAP_CLIST, "Exclude_Namespaces", NULL, | ||
0, FLB_TRUE, offsetof(struct flb_out_parseable, exclude_namespaces), | ||
"A space-separated list of Kubernetes namespaces to exclude from log forwarding." | ||
}, | ||
/* EOF */ | ||
{0} | ||
}; | ||
|
||
/* Plugin registration */ | ||
struct flb_output_plugin out_parseable_plugin = { | ||
.name = "parseable", | ||
.description = "Sends events to a HTTP server", | ||
.cb_init = cb_parseable_init, | ||
.cb_flush = cb_parseable_flush, | ||
.cb_exit = cb_parseable_exit, | ||
.flags = 0, | ||
.event_type = FLB_OUTPUT_LOGS, | ||
.config_map = config_map | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#ifndef FLB_OUT_PARSEABLE_H | ||
#define FLB_OUT_PARSEABLE_H | ||
|
||
#include <fluent-bit/flb_output_plugin.h> | ||
#include <fluent-bit/flb_sds.h> | ||
|
||
struct flb_out_parseable { | ||
flb_sds_t server_host; | ||
int server_port; | ||
flb_sds_t username; | ||
flb_sds_t password; | ||
flb_sds_t stream; | ||
struct cfl_list *exclude_namespaces; // Use mk_list for namespace exclusion | ||
struct flb_upstream *upstream; | ||
struct flb_output_instance *ins; | ||
}; | ||
|
||
#endif |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this what should be used in the cmake config? It's already defaulting to on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feel free to suggest the best practice here. I tried to build without it but was not able to run the plugin.