Skip to content

es_out: support Upstream Servers with configuration overriding #7608

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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

mabrarov
Copy link
Contributor

@mabrarov mabrarov commented Jun 25, 2023

Implementation of Upstream feature for the Elasticsearch output plugin.

This pull request is based on pull request #1560 and Forward output plugin.

It was tested in a local setup with:

  1. Fluent Bit without Upstream feature connected to a single node of Elasticsearch cluster consisting of 3 master-eligible/data and 1 coordinating nodes.

    Refer to elastic-cluster directory of mabrarov/elastic-stack repository for Docker Compose project used to create target Elasticsearch cluster and Kibana.

    fluent-bit.conf Fluent Bit configuration file used for the test - refer to fluent-bit-es/fluent-bit.conf and (same in YAML format) fluent-bit-es/fluent-bit.yaml in mabrarov/elastic-stack repository.

    Debug log is available at flb_es.log.

  2. Fluent Bit with Upstream feature connected to all Elasticsearch data nodes of Elasticsearch cluster consisting of 3 master-eligible/data and 1 coordinating nodes.

    Refer to elastic-cluster directory of mabrarov/elastic-stack repository for Docker Compose project used to create target Elasticsearch cluster and Kibana.

    fluent-bit.conf Fluent Bit configuration file used for the test - refer to fluent-bit-es-cluster/fluent-bit.conf and (same in YAML format) fluent-bit-es-cluster/fluent-bit.yaml in mabrarov/elastic-stack repository.

    Debug log is available at flb_es_upstream.log.

Testing

  • Example configuration files for the change can be found in mabrarov/elastic-stack repository under fluent-bit-es-cluster directory.
  • Debug log output from testing the change - see above.
  • Attached Valgrind output that shows no leaks or memory corruption was found - refer to flb_run_code_analysis.log for the output of command
    TEST_PRESET=valgrind SKIP_TESTS='flb-rt-out_td flb-it-network' ./run_code_analysis.sh
  • [N/A] Run local packaging test showing all targets (including any new ones) build.
  • [N/A] Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

Backporting

  • [N/A] Backport to latest stable release.

Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

@mabrarov
Copy link
Contributor Author

Hi reviewers,

Is it possible to approve only workflow for this pull request, so that automated checks and build can start?

Thank you.

@mabrarov mabrarov temporarily deployed to pr June 28, 2023 17:55 — with GitHub Actions Inactive
@mabrarov mabrarov temporarily deployed to pr June 28, 2023 17:55 — with GitHub Actions Inactive
@mabrarov mabrarov temporarily deployed to pr June 28, 2023 17:55 — with GitHub Actions Inactive
@PettitWesley
Copy link
Contributor

@mabrarov sure

@mabrarov mabrarov temporarily deployed to pr June 28, 2023 18:22 — with GitHub Actions Inactive
@mabrarov
Copy link
Contributor Author

mabrarov commented Jun 29, 2023

Hi @PettitWesley,

It looks like all failed checks are around run-macos-unit-tests jobs and caused by the following failed unit tests:

  1. flb-rt-in_event_test
  2. flb-rt-out_tcp

I feel like other pull requests have the same issues, i.e. it doesn't seem that the failed checks are caused by this pull request changes.

Help of maintainers is appreciated.

Thank you.

@mabrarov mabrarov force-pushed the feature/out_es_upstream_support_extended branch from ba3382a to b7cd81b Compare July 8, 2023 10:22
@mabrarov
Copy link
Contributor Author

Hi @PettitWesley,

Is it possible to trigger automated workflow (build) for this pull request one more time? I found & fixed one issue and added tests for the new code since last build happened.

Thank you.

@mabrarov mabrarov temporarily deployed to pr July 10, 2023 12:05 — with GitHub Actions Inactive
@mabrarov mabrarov temporarily deployed to pr July 10, 2023 12:05 — with GitHub Actions Inactive
@mabrarov mabrarov temporarily deployed to pr July 10, 2023 12:05 — with GitHub Actions Inactive
@mabrarov mabrarov temporarily deployed to pr July 10, 2023 12:28 — with GitHub Actions Inactive
@mabrarov
Copy link
Contributor Author

Hi dear reviewers,

Is it possible to get this pull request reviewed / accepted sooner? Is there something pending / waiting from my side to start review?

Thank you.

@mabrarov mabrarov force-pushed the feature/out_es_upstream_support_extended branch from b7cd81b to b81d3f7 Compare July 20, 2023 19:38
@mabrarov
Copy link
Contributor Author

Hi @PettitWesley and @edsiper,

It feels like you are code owners for Elasticsearch output plugin. Is there something pending / waiting from my side to start review of this pull request? This new feature was requested 4 years ago and I feel it is something which multiple users of Fluent Bit (not just my team) would like to have.

Thank you.

@mabrarov mabrarov force-pushed the feature/out_es_upstream_support_extended branch from b81d3f7 to f6431c2 Compare September 30, 2023 13:32
Copy link
Contributor

@cosmo0920 cosmo0920 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to use slightly different approach for achieving this.

This is because own_* flags are frequently appeared in this PR.
So, we wanted to wrap them with the following struct like:

/* A wrapper for flb_sds_t that tracks memory ownership */
typedef struct {
    flb_sds_t sds;   /* The actual string data */
    int       owned; /* A flag indicating if this struct owns the memory */
} flb_es_sds_t;

Then, the wrapped members could be:

/* In es.h, struct flb_elasticsearch_config */
struct flb_elasticsearch_config {
    /* ... other properties ... */

    flb_es_sds_t index;
    flb_es_sds_t type;
    flb_es_sds_t http_user;
    flb_es_sds_t logstash_prefix;
    flb_es_sds_t time_key;

    /* ... etc ... */
};

For just initialization, it could be:

static inline void es_sds_init(flb_es_sds_t *dest, flb_es_sds_t *src)
{
    dest->sds = src->sds;
    dest->owned = FLB_FALSE; /* The new struct does not own the shared memory */
}

For setting up a value, it could be:

static inline int es_sds_set(flb_es_sds_t *wrapper, const char *value)
{
    /* If we previously owned a different string, free it first */
    if (wrapper->owned && wrapper->sds) {
        flb_sds_destroy(wrapper->sds);
    }

    wrapper->sds = flb_sds_create(value);
    if (!wrapper->sds) {
        return -1;
    }
    wrapper->owned = FLB_TRUE;
    return 0;
}

The teardown operation of these values could be:

static inline void es_sds_destroy(flb_es_sds_t *wrapper)
{
    if (wrapper->owned && wrapper->sds) {
        flb_sds_destroy(wrapper->sds);
    }
    wrapper->sds = NULL;
    wrapper->owned = FLB_FALSE;
}

Then, just teardown operation could be:

es_sds_destroy(&ec->index);
es_sds_destroy(&ec->type);
/* ... etc ... */

These changes could be cleaner way to handle shallow copy.
We would love to use this type of wrapper to encapsulate for these type of complex operations.

@mabrarov
Copy link
Contributor Author

mabrarov commented Jul 29, 2025

Hi @cosmo0920,

Regarding:

We might want to use slightly different approach for achieving this.

This is because own_* flags are frequently appeared in this PR. So, we wanted to wrap them with the following struct like:

/* A wrapper for flb_sds_t that tracks memory ownership */
typedef struct {
    flb_sds_t sds;   /* The actual string data */
    int       owned; /* A flag indicating if this struct owns the memory */
} flb_es_sds_t;

I like this approach, but there might be not just flb_sds_t type which will be wrapped (I'm looking at elasticsearch_config_destroy function in plugins/out_es/es_conf.c) if we decide to use this approach (C does not have C++ templates 😄). Let me check and try during this week.

Thank you.

@cosmo0920
Copy link
Contributor

cosmo0920 commented Jul 29, 2025

Regarding:

We might want to use slightly different approach for achieving this.
This is because own_* flags are frequently appeared in this PR. So, we wanted to wrap them with the following struct like:

/* A wrapper for flb_sds_t that tracks memory ownership */
typedef struct {
    flb_sds_t sds;   /* The actual string data */
    int       owned; /* A flag indicating if this struct owns the memory */
} flb_es_sds_t;

I like this approach, but there might be not just flb_sds_t type which will be wrapped (I'm looking at elasticsearch_config_destroy function in plugins/out_es/es_conf.c) if we decide to use this approach (C does not have C++ templates 😄).

Hi,
Thanks for the response. I mean, I'm not objection for the defining each of necessary functions for wrapping up for shallow copies. Just wanted to conceal own_* flags.

@mabrarov
Copy link
Contributor Author

mabrarov commented Aug 3, 2025

Hi @cosmo0920,

Here is one more thing I found.

Some of configuration options - like flb_elasticsearch_config::index defined in plugins/out_es/es.h - are loaded using flb_config_map, which instance is defined at plugins/out_es/es.c - refer to

0, FLB_TRUE, offsetof(struct flb_elasticsearch, index),

If I use custom type for such configuration options (fields of flb_elasticsearch_config struct) - like flb_es_char_ptr struct for index:

struct flb_es_char_ptr {
    char *ptr;
    int   owned;
};

struct flb_elasticsearch_config {
    /* Elasticsearch index (database) and type (table) */
    struct flb_es_char_ptr index;
    ...
};

then it will complicate usage of flb_config_map too. Like (I'm not sure this code is correct):

static struct flb_config_map config_map[] = {
    {
     FLB_CONFIG_MAP_STR, FLB_ES_CONFIG_PROPERTY_INDEX, FLB_ES_DEFAULT_INDEX,
     0, FLB_TRUE, offsetof(struct flb_elasticsearch_config, index) + offsetof(struct flb_es_char_ptr, ptr),
     "Set an index name"
    },
   ...

Anyway, I need to try it first. Just some thoughts.

Thank you.

…wn to parser of Upstream node configuration section are implemented, e.g. "host" and "port"

Signed-off-by: Marat Abrarov <[email protected]>
…o the test callback based on configuration of Fluent Bit and based on configuration of plugin

Signed-off-by: Marat Abrarov <[email protected]>
…with Upstream node configuration

For Elastic cloud authentication these parameters are always taken from plugin configuration and never from Upstream node configuration: cloud_id.

For AWS authentication these parameters are always taken from plugin configuration and never from Upstream node configuration: http_proxy, no_proxy, tls*.

Signed-off-by: Marat Abrarov <[email protected]>
…o the test callback based on configuration of Fluent Bit and based on configuration of plugin

Signed-off-by: Marat Abrarov <[email protected]>
@mabrarov mabrarov force-pushed the feature/out_es_upstream_support_extended branch from cb8d7b1 to 717d6b3 Compare August 5, 2025 18:28
Copy link

coderabbitai bot commented Aug 5, 2025

Walkthrough

This update refactors and modularizes the Elasticsearch output plugin in Fluent Bit, introducing new configuration structures and helper files to support high-availability (HA) mode and upstream configuration overrides. It adds new test cases for upstream-specific properties, updates function signatures and callbacks for test mode, and introduces several new headers and helper functions for configuration parsing and AWS/cloud integration.

Changes

Cohort / File(s) Change Summary
Elasticsearch Plugin Core Refactor
plugins/out_es/es.c, plugins/out_es/es.h, plugins/out_es/es_conf.c, plugins/out_es/es_conf.h
Major refactor: Introduced flb_elasticsearch_config struct for configuration, separated from main context; added HA mode support; modularized configuration parsing and validation; updated and added function signatures for config handling and target selection.
Elasticsearch Plugin Config Parsing (New)
plugins/out_es/es_conf_parse.c, plugins/out_es/es_conf_parse.h, plugins/out_es/es_conf_prop.h
Added new files for parsing and handling cloud/AWS authentication and configuration property macros. Declared and implemented functions for cloud credentials, AWS provider setup, and property name macros.
Elasticsearch Plugin Build
plugins/out_es/CMakeLists.txt
Added es_conf_parse.c to the build sources for the Elasticsearch output plugin.
Test Enhancements for Elasticsearch Output
tests/runtime/out_elasticsearch.c
Added new test cases for upstream configuration overrides, helper for dynamic upstream config file creation, flush context callback integration, and updated existing tests for new test mode callbacks.
Test Mode API and Callback Updates
include/fluent-bit/flb_lib.h, src/flb_lib.c, include/fluent-bit/flb_output.h, src/flb_engine_dispatch.c
Updated test mode API: added flush context callback support, renamed parameters, updated function signatures, and adjusted test runner logic to use new callback mechanism.

Sequence Diagram(s)

sequenceDiagram
    participant TestRunner
    participant OutputInstance
    participant FlushCtxCallback
    participant FormatterCallback

    TestRunner->>OutputInstance: Enable test mode with flush_ctx_callback
    TestRunner->>OutputInstance: Push test data
    OutputInstance->>FlushCtxCallback: Get flush context (if callback set)
    FlushCtxCallback-->>OutputInstance: Return flush context
    OutputInstance->>FormatterCallback: Run formatter with flush context
    FormatterCallback-->>OutputInstance: Return result
    OutputInstance-->>TestRunner: Test result
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~75 minutes

Poem

A patch for Elasticsearch, quite grand,
With configs and tests now carefully planned.
HA mode joins the show,
And upstreams can now override the flow.
Callbacks and helpers hop in with glee—
This bunny’s proud of such modularity!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (4)
plugins/out_es/es.h (1)

48-161: Ownership flags pattern needs architectural consideration.

The extensive use of own_xxx flags throughout the struct deviates from Fluent Bit's typical patterns. While functional for tracking resource ownership between plugin and upstream configurations, this approach adds complexity that may impact maintainability.

As discussed in previous reviews, consider whether this ownership tracking could be encapsulated differently or if the architecture needs adaptation to properly support this use case.

plugins/out_es/es_conf_parse.c (2)

102-109: Consider using thread-safe string parsing alternatives.

The use of strtok is not thread-safe and has been flagged as a dangerous function. Consider using flb_utils_split or other thread-safe alternatives for better safety.


124-130: Use safer string operations to prevent buffer overflows.

Using strcpy and strcat without bounds checking can lead to buffer overflows. Consider using snprintf or Fluent Bit's flb_sds APIs for safer string operations.

-    strcpy(cloud_host_buf, host);
-    strcat(cloud_host_buf, ".");
-    strcat(cloud_host_buf, region);
-    if (port != NULL) {
-        strcat(cloud_host_buf, ":");
-        strcat(cloud_host_buf, port);
-    }
+    int ret;
+    if (port != NULL) {
+        ret = snprintf(cloud_host_buf, sizeof(cloud_host_buf), "%s.%s:%s", 
+                      host, region, port);
+    } else {
+        ret = snprintf(cloud_host_buf, sizeof(cloud_host_buf), "%s.%s", 
+                      host, region);
+    }
+    if (ret < 0 || ret >= sizeof(cloud_host_buf)) {
+        return NULL;
+    }
plugins/out_es/es_conf.c (1)

302-327: Ownership tracking pattern needs architectural review

As noted in previous reviews, this ownership tracking pattern using own_xxx flags deviates from Fluent Bit's typical coding style. While the implementation appears correct for preventing double-frees in a shared configuration scenario, this approach introduces complexity that may be difficult to maintain.

Consider:

  1. Documenting why this pattern is necessary for the Elasticsearch plugin specifically
  2. Exploring alternative approaches such as reference counting or configuration cloning
  3. Adding comprehensive comments explaining the ownership model
🧹 Nitpick comments (3)
include/fluent-bit/flb_lib.h (1)

74-80: Consider function signature readability.

The new function signature is quite complex with many parameters. While this follows existing patterns in the codebase for similar callback registration functions, consider if some parameters could be grouped into a struct for better maintainability.

However, this is consistent with the existing API style in this file and likely maintains backward compatibility.

plugins/out_es/es.c (1)

853-867: Consider simplifying upstream connection logic

The current if-else structure could be simplified by extracting the upstream selection logic.

-    /* Get upstream connection */
-    if (ctx->ha_mode == FLB_TRUE) {
-        u_conn = flb_upstream_conn_get(node->u);
-        if (!u_conn) {
-            flb_plg_error(ctx->ins, "no upstream connections available for %s node",
-                          node->name);
-            FLB_OUTPUT_RETURN(FLB_RETRY);
-        }
-    }
-    else {
-        u_conn = flb_upstream_conn_get(ctx->u);
-        if (!u_conn) {
-            flb_plg_error(ctx->ins, "no upstream connections available");
-            FLB_OUTPUT_RETURN(FLB_RETRY);
-        }
-    }
+    /* Get upstream connection */
+    struct flb_upstream *upstream = (ctx->ha_mode == FLB_TRUE) ? node->u : ctx->u;
+    u_conn = flb_upstream_conn_get(upstream);
+    if (!u_conn) {
+        if (ctx->ha_mode == FLB_TRUE) {
+            flb_plg_error(ctx->ins, "no upstream connections available for %s node",
+                          node->name);
+        } else {
+            flb_plg_error(ctx->ins, "no upstream connections available");
+        }
+        FLB_OUTPUT_RETURN(FLB_RETRY);
+    }
tests/runtime/out_elasticsearch.c (1)

1065-1067: Add validation for upstream configuration loading

The test creates an upstream configuration file but doesn't verify if it was successfully loaded and parsed. Consider adding assertions to validate the upstream configuration was applied correctly.

// After setting upstream, verify it was loaded
TEST_CHECK(ctx != NULL);
// Could also add checks to verify the upstream nodes were created
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d4c4dc and 717d6b3.

📒 Files selected for processing (13)
  • include/fluent-bit/flb_lib.h (2 hunks)
  • include/fluent-bit/flb_output.h (1 hunks)
  • plugins/out_es/CMakeLists.txt (1 hunks)
  • plugins/out_es/es.c (31 hunks)
  • plugins/out_es/es.h (5 hunks)
  • plugins/out_es/es_conf.c (1 hunks)
  • plugins/out_es/es_conf.h (1 hunks)
  • plugins/out_es/es_conf_parse.c (1 hunks)
  • plugins/out_es/es_conf_parse.h (1 hunks)
  • plugins/out_es/es_conf_prop.h (1 hunks)
  • src/flb_engine_dispatch.c (2 hunks)
  • src/flb_lib.c (2 hunks)
  • tests/runtime/out_elasticsearch.c (17 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (70)
  • GitHub Check: PR - container builds / Windows container images (2025)
  • GitHub Check: PR - container builds / Windows container images (2022)
  • GitHub Check: PR - packages build Windows / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: PR - packages build Windows / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: PR - packages build Windows / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: PR - packages build Linux / ubuntu/24.04 package build and stage to S3
  • GitHub Check: PR - packages build Linux / raspbian/bookworm package build and stage to S3
  • GitHub Check: PR - packages build Linux / ubuntu/24.04.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / debian/bullseye.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / ubuntu/22.04 package build and stage to S3
  • GitHub Check: PR - packages build Linux / rockylinux/9.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / debian/bullseye package build and stage to S3
  • GitHub Check: PR - packages build Linux / debian/bookworm package build and stage to S3
  • GitHub Check: PR - packages build Linux / ubuntu/22.04.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / debian/buster package build and stage to S3
  • GitHub Check: PR - packages build Linux / debian/buster.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / almalinux/8.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / almalinux/8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / almalinux/9.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / debian/bookworm.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / rockylinux/9 package build and stage to S3
  • GitHub Check: PR - packages build Linux / rockylinux/8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / centos/7 package build and stage to S3
  • GitHub Check: PR - packages build Linux / almalinux/9 package build and stage to S3
  • GitHub Check: PR - packages build Linux / rockylinux/8.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / centos/7.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / centos/8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / amazonlinux/2.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / amazonlinux/2023 package build and stage to S3
  • GitHub Check: PR - packages build Linux / amazonlinux/2023.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / centos/9 package build and stage to S3
  • GitHub Check: PR - packages build Linux / centos/9.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / centos/8.arm64v8 package build and stage to S3
  • GitHub Check: PR - packages build Linux / amazonlinux/2 package build and stage to S3
  • GitHub Check: PR - container builds / arm64/debug container image build
  • GitHub Check: PR - container builds / arm/v7/production container image build
  • GitHub Check: PR - container builds / arm/v7/debug container image build
  • GitHub Check: PR - container builds / amd64/debug container image build
  • GitHub Check: PR - container builds / arm64/production container image build
  • GitHub Check: PR - container builds / amd64/production container image build
  • GitHub Check: PR - packages build MacOS / call-build-macos-package (Intel macOS runner, macos-14-large, 3.31.6)
  • GitHub Check: PR - packages build MacOS / call-build-macos-package (Apple Silicon macOS runner, macos-14, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-centos-7
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: PR - fuzzing test
🔇 Additional comments (15)
plugins/out_es/es_conf_prop.h (1)

1-65: LGTM! Well-structured configuration property definitions.

The header file follows good practices with proper include guards, consistent naming conventions, and appropriate conditional compilation for AWS features.

plugins/out_es/CMakeLists.txt (1)

3-3: LGTM! Correct addition of new source file.

The new es_conf_parse.c source file is properly added to the build configuration in alphabetical order.

include/fluent-bit/flb_lib.h (2)

25-25: LGTM! Required include for new API.

The addition of flb_input.h is necessary for the struct flb_input_instance type used in the new flush context callback function.


73-73: LGTM! Parameter rename improves clarity.

Renaming test_ctx to flush_ctx better reflects the parameter's purpose in the context of flush operations.

plugins/out_es/es_conf.h (4)

23-23: LGTM! Appropriate include for upstream functionality.

The replacement of general includes with flb_upstream_node.h aligns with the focus on upstream server support.


27-30: LGTM! Well-defined write operation constants.

The write operation constants are clearly defined and follow consistent naming conventions. These align with standard Elasticsearch operations.


35-35: LGTM! Appropriate return type change.

Changing flb_es_conf_destroy to void suggests improved error handling where cleanup operations are designed to always succeed or handle errors internally.


37-38: LGTM! New function supports upstream configuration.

The new flb_es_upstream_conf function provides a clean interface for retrieving upstream-specific configuration, which is essential for the upstream servers feature.

include/fluent-bit/flb_output.h (2)

153-154: LGTM! Clarified comment improves understanding.

The updated comment clearly explains the relationship between flush_ctx and the new callback mechanism.


156-169: LGTM! Well-documented callback interface.

The new flush_ctx_callback function pointer is properly documented with clear parameter descriptions. The signature is consistent with the API declared in flb_lib.h.

src/flb_engine_dispatch.c (1)

101-142: Changes to test formatter function look good.

The refactoring to retrieve flush_ctx locally and support an optional callback provides better flexibility for test configurations without breaking existing functionality.

src/flb_lib.c (1)

579-644: API changes for test mode configuration are well-implemented.

The parameter rename to flush_ctx improves clarity, and the new flb_output_set_test_flush_ctx_callback function follows established patterns with proper error handling.

plugins/out_es/es_conf_parse.h (1)

1-54: Header file structure and declarations are appropriate.

The new header properly declares configuration parsing functions with clear documentation and appropriate conditional compilation for AWS features.

plugins/out_es/es.h (1)

28-28: Good catch on fixing the default port.

The correction from 92000 to 9200 fixes what was clearly a typo in the default Elasticsearch port.

plugins/out_es/es_conf_parse.c (1)

186-337: AWS authentication setup is comprehensive.

The AWS provider initialization with proper TLS context creation, STS support, and error handling is well-implemented. Good use of ownership flags to track resource lifecycle.

Comment on lines +409 to +463
ec->logstash_prefix = flb_sds_create(tmp);
if (ec->logstash_prefix == NULL) {
return -1;
}
ec->own_logstash_prefix = FLB_TRUE;
}
tmp = flb_upstream_node_get_property(FLB_ES_CONFIG_PROPERTY_LOGSTASH_PREFIX_SEPARATOR,
node);
if (tmp) {
ec->logstash_prefix_separator = flb_sds_create(tmp);
if (ec->logstash_prefix_separator == NULL) {
return -1;
}
ec->own_logstash_prefix_separator = FLB_TRUE;
}
tmp = flb_upstream_node_get_property(FLB_ES_CONFIG_PROPERTY_LOGSTASH_DATEFORMAT,
node);
if (tmp) {
ec->logstash_dateformat = flb_sds_create(tmp);
if (ec->logstash_dateformat == NULL) {
return -1;
}
ec->own_logstash_dateformat = FLB_TRUE;
}
tmp = flb_upstream_node_get_property(FLB_ES_CONFIG_PROPERTY_TIME_KEY, node);
if (tmp) {
ec->time_key = flb_sds_create(tmp);
if (ec->time_key == NULL) {
return -1;
}
ec->own_time_key = FLB_TRUE;
}
tmp = flb_upstream_node_get_property(FLB_ES_CONFIG_PROPERTY_TIME_KEY_FORMAT, node);
if (tmp) {
ec->time_key_format = flb_sds_create(tmp);
if (ec->time_key_format == NULL) {
return -1;
}
ec->own_time_key_format = FLB_TRUE;
}
tmp = flb_upstream_node_get_property(FLB_ES_CONFIG_PROPERTY_TIME_KEY_NANOS, node);
if (tmp) {
ec->time_key_nanos = flb_utils_bool(tmp);
}
tmp = flb_upstream_node_get_property(FLB_ES_CONFIG_PROPERTY_INCLUDE_TAG_KEY, node);
if (tmp) {
ec->include_tag_key = flb_utils_bool(tmp);
}
tmp = flb_upstream_node_get_property(FLB_ES_CONFIG_PROPERTY_TAG_KEY, node);
if (tmp) {
ec->tag_key = flb_sds_create(tmp);
if (ec->tag_key == NULL) {
return -1;
}
ec->own_tag_key = FLB_TRUE;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider cleanup on partial allocation failures

When creating multiple allocated strings, if one allocation fails (e.g., at line 444), previously allocated strings in the same ec structure (like logstash_prefix at line 409) won't be freed before returning -1.

Consider adding a cleanup path or ensuring the caller properly handles partial initialization:

// At the error return points, ensure cleanup of already allocated resources
if (ec->tag_key == NULL) {
    // Free any previously allocated strings in this function
    if (ec->own_logstash_prefix == FLB_TRUE) {
        flb_sds_destroy(ec->logstash_prefix);
        ec->own_logstash_prefix = FLB_FALSE;
    }
    // ... similar cleanup for other allocated strings
    return -1;
}
🤖 Prompt for AI Agents
In plugins/out_es/es_conf.c between lines 409 and 463, multiple string
allocations are performed and if any allocation fails, the function returns -1
without freeing previously allocated strings, causing potential memory leaks. To
fix this, add a cleanup section before each error return that checks which
strings were successfully allocated (using the corresponding own_* flags) and
frees them properly, resetting the flags to false. This ensures no partial
allocations remain unfreed on failure.

Comment on lines +645 to +667
struct flb_elasticsearch_config *flb_elasticsearch_target(
struct flb_elasticsearch *ctx, struct flb_upstream_node **node)
{
struct flb_elasticsearch_config *ec;
struct flb_upstream_node *target_node;

if (ctx->ha_mode == FLB_FALSE) {
ec = flb_es_upstream_conf(ctx, NULL);
*node = NULL;
return ec;
}

target_node = flb_upstream_ha_node_get(ctx->ha);
if (!target_node) {
*node = NULL;
return NULL;
}

ec = flb_es_upstream_conf(ctx, target_node);
*node = target_node;

return ec;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add null check for ctx parameter

The function should validate the ctx parameter before dereferencing it to avoid potential null pointer dereference.

 struct flb_elasticsearch_config *flb_elasticsearch_target(
         struct flb_elasticsearch *ctx, struct flb_upstream_node **node)
 {
     struct flb_elasticsearch_config *ec;
     struct flb_upstream_node *target_node;
 
+    if (!ctx || !node) {
+        return NULL;
+    }
+
     if (ctx->ha_mode == FLB_FALSE) {
         ec = flb_es_upstream_conf(ctx, NULL);
         *node = NULL;
         return ec;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
struct flb_elasticsearch_config *flb_elasticsearch_target(
struct flb_elasticsearch *ctx, struct flb_upstream_node **node)
{
struct flb_elasticsearch_config *ec;
struct flb_upstream_node *target_node;
if (ctx->ha_mode == FLB_FALSE) {
ec = flb_es_upstream_conf(ctx, NULL);
*node = NULL;
return ec;
}
target_node = flb_upstream_ha_node_get(ctx->ha);
if (!target_node) {
*node = NULL;
return NULL;
}
ec = flb_es_upstream_conf(ctx, target_node);
*node = target_node;
return ec;
}
struct flb_elasticsearch_config *flb_elasticsearch_target(
struct flb_elasticsearch *ctx, struct flb_upstream_node **node)
{
struct flb_elasticsearch_config *ec;
struct flb_upstream_node *target_node;
if (!ctx || !node) {
return NULL;
}
if (ctx->ha_mode == FLB_FALSE) {
ec = flb_es_upstream_conf(ctx, NULL);
*node = NULL;
return ec;
}
target_node = flb_upstream_ha_node_get(ctx->ha);
if (!target_node) {
*node = NULL;
return NULL;
}
ec = flb_es_upstream_conf(ctx, target_node);
*node = target_node;
return ec;
}
🤖 Prompt for AI Agents
In plugins/out_es/es.c around lines 645 to 667, the function
flb_elasticsearch_target dereferences the ctx parameter without checking if it
is NULL, which can cause a null pointer dereference. Add a null check at the
start of the function to verify if ctx is NULL, and if so, set *node to NULL and
return NULL immediately to safely handle invalid input.

int arg_idx;
va_list args;

upstream_conf_filename = tmpnam(NULL);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace deprecated tmpnam() with safer alternative

The tmpnam() function is deprecated and has known security vulnerabilities (race conditions, predictable names). Use mkstemp() or platform-specific secure alternatives instead.

-    upstream_conf_filename = tmpnam(NULL);
-    if (upstream_conf_filename == NULL) {
-        return NULL;
-    }
-
-    upstream_conf_file = fopen(upstream_conf_filename, "w");
+    char template[] = "/tmp/flb_es_test_XXXXXX";
+    int fd = mkstemp(template);
+    if (fd == -1) {
+        return NULL;
+    }
+    
+    upstream_conf_filename = strdup(template);
+    if (upstream_conf_filename == NULL) {
+        close(fd);
+        unlink(template);
+        return NULL;
+    }
+    
+    upstream_conf_file = fdopen(fd, "w");
     if (upstream_conf_file == NULL) {
+        close(fd);
+        unlink(template);
+        free(upstream_conf_filename);
         return NULL;
     }
🤖 Prompt for AI Agents
In tests/runtime/out_elasticsearch.c at line 32, replace the deprecated and
insecure tmpnam() call with mkstemp() to safely create a unique temporary
filename. Use mkstemp() to generate a secure temporary file, handle the returned
file descriptor properly, and store the filename for further use, ensuring no
race conditions or predictable names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs-required ok-package-test Run PR packaging tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants