Skip to content

out_azure_blob: add path templating support comparable to s3#11178

Merged
edsiper merged 2 commits intofluent:masterfrom
nberlee:master
Apr 1, 2026
Merged

out_azure_blob: add path templating support comparable to s3#11178
edsiper merged 2 commits intofluent:masterfrom
nberlee:master

Conversation

@nberlee
Copy link
Copy Markdown
Contributor

@nberlee nberlee commented Nov 18, 2025

fixes #7515


Enter [N/A] in the box, if an item is not applicable to your change.

Testing
Before we can approve your change; please submit the following in a comment:

  • Example configuration file for the change
[SERVICE]
    flush     1
    log_level info

[INPUT]
    name      dummy
    dummy     {"name": "Fluent Bit", "year": 2020}
    samples   1
    tag       app.log


[OUTPUT]
    name                  azure_blob
    match                 *
    account_name          devstoreaccount1
    shared_key            Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==
    path                  logs/$TAG/%Y/%m/%d/$UUID
    container_name        devstoreaccount1
    auto_create_container on
    tls                   off
    emulator_mode         on
    endpoint              http://localhost:10000
  • Debug log output from testing the change
    see valgrind log
  • Attached Valgrind output that shows no leaks or memory corruption was found

valgrind.log

If this is a change to packaging of containers or native binaries then please confirm it works for all targets.

  • [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

  • 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.

Summary by CodeRabbit

  • New Features

    • Path templating for Azure Blob output: dynamic, per-file prefixes using UUIDs, time/strftime tokens and tag segments; templating applied consistently to uploads, appends and commits with legacy fallback.
  • Bug Fixes

    • Improved error handling, cleanup and retry logic for templated paths to reduce leaks and failed uploads.
  • Tests

    • Added unit tests covering templating, UUID/time/token expansion and resulting URIs.
  • Chores

    • Persist resolved path_prefix with file metadata and updated URI/SAS handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@nberlee
Copy link
Copy Markdown
Contributor Author

nberlee commented Nov 25, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Nov 25, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Nov 25, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds path-templating and resolution to the Azure Blob output: implements token expansion (UUID, time tokens, strftime, record-accessors) via azb_resolve_path(), threads a resolved path_prefix through DB records and URI/append/block/commit flows, updates DB schema to store path_prefix, and adds unit tests for path resolution.

Changes

Cohort / File(s) Summary
Core path templating & resolver
plugins/out_azure_blob/azure_blob.c
Implements token-replacement helpers (azb_replace_uuid, azb_simple_replace, azb_apply_time_tokens, azb_apply_strftime, azb_trim_slashes), RNG utilities, and azb_resolve_path(); threads path_prefix through create/send/commit/delete flows with error-path cleanup.
Public context & config
plugins/out_azure_blob/azure_blob.h, plugins/out_azure_blob/azure_blob_conf.c
Adds path_templating_enabled to struct flb_azure_blob; declares azb_resolve_path() and azb_commit_prefix_with_fallback(); moves/sanitizes ctx->path handling and manages templating flag lifecycle.
URI helpers & effective path
plugins/out_azure_blob/azure_blob_uri.c, plugins/out_azure_blob/azure_blob_uri.h
Adds azb_effective_path(); changes azb_uri_create_blob() to accept path_prefix and use effective path when building URIs; adds NULL/error checks for sds operations and SAS appends.
Append-blob URI updates
plugins/out_azure_blob/azure_blob_appendblob.c, plugins/out_azure_blob/azure_blob_appendblob.h
Extends azb_append_blob_uri() to accept path_prefix, computes effective_path, includes it in append-block URIs, and tightens error handling.
Block-blob URI & commit updates
plugins/out_azure_blob/azure_blob_blockblob.c, plugins/out_azure_blob/azure_blob_blockblob.h
Adds path_prefix parameter to blocklist/uri/commit/block functions; uses effective_path in URI assembly and propagates path_prefix through commit/block APIs and call sites.
Database schema & accessors
plugins/out_azure_blob/azure_blob_db.c, plugins/out_azure_blob/azure_blob_db.h
Adds path_prefix column to out_azure_blob_files, migration helper ensure_path_prefix_column(), extends INSERT/SELECT SQL and DB API signatures to store and return path_prefix, and propagates path_prefix through DB retrievals and file-part handling.
Configuration & lifecycle
plugins/out_azure_blob/azure_blob_conf.c
Sanitizes ctx->path after remote overrides, enables path_templating_enabled when path present, and clears flag on destroy.
Tests & build
tests/internal/azure_blob_path.c, tests/internal/CMakeLists.txt
Adds unit tests covering tag/time/UUID/strftime templating and URI behavior; conditionally includes and links tests when FLB_OUT_AZURE_BLOB is enabled.
Minor integrations
plugins/out_azure_blob/* (multiple files)
Updates numerous call sites to accept and pass path_prefix through URI creation, append/block/commit, file-part handling, ingestion/flush flows, and ensures path_prefix memory is freed on error paths.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Ingest as Ingest/Flush
    participant Resolver as azb_resolve_path()
    participant Expander as Token Expander
    participant DB as SQLite (azb_db_*)
    participant URI as URI builders (azb_uri_*/azb_effective_path)
    participant Creator as create/commit routines

    Ingest->>Resolver: resolve path_prefix(tag, timestamp, record)
    activate Resolver
    Resolver->>Expander: expand tokens (%L, %3N, %9N), strftime, $UUID, record-accessors
    Expander-->>Resolver: resolved, trimmed path_prefix
    Resolver-->>Ingest: return resolved path_prefix
    deactivate Resolver

    Ingest->>DB: insert file(..., path_prefix)
    DB-->>Ingest: rowid / ack

    Ingest->>URI: build blob URI(path_prefix, name)
    activate URI
    URI->>URI: effective_path = azb_effective_path(ctx, path_prefix)
    URI-->>Ingest: blob URI (with effective_path + SAS if present)
    deactivate URI

    Ingest->>Creator: create/append/commit blob(path_prefix, blob_name, parts)
    activate Creator
    Creator->>DB: update/commit metadata (with path_prefix)
    Creator-->>Ingest: success / retry / error
    deactivate Creator
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing extra attention:
    • plugins/out_azure_blob/azure_blob.c — token expansion correctness, RNG/UUID replacement, strftime/time-token handling, memory ownership and trimming edge cases.
    • Cross-file signature changes (azure_blob_uri.*, azure_blob_appendblob.*, azure_blob_blockblob.*, callers) — ensure all call sites updated and const-correctness maintained.
    • DB migration and SQL binding (ensure_path_prefix_column(), updated INSERT/SELECT) — NULL handling, backward compatibility, and statement preparation.
    • Unit tests (tests/internal/azure_blob_path.c) — determinism for UUID/randomness and coverage for empty/error cases.

Suggested reviewers

  • edsiper
  • cosmo0920
  • fujimotos

Poem

🐇 I hopped through tokens, chased a $UUID seed,
I stitched time into paths and trimmed each weed,
Resolved prefixes tidy, no slashes stray,
A rabbit's small cheer for every mapped away,
Hop, commit, and store — templating saved the day!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.92% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding path templating support to Azure Blob output to match S3 functionality, directly addressing the PR's core objective.
Linked Issues check ✅ Passed The PR fully addresses issue #7515 by implementing S3-like path templating with support for date/time format directives (strftime), $TAG, and $UUID tokens in Azure Blob path configuration, as verified by the comprehensive changes across files.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing path templating: new functions (azb_resolve_path, azb_effective_path), database schema updates for path_prefix tracking, URI construction modifications, and comprehensive test coverage. No unrelated changes detected.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (2)
plugins/out_azure_blob/azure_blob.c (2)

176-218: Only replaces the first $UUID occurrence.

The azb_replace_uuid function uses strstr which finds only the first occurrence of $UUID. If a user specifies a path like logs/$UUID/data/$UUID, only the first placeholder will be replaced.

Consider whether multiple UUID placeholders should be supported. If so, a loop would be needed. If single replacement is intentional, document this limitation.


347-366: Minor: strftime returns 0 for both buffer overflow and empty output.

The loop relies on strftime returning 0 to indicate the buffer is too small. However, strftime also returns 0 if the output is an empty string (e.g., if the path contains no format specifiers that produce output, though unlikely). The 4096-byte limit prevents infinite looping, so this is safe, but the behavior could be surprising.

If you want to distinguish these cases more explicitly:

     while (1) {
         out_len = strftime(buf, buf_size + 1, path, &tm_utc);
-        if (out_len > 0) {
+        if (out_len > 0 || buf_size > flb_sds_len(path) * 2) {
             break;
         }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73d20d0 and 168dcae.

📒 Files selected for processing (11)
  • plugins/out_azure_blob/azure_blob.c (15 hunks)
  • plugins/out_azure_blob/azure_blob.h (3 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.c (7 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_conf.c (3 hunks)
  • plugins/out_azure_blob/azure_blob_uri.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_uri.h (1 hunks)
  • tests/internal/CMakeLists.txt (2 hunks)
  • tests/internal/azure_blob_path.c (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-08-31T12:46:11.940Z
Learnt from: ThomasDevoogdt
Repo: fluent/fluent-bit PR: 9277
File: .github/workflows/pr-compile-check.yaml:147-151
Timestamp: 2025-08-31T12:46:11.940Z
Learning: In fluent-bit CMakeLists.txt, the system library preference flags are defined as FLB_PREFER_SYSTEM_LIB_ZSTD and FLB_PREFER_SYSTEM_LIB_KAFKA with the FLB_ prefix.

Applied to files:

  • tests/internal/CMakeLists.txt
  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:02.561Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:7-7
Timestamp: 2025-08-29T06:25:02.561Z
Learning: In Fluent Bit, ZSTD (zstandard) compression library is bundled directly in the source tree at `lib/zstd-1.5.7` and is built unconditionally as a static library. Unlike optional external dependencies, ZSTD does not use conditional compilation guards like `FLB_HAVE_ZSTD` and is always available. Headers like `<fluent-bit/flb_zstd.h>` can be included directly without guards.

Applied to files:

  • plugins/out_azure_blob/azure_blob_conf.c
  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components such as ARROW/PARQUET (which use `#ifdef FLB_HAVE_ARROW` guards), ZSTD support is always available and doesn't need build-time conditionals. ZSTD headers are included directly without guards across multiple plugins and core components.

Applied to files:

  • plugins/out_azure_blob/azure_blob_conf.c
  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:55.855Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:52-56
Timestamp: 2025-08-29T06:24:55.855Z
Learning: ZSTD compression is always available in Fluent Bit and does not require conditional compilation guards. Unlike Arrow/Parquet which use #ifdef FLB_HAVE_ARROW guards, ZSTD is built unconditionally with flb_zstd.c included directly in src/CMakeLists.txt and a bundled ZSTD library at lib/zstd-1.5.7/.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:26.170Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:39-42
Timestamp: 2025-08-29T06:24:26.170Z
Learning: In Fluent Bit, ZSTD compression support is enabled by default and does not require conditional compilation guards (like #ifdef FLB_HAVE_ZSTD) around ZSTD-related code declarations and implementations.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components, ZSTD support is always available and doesn't need build-time conditionals.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:44.797Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:26-26
Timestamp: 2025-08-29T06:24:44.797Z
Learning: In Fluent Bit, ZSTD support is always available and enabled by default. The build system automatically detects and uses either the system libzstd library or builds the bundled ZSTD version. Unlike other optional dependencies like Arrow which use conditional compilation guards (e.g., FLB_HAVE_ARROW), ZSTD does not require conditional includes or build flags.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
🧬 Code graph analysis (8)
plugins/out_azure_blob/azure_blob_uri.h (1)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_create_blob (137-163)
tests/internal/azure_blob_path.c (4)
src/flb_sds.c (2)
  • flb_sds_destroy (389-399)
  • flb_sds_create (78-90)
src/flb_record_accessor.c (2)
  • flb_ra_destroy (232-248)
  • flb_ra_create (271-358)
plugins/out_azure_blob/azure_blob.c (1)
  • azb_resolve_path (412-518)
include/fluent-bit/flb_time.h (1)
  • flb_time_set (75-79)
plugins/out_azure_blob/azure_blob_conf.c (1)
src/flb_record_accessor.c (2)
  • flb_ra_create (271-358)
  • flb_ra_destroy (232-248)
plugins/out_azure_blob/azure_blob_appendblob.c (2)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_container (107-118)
src/flb_sds.c (1)
  • flb_sds_printf (336-387)
plugins/out_azure_blob/azure_blob_uri.c (1)
src/flb_sds.c (1)
  • flb_sds_printf (336-387)
plugins/out_azure_blob/azure_blob_blockblob.c (2)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_container (107-118)
src/flb_sds.c (1)
  • flb_sds_printf (336-387)
plugins/out_azure_blob/azure_blob_appendblob.h (1)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-53)
plugins/out_azure_blob/azure_blob.h (1)
plugins/out_azure_blob/azure_blob.c (1)
  • azb_resolve_path (412-518)
🔇 Additional comments (32)
plugins/out_azure_blob/azure_blob.h (1)

27-27: LGTM!

The header additions are well-structured:

  • The flb_time.h include is required for the struct flb_time parameter in azb_resolve_path.
  • The path_accessor field enables tag expansion via record accessor.
  • The function declaration correctly matches the implementation signature.

Also applies to: 66-66, 171-176

tests/internal/CMakeLists.txt (1)

62-67: LGTM!

The CMake integration follows the project's established patterns:

  • Conditional inclusion of test file when FLB_OUT_AZURE_BLOB is enabled mirrors other plugin-specific tests.
  • Library linking is correctly scoped to only the flb-it-azure_blob_path test target.

Also applies to: 227-229

plugins/out_azure_blob/azure_blob_appendblob.h (1)

26-28: LGTM!

The function signature update correctly adds path_prefix parameter to support path templating. The const char * type for path_prefix is appropriate since it's read-only input.

plugins/out_azure_blob/azure_blob_conf.c (1)

816-819: LGTM!

The cleanup logic correctly destroys the path accessor and nullifies the pointer, following the established pattern for other resources in this function.

plugins/out_azure_blob/azure_blob_uri.h (1)

30-32: LGTM!

The updated function signature correctly adds the path_prefix parameter, consistent with the implementation and the parallel changes in azure_blob_appendblob.h.

plugins/out_azure_blob/azure_blob_appendblob.c (1)

27-49: LGTM!

The implementation correctly:

  • Selects effective_path preferring path_prefix over ctx->path when provided and non-empty.
  • Constructs the URI with proper path/tag structure for append blob operations.
  • Maintains existing SAS token handling.

The flb_sds_printf return value is not checked, but this follows the existing pattern in the codebase for this function.

tests/internal/azure_blob_path.c (7)

13-24: LGTM!

The ctx_cleanup helper properly handles resource cleanup for both path and path_accessor, with NULL checks before destruction and pointer nullification after.


26-58: LGTM!

Good test coverage for basic $TAG substitution with proper setup, assertion, and cleanup flow.


60-94: LGTM!

Excellent test for $TAG[n] indexed tag segment extraction with delimiter parsing.


96-131: LGTM!

Comprehensive test for time-based tokens (%Y, %m, %d, %3N, %9N, %L) using a fixed timestamp for deterministic verification.


133-177: LGTM!

Good test for UUID token substitution with validation that:

  • The UUID prefix is preserved.
  • The generated value is 8 alphanumeric characters.
  • No $UUID literal remains in output.

179-209: LGTM!

Important edge case test verifying that out-of-bounds tag index ($TAG[5] with only 2 tag segments) correctly returns ret == 0 with resolved == NULL.


211-217: LGTM!

Test registration is complete and properly null-terminated.

plugins/out_azure_blob/azure_blob_uri.c (1)

137-162: LGTM!

The implementation correctly:

  • Adds path_prefix parameter to enable dynamic path resolution.
  • Uses the same effective_path selection logic as azb_append_blob_uri for consistency.
  • Properly handles SAS token appending with ? (vs & in appendblob which already has query params).
plugins/out_azure_blob/azure_blob_blockblob.h (1)

26-43: LGTM! Consistent API extension for path templating support.

The function signatures are updated consistently to accept the new path_prefix parameter with appropriate const qualification. The parameter ordering is uniform across all modified functions.

plugins/out_azure_blob/azure_blob_blockblob.c (5)

34-61: LGTM! Clean effective_path fallback logic.

The function correctly implements the path_prefix fallback pattern: if path_prefix is provided and non-empty, use it; otherwise fall back to ctx->path. The dual check for both NULL and empty string is appropriate.


63-124: LGTM! Proper resource management and path handling.

The function correctly handles the path_prefix parameter with proper fallback logic and ensures encoded_blockid is freed before return in all code paths.


126-165: LGTM! Consistent implementation.

The azb_block_blob_uri_commit function follows the same effective_path pattern as other functions in this file.


354-393: LGTM! Proper path_prefix propagation.

The function correctly forwards the path_prefix parameter to the internal azb_block_blob_uri_commit call.


447-451: LGTM! Correct NULL path_prefix for file parts.

Passing NULL as path_prefix is appropriate here since file parts use the pre-determined path stored in the database rather than dynamically resolved templated paths.

plugins/out_azure_blob/azure_blob.c (12)

220-267: LGTM with same single-replacement caveat.

The helper correctly handles NULL inputs and memory management. Like azb_replace_uuid, it only replaces the first occurrence of a token, which is acceptable for the time tokens (%3N, %9N, %L) that are typically used once per path.


269-305: LGTM! Correct sequential token application.

The function properly chains time token replacements and handles failures appropriately.


382-410: LGTM! Correct in-place slash trimming.

The function properly uses memmove for overlapping memory regions and correctly updates the SDS length. Edge cases (NULL input, all-slash paths) are handled.


412-518: LGTM! Well-structured path resolution pipeline.

The function implements a clean multi-stage path resolution:

  1. UUID replacement (before record accessor to preserve $ tokens)
  2. Time token replacement (%3N, %9N, %L)
  3. strftime formatting
  4. Record accessor expansion for $TAG and $TAG[n]
  5. Slash trimming

Memory management is correct across all error paths.


520-542: LGTM! Clean wrapper for tag-based blob creation.

The function properly wraps path resolution with blob creation. The defensive NULL check before flb_sds_destroy(prefix) at lines 529-531 is good practice, even though azb_resolve_path initializes *out_path to NULL on entry.


544-555: LGTM! Properly propagates path_prefix.

The function correctly forwards the path_prefix parameter to azb_uri_create_blob.


624-632: LGTM! Correct NULL path_prefix for delete operation.

Delete operations target existing blobs by name rather than templated paths, so passing NULL is appropriate.


836-946: LGTM! Comprehensive path_prefix handling in send_blob.

The function correctly:

  1. Resolves the path at the start using current timestamp
  2. Propagates path_prefix to all URI construction and blob operation functions
  3. Cleans up path_prefix in all exit paths (success, error, and retry)

1663-1670: LGTM! Consistent use of tag-aware blob creation.

The callback correctly uses azb_create_blob_with_tag to ensure path templating is applied when creating blobs.


1794-1800: LGTM! Path templating in chunk ingestion.

Consistent with other code paths, this uses azb_create_blob_with_tag for path-aware blob creation.


2052-2065: LGTM! Path templating in non-buffered flush.

The non-buffered flush path correctly uses azb_create_blob_with_tag for consistent path templating behavior.


433-435: path_accessor initialization is correctly implemented.

Verification confirms the code works as intended: path_accessor is conditionally created in azure_blob_conf.c:766 when a path template is configured, with proper error handling (lines 767-769). The early return at line 433 is appropriate—if no path template is configured, the function returns 0 (success) with *out_path = NULL, which is the correct behavior.

Copy link
Copy Markdown

@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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 168dcae and feafb8a.

📒 Files selected for processing (12)
  • plugins/out_azure_blob/azure_blob.c (16 hunks)
  • plugins/out_azure_blob/azure_blob.h (3 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.c (7 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_conf.c (3 hunks)
  • plugins/out_azure_blob/azure_blob_uri.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_uri.h (1 hunks)
  • tests/internal/CMakeLists.txt (2 hunks)
  • tests/internal/azure_blob.c (1 hunks)
  • tests/internal/azure_blob_path.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • tests/internal/CMakeLists.txt
  • plugins/out_azure_blob/azure_blob_conf.c
  • plugins/out_azure_blob/azure_blob.h
  • tests/internal/azure_blob_path.c
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components such as ARROW/PARQUET (which use `#ifdef FLB_HAVE_ARROW` guards), ZSTD support is always available and doesn't need build-time conditionals. ZSTD headers are included directly without guards across multiple plugins and core components.

Applied to files:

  • tests/internal/azure_blob.c
📚 Learning: 2025-08-29T06:24:55.855Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:52-56
Timestamp: 2025-08-29T06:24:55.855Z
Learning: ZSTD compression is always available in Fluent Bit and does not require conditional compilation guards. Unlike Arrow/Parquet which use #ifdef FLB_HAVE_ARROW guards, ZSTD is built unconditionally with flb_zstd.c included directly in src/CMakeLists.txt and a bundled ZSTD library at lib/zstd-1.5.7/.

Applied to files:

  • tests/internal/azure_blob.c
🧬 Code graph analysis (5)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
src/flb_sds.c (1)
  • flb_sds_printf (336-387)
plugins/out_azure_blob/azure_blob_appendblob.h (1)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-53)
tests/internal/azure_blob.c (6)
src/flb_config.c (2)
  • flb_config_init (233-486)
  • flb_config_exit (488-672)
src/flb_upstream.c (1)
  • flb_upstream_create (290-363)
src/flb_sds.c (2)
  • flb_sds_create (78-90)
  • flb_sds_destroy (389-399)
plugins/out_azure_blob/azure_blob_blockblob.c (1)
  • azb_block_blob_uri (63-124)
src/flb_http_client.c (3)
  • flb_http_client (814-859)
  • flb_http_get_header (1002-1019)
  • flb_http_client_destroy (1688-1695)
plugins/out_azure_blob/azure_blob_http.c (1)
  • azb_http_client_setup (293-366)
plugins/out_azure_blob/azure_blob_uri.c (1)
src/flb_sds.c (1)
  • flb_sds_printf (336-387)
plugins/out_azure_blob/azure_blob.c (3)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_create_blob (137-163)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-53)
plugins/out_azure_blob/azure_blob_blockblob.c (1)
  • azb_block_blob_uri (63-124)
🔇 Additional comments (21)
plugins/out_azure_blob/azure_blob_appendblob.h (1)

26-28: LGTM: API signature updated for path templating support.

The addition of path_prefix parameter aligns with the broader path templating changes across the Azure Blob module.

Minor note: Lines 27-28 use tabs for indentation while the codebase generally uses 4-space indentation. This is a cosmetic issue that can be addressed if desired.

plugins/out_azure_blob/azure_blob_uri.h (1)

30-32: LGTM: Header declaration updated for path_prefix support.

The signature change is consistent with the implementation and other URI-building functions in this PR.

plugins/out_azure_blob/azure_blob_appendblob.c (1)

27-46: LGTM: Path prefix logic correctly implemented.

The effective_path computation properly falls back to ctx->path when path_prefix is NULL or empty, maintaining backward compatibility while enabling path templating.

plugins/out_azure_blob/azure_blob_uri.c (1)

137-162: LGTM: Consistent path_prefix handling in azb_uri_create_blob.

The implementation follows the same pattern as azb_append_blob_uri, properly computing effective_path and using it for URI construction with appropriate SAS token handling.

tests/internal/azure_blob.c (1)

42-89: Test fixture setup and teardown are well-structured.

The fixture properly initializes and cleans up resources (config, upstream, connection) in the correct order, with appropriate error handling during initialization.

plugins/out_azure_blob/azure_blob_blockblob.h (1)

26-43: LGTM: Block blob function signatures updated for path templating.

All three function declarations (azb_block_blob_blocklist_uri, azb_block_blob_uri, azb_block_blob_commit_block) consistently add the path_prefix parameter, aligning with the implementation and broader path templating support.

plugins/out_azure_blob/azure_blob_blockblob.c (4)

34-61: LGTM: Consistent path_prefix handling in blocklist URI builder.

The effective_path pattern is correctly applied, with proper fallback to ctx->path when path_prefix is NULL or empty.


63-124: LGTM: Block blob URI construction properly updated.

The function correctly handles both path-prefixed and non-prefixed cases, maintaining all existing functionality including timestamp handling, compression extensions, and SAS token appending.


354-366: LGTM: Commit block function properly propagates path_prefix.

The path_prefix parameter is correctly passed through to azb_block_blob_uri_commit.


447-447: Correct: NULL path_prefix for file parts commit.

Passing NULL here is appropriate since file parts committed via azb_block_blob_commit_file_parts use the stored path from ctx rather than dynamically resolved templating.

plugins/out_azure_blob/azure_blob.c (11)

184-254: LGTM: UUID replacement implementation is correct.

The function properly:

  • Counts occurrences before allocation
  • Returns the original path unchanged if no $UUID tokens exist (line 207)
  • Correctly calculates result length accounting for size difference between token and replacement
  • Properly frees the original path and returns the new SDS string

260-306: LGTM: Token replacement helper is well-implemented.

The function correctly handles edge cases (NULL input, token not found) and properly manages memory by destroying the input SDS and returning a new one.


311-347: LGTM: Time token expansion correctly chains replacements.

The function properly chains azb_simple_replace calls, which handle memory cleanup of intermediate SDS strings.


352-433: LGTM: strftime application with proper buffer growth.

The implementation correctly handles buffer sizing with safeguards against infinite loops (empty_threshold and 4096 byte limit). Memory is properly freed in all code paths.


438-466: LGTM: Slash trimming correctly modifies SDS in-place.

The function properly uses memmove for potentially overlapping memory regions and updates the SDS length metadata.


471-577: LGTM: Path resolution function with proper resource cleanup.

The function correctly handles:

  • Early return when templating is disabled
  • Fallback to current time when no timestamp provided
  • Sequential application of UUID, time tokens, strftime, and record accessor
  • Proper cleanup of msgpack and record accessor resources on all paths

579-601: LGTM: Blob creation wrapper with path resolution.

The function properly resolves the path prefix and cleans up on failure. Note that flb_sds_destroy already handles NULL safely, so the NULL check at line 588 is defensive but harmless.


895-1004: LGTM: send_blob properly manages path_prefix lifecycle.

The function correctly:

  • Resolves path_prefix at the beginning using the event timestamp
  • Passes path_prefix through all URI building and blob creation calls
  • Cleans up path_prefix on all exit paths (early returns and final cleanup)

691-691: Correct: delete_blob passes NULL for path_prefix.

Deletion uses the stored path from context rather than dynamically resolved templating, so NULL is appropriate here.


1722-1724: LGTM: Ingest callback uses azb_create_blob_with_tag.

The callback correctly uses the new wrapper function to resolve the path template when creating blobs.


2111-2113: LGTM: Flush callback uses azb_create_blob_with_tag.

Consistent integration with the path templating system.

@edsiper
Copy link
Copy Markdown
Member

edsiper commented Dec 2, 2025

@codex review

@edsiper edsiper added this to the Fluent Bit v4.2.1 milestone Dec 2, 2025
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
plugins/out_azure_blob/azure_blob.c (2)

161-178: UUID and time token helpers are sound, but %3N/%9N/%L only replace the first occurrence

The overall flow in azb_replace_uuid(), azb_simple_replace(), and azb_apply_time_tokens() looks correct:

  • $UUID is replaced with a single 8‑char random suffix consistently across all occurrences.
  • Memory ownership is clear: the incoming SDS is always either returned as-is or destroyed exactly once on success/failure.

One functional nit: azb_apply_time_tokens() uses azb_simple_replace(), which only replaces the first occurrence of each token. If a user puts %3N or %L multiple times in the path, only the first instance is expanded.

You can make token expansion robust for repeated tokens with a small loop around azb_simple_replace():

-static flb_sds_t azb_apply_time_tokens(flb_sds_t path, const struct flb_time *timestamp)
+static flb_sds_t azb_apply_time_tokens(flb_sds_t path, const struct flb_time *timestamp)
 {
@@
-    /* Replace %3N with milliseconds */
-    tmp = azb_simple_replace(path, "%3N", ms_buf);
-    if (!tmp) {
-        return NULL;
-    }
-    path = tmp;
+    /* Replace all %3N with milliseconds */
+    while (1) {
+        tmp = azb_simple_replace(path, "%3N", ms_buf);
+        if (tmp == path || !tmp) {
+            /* No more matches or allocation failure */
+            if (!tmp) {
+                return NULL;
+            }
+            break;
+        }
+        path = tmp;
+    }
@@
-    /* Replace %9N with nanoseconds */
-    tmp = azb_simple_replace(path, "%9N", ns_buf);
-    if (!tmp) {
-        return NULL;
-    }
-    path = tmp;
+    /* Replace all %9N with nanoseconds */
+    while (1) {
+        tmp = azb_simple_replace(path, "%9N", ns_buf);
+        if (tmp == path || !tmp) {
+            if (!tmp) {
+                return NULL;
+            }
+            break;
+        }
+        path = tmp;
+    }
@@
-    /* Replace %L with nanoseconds */
-    tmp = azb_simple_replace(path, "%L", ns_buf);
-    if (!tmp) {
-        return NULL;
-    }
-
-    return tmp;
+    /* Replace all %L with nanoseconds */
+    while (1) {
+        tmp = azb_simple_replace(path, "%L", ns_buf);
+        if (tmp == path || !tmp) {
+            if (!tmp) {
+                return NULL;
+            }
+            break;
+        }
+        path = tmp;
+    }
+
+    return path;

(Adjust the “no match” detection depending on how you prefer to signal “unchanged”; the main point is to loop until no further replacements.)

Also applies to: 184-254, 256-347


887-1007: send_blob: path templating integration is correct for logs but risky for BLOB parts

Positive points:

  • Calling azb_resolve_path() once per send_blob() and passing path_prefix through to azb_append_blob_uri(), azb_block_blob_uri(), azb_block_blob_commit_block(), and create_blob() is the right way to make all Azure operations path-templating-aware.
  • path_prefix ownership is handled carefully: only set via azb_resolve_path(), freed in all early-return and normal-exit paths.

Two concerns:

  1. BLOB uploads (FLB_EVENT_TYPE_BLOBS) also go through azb_resolve_path() with tag == NULL

    As noted in the azb_resolve_path() comment, this means:

    • flb_ra_translate() may see a null tag pointer if a user puts $TAG in the template.
    • Even if templates avoid $TAG, BLOB uploads will now start honoring time/UUID-based templating, which was not clearly part of the original behavior.

    If the intent is to support templating only for log-based uploads initially, you can defensively gate the resolve step:

  • flb_time_get(&now);
  • if (azb_resolve_path(ctx, tag, tag_len, &now, &path_prefix) != 0) {
  •    return FLB_RETRY;
    
  • }
  • flb_time_get(&now);
  • if (tag && tag_len > 0) {
  •    if (azb_resolve_path(ctx, tag, tag_len, &now, &path_prefix) != 0) {
    
  •        return FLB_RETRY;
    
  •    }
    
  • }

That keeps existing BLOB behavior unchanged while still enabling templating for logs.

2. **Potential path mismatch for multi-part BLOB commits**

For BLOBs (`FLB_EVENT_TYPE_BLOBS`), `send_blob()` builds block URIs via:

```c
uri = azb_block_blob_uri(ctx, path_prefix, name, block_id, 0, generated_random_string);

whereas azb_block_blob_commit_file_parts() later commits via:

uri = azb_block_blob_blocklist_uri(ctx, NULL, path);

So the PUT-block step uses path_prefix (when non-NULL) but the PUT-block-list commit is always called with a NULL path_prefix. If a user enables path templating and you do let BLOB traffic go through azb_resolve_path(), the commit step may target a different blob path than the blocks were written under.

If you do decide to support templating for BLOBs, you’ll likely need to persist the resolved path_prefix alongside the file metadata and pass it into azb_block_blob_commit_file_parts() so both flows use the same effective path.

Given the current PR scope, I recommend at least gating azb_resolve_path() on tag != NULL as above to avoid surprising BLOB behavior and potential mismatches.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9664f44 and 445283c.

📒 Files selected for processing (11)
  • plugins/out_azure_blob/azure_blob.c (19 hunks)
  • plugins/out_azure_blob/azure_blob.h (3 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.c (7 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_conf.c (3 hunks)
  • plugins/out_azure_blob/azure_blob_uri.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_uri.h (1 hunks)
  • tests/internal/CMakeLists.txt (2 hunks)
  • tests/internal/azure_blob_path.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/out_azure_blob/azure_blob_conf.c
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-08-31T12:46:11.940Z
Learnt from: ThomasDevoogdt
Repo: fluent/fluent-bit PR: 9277
File: .github/workflows/pr-compile-check.yaml:147-151
Timestamp: 2025-08-31T12:46:11.940Z
Learning: In fluent-bit CMakeLists.txt, the system library preference flags are defined as FLB_PREFER_SYSTEM_LIB_ZSTD and FLB_PREFER_SYSTEM_LIB_KAFKA with the FLB_ prefix.

Applied to files:

  • tests/internal/CMakeLists.txt
  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components such as ARROW/PARQUET (which use `#ifdef FLB_HAVE_ARROW` guards), ZSTD support is always available and doesn't need build-time conditionals. ZSTD headers are included directly without guards across multiple plugins and core components.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:55.855Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:52-56
Timestamp: 2025-08-29T06:24:55.855Z
Learning: ZSTD compression is always available in Fluent Bit and does not require conditional compilation guards. Unlike Arrow/Parquet which use #ifdef FLB_HAVE_ARROW guards, ZSTD is built unconditionally with flb_zstd.c included directly in src/CMakeLists.txt and a bundled ZSTD library at lib/zstd-1.5.7/.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:02.561Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:7-7
Timestamp: 2025-08-29T06:25:02.561Z
Learning: In Fluent Bit, ZSTD (zstandard) compression library is bundled directly in the source tree at `lib/zstd-1.5.7` and is built unconditionally as a static library. Unlike optional external dependencies, ZSTD does not use conditional compilation guards like `FLB_HAVE_ZSTD` and is always available. Headers like `<fluent-bit/flb_zstd.h>` can be included directly without guards.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:26.170Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:39-42
Timestamp: 2025-08-29T06:24:26.170Z
Learning: In Fluent Bit, ZSTD compression support is enabled by default and does not require conditional compilation guards (like #ifdef FLB_HAVE_ZSTD) around ZSTD-related code declarations and implementations.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components, ZSTD support is always available and doesn't need build-time conditionals.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:44.797Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:26-26
Timestamp: 2025-08-29T06:24:44.797Z
Learning: In Fluent Bit, ZSTD support is always available and enabled by default. The build system automatically detects and uses either the system libzstd library or builds the bundled ZSTD version. Unlike other optional dependencies like Arrow which use conditional compilation guards (e.g., FLB_HAVE_ARROW), ZSTD does not require conditional includes or build flags.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
🧬 Code graph analysis (8)
plugins/out_azure_blob/azure_blob.h (1)
plugins/out_azure_blob/azure_blob.c (1)
  • azb_resolve_path (471-577)
plugins/out_azure_blob/azure_blob_blockblob.h (1)
plugins/out_azure_blob/azure_blob_blockblob.c (3)
  • azb_block_blob_blocklist_uri (34-61)
  • azb_block_blob_uri (63-124)
  • azb_block_blob_commit_block (354-393)
tests/internal/azure_blob_path.c (3)
plugins/out_azure_blob/azure_blob.c (1)
  • azb_resolve_path (471-577)
include/fluent-bit/flb_time.h (1)
  • flb_time_set (75-79)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_create_blob (155-181)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
plugins/out_azure_blob/azure_blob_uri.c (2)
  • azb_uri_container (107-118)
  • azb_effective_path (137-153)
plugins/out_azure_blob/azure_blob_uri.h (1)
plugins/out_azure_blob/azure_blob_uri.c (2)
  • azb_uri_create_blob (155-181)
  • azb_effective_path (137-153)
plugins/out_azure_blob/azure_blob.c (3)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_create_blob (155-181)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-53)
plugins/out_azure_blob/azure_blob_blockblob.c (1)
  • azb_block_blob_uri (63-124)
plugins/out_azure_blob/azure_blob_uri.c (1)
src/flb_sds.c (1)
  • flb_sds_printf (336-387)
plugins/out_azure_blob/azure_blob_appendblob.h (1)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-53)
🔇 Additional comments (16)
plugins/out_azure_blob/azure_blob_appendblob.h (1)

26-28: Append-blob URI signature updated for path_prefix support

Function now takes const char *path_prefix, matching the implementation and enabling reuse of azb_effective_path without mutating the prefix.

tests/internal/CMakeLists.txt (2)

62-67: Conditional inclusion of azure_blob_path test is correct

azure_blob_path.c is only compiled when FLB_OUT_AZURE_BLOB is enabled, which aligns the test with the plugin’s availability and avoids build issues when the plugin is disabled.


227-229: Selective linking of azure_blob_path test against Azure Blob plugin

Linking flb-it-azure_blob_path with flb-plugin-out_azure_blob under the same FLB_OUT_AZURE_BLOB guard cleanly wires the test to the plugin without affecting other internal tests.

plugins/out_azure_blob/azure_blob.h (1)

27-27: New path-templating state and azb_resolve_path API look consistent

Including flb_time.h, adding path_templating_enabled, and declaring azb_resolve_path match the implementation in azure_blob.c and how the tests use the function (out_path either NULL or a heap-allocated flb_sds_t owned by the caller).

Also applies to: 66-66, 171-175

plugins/out_azure_blob/azure_blob_appendblob.c (1)

27-29: Append-blob URIs now honor effective_path and templated prefixes

Using azb_effective_path(ctx, path_prefix) and branching on a non-empty effective_path brings append-blob URIs in line with azb_uri_create_blob, correctly omitting the prefix when templating resolves to an empty path and still appending SAS tokens as before.

Also applies to: 32-32, 39-42

plugins/out_azure_blob/azure_blob_uri.h (1)

30-34: URI helper declarations aligned with path_prefix handling

azb_uri_create_blob and the new azb_effective_path declaration match their definitions and clearly expose a path-prefix–aware URI-building API for callers.

plugins/out_azure_blob/azure_blob_uri.c (1)

137-153: azb_effective_path semantics correctly separate templated and static paths

When path_templating_enabled is true, azb_effective_path always returns the caller-supplied path_prefix (including NULL for “no prefix”), so URIs never fall back to the raw template in ctx->path; when templating is disabled, it reuses path_prefix if non-empty and otherwise falls back to ctx->path, preserving existing behavior. azb_uri_create_blob then formats the URI from this effective_path in the expected way.

Also applies to: 155-170

tests/internal/azure_blob_path.c (1)

1-294: Comprehensive tests for Azure Blob path templating and effective URI behavior

The suite covers $TAG, $TAG[n], time tokens, single and repeated $UUID tokens (including equality across uses), the empty-resolution case where $TAG[5] yields NULL, and the resulting azb_uri_create_blob behavior when the resolved prefix is NULL; ctx_cleanup handles allocated SDS fields, so the tests exercise the new templating flow without obvious leaks.

plugins/out_azure_blob/azure_blob_blockblob.h (1)

26-34: Block-blob APIs extended with path_prefix consistently

Adding const char *path_prefix to the blocklist, per-block, and commit helpers matches the updated implementations and gives block blobs the same effective-path / templating behavior as append blobs.

Also applies to: 38-43

plugins/out_azure_blob/azure_blob_blockblob.c (2)

34-61: Blocklist URI now path-prefix aware; existing file-part commit behavior preserved

azb_block_blob_blocklist_uri() correctly introduces path_prefix and uses azb_effective_path() so log paths can honor per-record prefixes while still falling back when path_prefix == NULL. azb_block_blob_commit_file_parts() passing NULL keeps multi-part file commit using the container + configured base path only, which matches previous behavior for blob uploads. No functional or memory-management issues here.

Also applies to: 447-457


63-124: Block blob PUT/commit URIs correctly propagate path_prefix

The updated azb_block_blob_uri(), azb_block_blob_uri_commit(), and azb_block_blob_commit_block() consistently compute effective_path via azb_effective_path(ctx, path_prefix) and build URIs with or without the prefix. encoded_blockid is always freed, and no new leak or error path was introduced. Layout matches the append-blob and create-blob helpers, so path templating behavior stays uniform across blob types.

Also applies to: 126-165, 353-393

plugins/out_azure_blob/azure_blob.c (5)

34-38: New headers align with added functionality

Including flb_record_accessor.h and <string.h> matches the new use of record accessors, strstr, strlen, memcpy, etc. This is the right place to add them; no issues.


579-601: azb_create_blob_with_tag correctly couples per-tag path resolution with blob creation

azb_create_blob_with_tag() cleanly wraps:

  • Resolving a path_prefix via azb_resolve_path().
  • Passing that prefix into create_blob() so the blob is created under the same templated path that send_blob() uses.
  • Always destroying prefix on both success and failure.

The retry semantics (returning FLB_RETRY on resolution failure) are consistent with surrounding code.


603-683: create_blob refactor: better cleanup and path-prefix support

The new create_blob(struct flb_azure_blob *ctx, const char *path_prefix, char *name) implementation looks good:

  • Uses azb_uri_create_blob(ctx, path_prefix, name) so the create step and subsequent writes share the same path resolution logic.
  • Introduces a status variable and cleanup_create: label to ensure uri, the HTTP client, and the upstream connection are always released on all paths.
  • Returns FLB_RETRY where previously some error paths just returned a generic error, which should integrate better with the caller’s retry logic.

No functional issues spotted here.


685-760: delete_blob refactor mirrors create_blob and looks safe

delete_blob() now:

  • Uses azb_uri_create_blob(ctx, NULL, name) (no per-record prefix, matching previous behavior).
  • Uses a status variable plus cleanup_delete: to guarantee the HTTP client and upstream connection are released in all branches.
  • Returns FLB_RETRY on transport or HTTP-status errors, consistent with the rest of the plugin.

This refactor improves robustness without changing intended semantics.


1725-1733: Call sites of azb_create_blob_with_tag are consistent and correct

All places that previously did a “create blob then resend” dance now call azb_create_blob_with_tag():

  • cb_azure_blob_ingest (timer-based upload of buffered files).
  • ingest_all_chunks (startup replay).
  • Both buffered and non-buffered branches in cb_azure_blob_flush.

They correctly:

  • Pass the tag as both the logical blob name and the tag used for path templating.
  • Use flb_sds_len(tag_sds) / tag_len for the length.
  • Only resend when azb_create_blob_with_tag() returns FLB_OK.

This keeps the create + send behavior consistent with the new path templating model.

Also applies to: 1857-1860, 2029-2033, 2115-2127

Copy link
Copy Markdown

@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: 0

🧹 Nitpick comments (1)
plugins/out_azure_blob/azure_blob.c (1)

311-347: Note: Custom time tokens replace first occurrence only.

The azb_apply_time_tokens function uses azb_simple_replace, which only replaces the first occurrence of each token (%3N, %9N, %L). If a user specifies a path like logs/%3N/%3N, only the first %3N is replaced with milliseconds; the second remains as literal %3N and will be handled by strftime later (likely producing unexpected results).

This is acceptable because:

  • It's unusual to repeat the same precision token multiple times
  • Standard strftime tokens (like %Y) will still be replaced correctly in all occurrences by azb_apply_strftime

However, document this limitation in user-facing docs to avoid confusion.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 445283c and fc838e5.

📒 Files selected for processing (11)
  • plugins/out_azure_blob/azure_blob.c (19 hunks)
  • plugins/out_azure_blob/azure_blob.h (3 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.c (7 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_conf.c (3 hunks)
  • plugins/out_azure_blob/azure_blob_uri.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_uri.h (1 hunks)
  • tests/internal/CMakeLists.txt (2 hunks)
  • tests/internal/azure_blob_path.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/internal/CMakeLists.txt
  • plugins/out_azure_blob/azure_blob_uri.h
  • plugins/out_azure_blob/azure_blob_conf.c
  • plugins/out_azure_blob/azure_blob_appendblob.c
  • plugins/out_azure_blob/azure_blob_appendblob.h
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components such as ARROW/PARQUET (which use `#ifdef FLB_HAVE_ARROW` guards), ZSTD support is always available and doesn't need build-time conditionals. ZSTD headers are included directly without guards across multiple plugins and core components.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:55.855Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:52-56
Timestamp: 2025-08-29T06:24:55.855Z
Learning: ZSTD compression is always available in Fluent Bit and does not require conditional compilation guards. Unlike Arrow/Parquet which use #ifdef FLB_HAVE_ARROW guards, ZSTD is built unconditionally with flb_zstd.c included directly in src/CMakeLists.txt and a bundled ZSTD library at lib/zstd-1.5.7/.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-31T12:46:11.940Z
Learnt from: ThomasDevoogdt
Repo: fluent/fluent-bit PR: 9277
File: .github/workflows/pr-compile-check.yaml:147-151
Timestamp: 2025-08-31T12:46:11.940Z
Learning: In fluent-bit CMakeLists.txt, the system library preference flags are defined as FLB_PREFER_SYSTEM_LIB_ZSTD and FLB_PREFER_SYSTEM_LIB_KAFKA with the FLB_ prefix.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:02.561Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:7-7
Timestamp: 2025-08-29T06:25:02.561Z
Learning: In Fluent Bit, ZSTD (zstandard) compression library is bundled directly in the source tree at `lib/zstd-1.5.7` and is built unconditionally as a static library. Unlike optional external dependencies, ZSTD does not use conditional compilation guards like `FLB_HAVE_ZSTD` and is always available. Headers like `<fluent-bit/flb_zstd.h>` can be included directly without guards.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:26.170Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:39-42
Timestamp: 2025-08-29T06:24:26.170Z
Learning: In Fluent Bit, ZSTD compression support is enabled by default and does not require conditional compilation guards (like #ifdef FLB_HAVE_ZSTD) around ZSTD-related code declarations and implementations.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components, ZSTD support is always available and doesn't need build-time conditionals.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:44.797Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:26-26
Timestamp: 2025-08-29T06:24:44.797Z
Learning: In Fluent Bit, ZSTD support is always available and enabled by default. The build system automatically detects and uses either the system libzstd library or builds the bundled ZSTD version. Unlike other optional dependencies like Arrow which use conditional compilation guards (e.g., FLB_HAVE_ARROW), ZSTD does not require conditional includes or build flags.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
🧬 Code graph analysis (5)
plugins/out_azure_blob/azure_blob.h (1)
plugins/out_azure_blob/azure_blob.c (1)
  • azb_resolve_path (486-607)
tests/internal/azure_blob_path.c (4)
src/flb_sds.c (2)
  • flb_sds_destroy (389-399)
  • flb_sds_create (78-90)
plugins/out_azure_blob/azure_blob.c (1)
  • azb_resolve_path (486-607)
include/fluent-bit/flb_time.h (1)
  • flb_time_set (75-79)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_create_blob (155-181)
plugins/out_azure_blob/azure_blob_blockblob.c (1)
plugins/out_azure_blob/azure_blob_uri.c (2)
  • azb_uri_container (107-118)
  • azb_effective_path (137-153)
plugins/out_azure_blob/azure_blob_blockblob.h (1)
plugins/out_azure_blob/azure_blob_blockblob.c (3)
  • azb_block_blob_blocklist_uri (34-61)
  • azb_block_blob_uri (63-124)
  • azb_block_blob_commit_block (354-393)
plugins/out_azure_blob/azure_blob.c (8)
src/flb_sds.c (4)
  • flb_sds_create_size (92-95)
  • flb_sds_destroy (389-399)
  • flb_sds_create_len (58-76)
  • flb_sds_printf (336-387)
include/fluent-bit/flb_compat.h (1)
  • gmtime_r (75-81)
include/fluent-bit/flb_mem.h (1)
  • flb_free (126-128)
src/flb_record_accessor.c (3)
  • flb_ra_create (271-358)
  • flb_ra_translate (628-633)
  • flb_ra_destroy (232-248)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_create_blob (155-181)
src/flb_http_client.c (1)
  • flb_http_client_destroy (1688-1695)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-53)
plugins/out_azure_blob/azure_blob_blockblob.c (3)
  • azb_block_blob_uri (63-124)
  • azb_block_blob_id_blob (219-272)
  • azb_block_blob_commit_block (354-393)
🔇 Additional comments (11)
plugins/out_azure_blob/azure_blob.h (1)

27-27: LGTM: Clean header additions for path templating support.

The additions integrate well:

  • flb_time.h include provides timestamp types for azb_resolve_path
  • path_templating_enabled flag cleanly extends the context structure
  • azb_resolve_path signature is clear and follows Fluent Bit conventions (out-parameter for result, return int for status)

Also applies to: 66-66, 171-175

plugins/out_azure_blob/azure_blob_uri.c (1)

137-181: LGTM: Path-prefix aware URI construction is correct.

The azb_effective_path helper cleanly implements the fallback logic:

  • When path_templating_enabled is TRUE, honors the resolved path_prefix (even if NULL/empty)
  • Otherwise falls back to ctx->path

The azb_uri_create_blob correctly handles empty effective_path by building /<tag> URIs, which addresses the past review concern about empty templates falling back to unresolved literal paths.

tests/internal/azure_blob_path.c (1)

1-294: LGTM: Comprehensive test coverage for path templating.

The test suite validates all key scenarios:

  • Tag substitution ($TAG, $TAG[n])
  • Time token expansion (%Y, %m, %d, %3N, %9N, %L)
  • UUID generation and consistency
  • Edge cases (empty resolution, NULL prefix URI construction)

The ctx_cleanup helper ensures proper resource management between tests, and all tests follow a clear arrange-act-assert pattern.

plugins/out_azure_blob/azure_blob_blockblob.h (1)

26-43: LGTM: Block blob signatures correctly extended for path templating.

All three functions now accept const char *path_prefix, which correctly propagates the resolved path through the block blob URI and commit operations. The const qualifier appropriately indicates read-only access.

plugins/out_azure_blob/azure_blob_blockblob.c (1)

34-165: LGTM: Block blob implementation correctly propagates path_prefix.

All URI constructors (azb_block_blob_blocklist_uri, azb_block_blob_uri, azb_block_blob_uri_commit) consistently:

  • Accept path_prefix parameter
  • Compute effective_path via azb_effective_path(ctx, path_prefix)
  • Build URIs with /<effective_path>/<name> when non-empty, else /<name>
  • Preserve SAS token handling in all branches

The azb_block_blob_commit_block correctly forwards path_prefix through the commit flow.

Also applies to: 354-393

plugins/out_azure_blob/azure_blob.c (6)

157-178: LGTM: Random string generation for UUID tokens.

The generate_random_string_blob function correctly generates 8-character alphanumeric strings using a properly seeded PRNG combining multiple entropy sources.


184-254: LGTM: UUID replacement correctly replaces all occurrences.

The azb_replace_uuid function properly:

  • Counts all $UUID occurrences before generating the random value
  • Replaces all instances with the same 8-character string
  • Pre-calculates result length to avoid reallocation
  • Handles edge cases (no matches, memory allocation failures)

This ensures consistent UUID values across multiple tokens in a single path template.


352-448: LGTM: strftime handling with proper error checking.

The azb_apply_strftime function correctly:

  • Uses adaptive buffer growth for large format expansions
  • Treats out_len == 0 after retry loop as an explicit error (addresses past review comment)
  • Logs meaningful error messages for invalid or too-long templates
  • Handles resource cleanup on all error paths

486-607: LGTM: Path resolution orchestrates token expansion correctly.

The azb_resolve_path function properly:

  • Guards against NULL ctx->path when templating is enabled (addresses past review comment at lines 511-514)
  • Applies transformations in correct order: UUID → custom time tokens → strftime → tag expansion
  • Handles NULL tag by using empty string for record accessor (addresses past review comment at lines 581-584)
  • Cleans up all intermediate allocations on success and error paths
  • Returns NULL *out_path for empty resolved paths, allowing callers to distinguish "no prefix" from "error"

The per-call record accessor construction is noted in past reviews as a performance optimization opportunity (pre-create at config time). This is acceptable for the current PR and can be addressed in future work.


609-631: LGTM: Path-prefix propagation is consistent throughout blob operations.

The updates correctly propagate path_prefix:

  • azb_create_blob_with_tag resolves the path and forwards to create_blob
  • send_blob resolves the path at line 937 and passes it to all URI constructors and commit operations
  • All error paths properly clean up path_prefix allocations (lines 944, 956, 973, 996, 1034-1036)
  • delete_blob correctly passes NULL (deletion doesn't use templating)

Memory management is correct with cleanup on both success and error paths.

Also applies to: 633-713, 917-1039


1756-1758: LGTM: Call sites updated to use tag-aware blob creation.

All blob creation call sites in cb_azure_blob_ingest, ingest_all_chunks, and cb_azure_blob_flush correctly replaced direct create_blob calls with azb_create_blob_with_tag, which properly resolves the path template before creating the blob.

Also applies to: 1887-1889, 2059-2059, 2145-2147

@nberlee
Copy link
Copy Markdown
Contributor Author

nberlee commented Dec 10, 2025

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@nberlee
Copy link
Copy Markdown
Contributor Author

nberlee commented Dec 10, 2025

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/out_azure_blob/azure_blob_blockblob.c (1)

395-457: Templated paths for BLOB uploads likely still break block list commit

For buffered BLOB uploads (FLB_EVENT_TYPE_BLOBS):

  • send_blob() first resolves a per-call prefix via
    azb_resolve_path(ctx, tag, tag_len, &now, &path_prefix) (tag is NULL here) and passes that path_prefix into azb_block_blob_uri() when uploading each block.
  • Later, azb_block_blob_commit_file_parts() builds the block list URI as:
    uri = azb_block_blob_blocklist_uri(ctx, ctx->path, path);

Given azb_effective_path():

  • When ctx->path_templating_enabled == FLB_TRUE (any non-empty path), it always returns its path_prefix argument and never consults ctx->path.
  • In send_blob(), path_prefix is the resolved template (after $UUID, time tokens, strftime, record accessor).
  • In azb_block_blob_commit_file_parts(), path_prefix is the raw template string ctx->path (e.g. "logs/$TAG/%Y/%m/%d/$UUID"), with no resolution.

As a result, for BLOBS when path contains any templating tokens:

  • Data blocks are written under /resolved_prefix/<name>... (e.g. /logs/2025/12/10/…),
  • But the subsequent Put Block List is sent to /ctx->path/<name>?comp=blocklist (e.g. /logs/$TAG/%Y/%m/%d/$UUID/<name>?comp=blocklist),

so the commit will not see the uploaded blocks and the buffered blob can never finalize.

This doesn’t affect cases where path is static and has no tokens (raw and resolved prefixes coincide), but it does undermine the new templating feature for BLOBS.

Consider:

  • Either explicitly disabling path templating for BLOBS (documenting it and bypassing azb_resolve_path() / using plain ctx->path there), or
  • Storing a per-file resolved prefix when the BLOB file is first registered (e.g., in the DB alongside file_path) and passing that stored prefix into both send_blob() and azb_block_blob_commit_file_parts() so they target the same blob path.

At minimum, this deserves tests in azure_blob_path (or a companion test) that cover BLOBS with templated paths to avoid regressions.

🧹 Nitpick comments (6)
plugins/out_azure_blob/azure_blob_appendblob.h (1)

26-28: Append blob URI API extension is consistent with path-prefix design

The new azb_append_blob_uri(struct flb_azure_blob *ctx, const char *path_prefix, char *tag) matches the implementation and the broader azb_uri_create_blob / azb_effective_path pattern. Consider making tag a const char * in both declaration and definition in a follow‑up, since it is not modified.

plugins/out_azure_blob/azure_blob_conf.c (2)

23-23: flb_record_accessor include appears unused in this TU

azure_blob_conf.c no longer uses record accessor APIs after switching to a simple path_templating_enabled flag, so <fluent-bit/flb_record_accessor.h> can likely be dropped to avoid confusion and keep dependencies minimal.


817-817: Resetting templating flag on destroy is harmless but optional

Clearing ctx->path_templating_enabled in flb_azure_blob_conf_destroy is not strictly necessary because the whole context is freed immediately after, but it doesn’t hurt and keeps the teardown logic explicit.

plugins/out_azure_blob/azure_blob.c (3)

157-178: Avoid reseeding the global PRNG on every random string generation

generate_random_string_blob() calls srand() on each invocation:

unsigned int seed = (unsigned int)(time(NULL) ^ clock() ^ getpid());
srand(seed);

Since rand()/srand() are process‑global, this has a few drawbacks:

  • Concurrent calls from different threads will trample each other’s RNG state.
  • Frequent reseeding (especially within the same second) can reduce randomness and produce correlated IDs.

Consider:

  • Seeding once per process/worker (e.g., in cb_azure_blob_init or cb_worker_init), or
  • Using an existing Fluent Bit helper for random bytes / IDs instead of rand().

The rest of the function (bounded charset, explicit terminator) is fine.


256-347: Time-token expansion is correct but only handles the first occurrence per token

azb_apply_time_tokens() plus azb_simple_replace():

  • Correctly derive %3N (milliseconds) and %9N / %L (nanoseconds) from timestamp->tm.tv_nsec.
  • Replace each token at most once because azb_simple_replace() is deliberately “first occurrence only”.

If you expect templates like "logs/%3N/%3N" to replace both instances, you might consider looping until strstr() no longer finds the token. If single-occurrence semantics are acceptable (as the comments suggest), the current implementation is fine.


917-1038: send_blob(): path_prefix threading is coherent; minor dead branch remains

The updated send_blob():

  • Always calls azb_resolve_path() to compute path_prefix (a no‑op when templating is disabled).
  • Passes path_prefix into azb_append_blob_uri() / azb_block_blob_uri() and, for log-type blocks, into azb_block_blob_commit_block() and create_blob(), ensuring a single, consistent prefix is used for create, write, and commit.
  • Cleans up path_prefix in all exit paths, including early failures.

There is a small leftover:

void *payload_buf = data;
/* ... */
if (payload_buf != data) {
    flb_sds_destroy(payload_buf);
}

payload_buf is never reassigned in this function, and http_send_blob() frees its own compressed buffer internally, so this condition is always false and can be safely removed in a later cleanup.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc838e5 and a177b76.

📒 Files selected for processing (11)
  • plugins/out_azure_blob/azure_blob.c (19 hunks)
  • plugins/out_azure_blob/azure_blob.h (3 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.c (7 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_conf.c (3 hunks)
  • plugins/out_azure_blob/azure_blob_uri.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_uri.h (1 hunks)
  • tests/internal/CMakeLists.txt (2 hunks)
  • tests/internal/azure_blob_path.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • plugins/out_azure_blob/azure_blob.h
  • plugins/out_azure_blob/azure_blob_uri.c
  • tests/internal/azure_blob_path.c
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-31T12:46:11.940Z
Learnt from: ThomasDevoogdt
Repo: fluent/fluent-bit PR: 9277
File: .github/workflows/pr-compile-check.yaml:147-151
Timestamp: 2025-08-31T12:46:11.940Z
Learning: In fluent-bit CMakeLists.txt, the system library preference flags are defined as FLB_PREFER_SYSTEM_LIB_ZSTD and FLB_PREFER_SYSTEM_LIB_KAFKA with the FLB_ prefix.

Applied to files:

  • tests/internal/CMakeLists.txt
📚 Learning: 2025-08-29T06:25:02.561Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:7-7
Timestamp: 2025-08-29T06:25:02.561Z
Learning: In Fluent Bit, ZSTD (zstandard) compression library is bundled directly in the source tree at `lib/zstd-1.5.7` and is built unconditionally as a static library. Unlike optional external dependencies, ZSTD does not use conditional compilation guards like `FLB_HAVE_ZSTD` and is always available. Headers like `<fluent-bit/flb_zstd.h>` can be included directly without guards.

Applied to files:

  • plugins/out_azure_blob/azure_blob_conf.c
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components such as ARROW/PARQUET (which use `#ifdef FLB_HAVE_ARROW` guards), ZSTD support is always available and doesn't need build-time conditionals. ZSTD headers are included directly without guards across multiple plugins and core components.

Applied to files:

  • plugins/out_azure_blob/azure_blob_conf.c
🧬 Code graph analysis (4)
plugins/out_azure_blob/azure_blob_uri.h (1)
plugins/out_azure_blob/azure_blob_uri.c (2)
  • azb_uri_create_blob (155-181)
  • azb_effective_path (137-153)
plugins/out_azure_blob/azure_blob_blockblob.c (1)
plugins/out_azure_blob/azure_blob_uri.c (2)
  • azb_uri_container (107-118)
  • azb_effective_path (137-153)
plugins/out_azure_blob/azure_blob_blockblob.h (1)
plugins/out_azure_blob/azure_blob_blockblob.c (3)
  • azb_block_blob_blocklist_uri (34-61)
  • azb_block_blob_uri (63-124)
  • azb_block_blob_commit_block (354-393)
plugins/out_azure_blob/azure_blob.c (4)
src/flb_record_accessor.c (3)
  • flb_ra_create (271-358)
  • flb_ra_translate (628-633)
  • flb_ra_destroy (232-248)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_create_blob (155-181)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-53)
plugins/out_azure_blob/azure_blob_blockblob.c (1)
  • azb_block_blob_uri (63-124)
🔇 Additional comments (19)
tests/internal/CMakeLists.txt (2)

62-67: Azure blob path tests correctly gated on plugin build option

Conditionally adding azure_blob_path.c to UNIT_TESTS_FILES behind FLB_OUT_AZURE_BLOB matches the existing pattern for feature‑gated tests and prevents build issues when the plugin is disabled.


227-229: Linking azure_blob_path tests against the output plugin is appropriate

Restricting the extra link of flb-plugin-out_azure_blob to the flb-it-azure_blob_path test keeps other tests unaffected while ensuring the new path‑templating tests have the symbols they need.

plugins/out_azure_blob/azure_blob_uri.h (1)

30-34: Centralized path-prefix handling via azb_effective_path looks sound

Extending azb_uri_create_blob with const char *path_prefix and introducing azb_effective_path(...) cleanly separates “template resolution” (in azure_blob.c) from low-level URI assembly. Call sites now have to pass the already‑resolved prefix, which is satisfied by the new azb_resolve_path() flow.

plugins/out_azure_blob/azure_blob_conf.c (1)

586-599: Path sanitization and templating flag placement is correct

Running path sanitization after applying remote configuration and enabling ctx->path_templating_enabled only when the resulting path is non‑empty ensures:

  • remote overrides participate in templating,
  • trailing slashes are stripped once, and
  • no templating work is done when path is unset or becomes empty.

This also addresses the earlier concern about remote overrides not updating templating behavior.

plugins/out_azure_blob/azure_blob_appendblob.c (1)

27-46: Append blob URIs now honor resolved path_prefix correctly

Using azb_effective_path(ctx, path_prefix) and emitting either "/<effective_path>/<tag>?comp=appendblock" or "/<tag>?comp=appendblock" aligns append blob URIs with the new templating flow:

  • For templated paths, the resolved prefix from azb_resolve_path() is used.
  • For static/non‑templated paths, ctx->path remains the fallback via azb_effective_path.

SAS token handling is preserved.

plugins/out_azure_blob/azure_blob_blockblob.h (1)

26-43: Block blob APIs consistently extended with path_prefix

Adding const char *path_prefix to azb_block_blob_blocklist_uri, azb_block_blob_uri, and azb_block_blob_commit_block keeps the block-blob surface consistent with append-blob and generic blob URI creation. This matches the implementations in azure_blob_blockblob.c and allows all block operations to share the same resolved prefix.

plugins/out_azure_blob/azure_blob_blockblob.c (4)

34-61: Blocklist URI builder aligns with effective_path semantics

azb_block_blob_blocklist_uri() now mirrors the general pattern:

  • builds the container URI,
  • derives effective_path = azb_effective_path(ctx, path_prefix),
  • prefixes /effective_path/ when non-empty, and
  • appends ?comp=blocklist and SAS parameters.

This is consistent with how data-block URIs and commit URIs work and looks correct.


63-124: Block blob data URIs correctly incorporate path_prefix and compression

The updated azb_block_blob_uri():

  • encodes blockid,
  • selects .gz vs "" based on ctx->compress_blob,
  • uses effective_path = azb_effective_path(ctx, path_prefix) to decide whether to prepend a directory segment, and
  • maintains SAS token behavior.

This keeps data-block writes consistent with the new path templating model.


126-165: Commit URI uses effective_path consistently for log-type blocks

azb_block_blob_uri_commit() now also takes path_prefix and routes it through azb_effective_path, so for log-type block uploads the same resolved prefix used in azb_block_blob_uri() will be reused when committing via ?comp=blocklist.


353-393: Commit-block helper correctly threads path_prefix through to commit URI

azb_block_blob_commit_block() now takes const char *path_prefix and passes it through to azb_block_blob_uri_commit(). This ensures that, for log-type block uploads, the commit request targets the same blob path used for the individual blocks.

plugins/out_azure_blob/azure_blob.c (9)

34-38: New includes correctly cover record accessor and string helpers

Including <fluent-bit/flb_record_accessor.h> and <string.h> is appropriate now that azb_resolve_path() uses record accessors and functions like strstr, snprintf, and memmove.


180-254: UUID placeholder replacement is well-structured and ownership-safe

azb_replace_uuid():

  • Counts $UUID occurrences first, bails out early if there are none, and reuses the original SDS in that case.
  • Allocates a correctly-sized result (result_len + 1), copies segments around each token, and replaces each with the same 8‑char random suffix.
  • Frees the original path SDS only after the new one is successfully constructed.

This gives deterministic $UUID expansion per call and keeps memory ownership clear.


349-448: strftime application now fails fast on invalid or too-long formats

azb_apply_strftime():

  • Handles a provided timestamp or falls back to flb_time_get().
  • Grows the buffer incrementally up to a 4KB ceiling.
  • After the loop, explicitly treats out_len == 0 as an error, logs a clear message, frees all temporaries, and returns NULL instead of silently producing an empty path.

This addresses the earlier concern where bad formats would quietly erase the prefix. Memory handling on all paths looks correct.


453-481: Slash trimming helper is simple and robust

azb_trim_slashes() removes leading and trailing / in place while updating the SDS length, preventing double separators when concatenating with container URIs. It behaves sensibly for edge cases like all‑slash or empty paths.


483-607: azb_resolve_path() composes templated paths safely and defensively

The path resolution pipeline:

  1. Exits quickly when path_templating_enabled is false or ctx->path is NULL.
  2. Clones ctx->path into a working SDS.
  3. Applies, in order:
    • $UUID expansion (azb_replace_uuid),
    • custom time tokens (%3N, %9N, %L),
    • strftime() formatting.
  4. Builds a temporary empty msgpack map and a flb_record_accessor from the intermediate string, then uses flb_ra_translate() with a safe fallback for tag == NULL (empty string) to expand $TAG / $TAG[n].
  5. Trims leading/trailing slashes and treats an empty final string as “no prefix”, returning success with *out_path == NULL.

Error handling is consistent: every intermediate allocation (SDS, RA, msgpack buffers) is freed on failure, and callers can reliably distinguish “no template” from “hard failure” via the return code and *out_path.


609-631: azb_create_blob_with_tag correctly shares path resolution with create_blob

azb_create_blob_with_tag():

  • Resolves prefix via azb_resolve_path(ctx, tag, tag_len, NULL, &prefix).
  • Always destroys prefix after calling create_blob(), and propagates errors via FLB_RETRY.

This helper keeps create_blob() unaware of tags/templating while ensuring blob creation uses the exact same resolved prefix as uploads.


633-713: create_blob()’s new path_prefix-aware implementation and cleanup look correct

Key points in the updated create_blob():

  • Uses azb_uri_create_blob(ctx, path_prefix, name) so the same resolved prefix is applied as in append/block uploads.
  • On HTTP‑level failures sets status = FLB_RETRY and jumps to a single cleanup_create block that destroys the client, releases the connection, and frees uri once.
  • Early failures (no URI, no connection, no client) still bail out promptly without touching uninitialized resources.

This reduces duplication and keeps resource management clear.


715-790: delete_blob() mirrors the new cleanup pattern but always ignores path templating

The refactored delete_blob():

  • Uses the same status + cleanup_delete pattern as create_blob(), which simplifies resource cleanup.
  • Calls azb_uri_create_blob(ctx, NULL, name), i.e., it never passes a path_prefix.

Given azb_effective_path() returns its path_prefix verbatim when templating is enabled, this means deletes will always target /container/<name> regardless of ctx->path or any templating. Today this function is only used in the BLOB buffering path (stale/aborted files), not for log blobs, but it’s worth double‑checking whether BLOB users expect deletes to honor a configured path prefix as well.


1751-1762: CREATE_BLOB handling now correctly reuses templated prefixes

In cb_azure_blob_ingest(), ingest_all_chunks(), and the non-buffered cb_azure_blob_flush() paths, the CREATE_BLOB branch now calls:

ret = azb_create_blob_with_tag(ctx, tag_sds, (int) flb_sds_len(tag_sds), tag_sds);

(or the analogous call with event_chunk->tag), then retries send_blob().

This ensures blob creation uses the same resolved path_prefix (including $TAG, $UUID, and time tokens) as the subsequent upload, avoiding mismatches between the created blob location and where the data is written.

Also applies to: 1886-1892, 2144-2157

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@nberlee
Copy link
Copy Markdown
Contributor Author

nberlee commented Dec 15, 2025

@codex review

Copy link
Copy Markdown

@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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e382913 and 42a849e.

📒 Files selected for processing (13)
  • plugins/out_azure_blob/azure_blob.c (26 hunks)
  • plugins/out_azure_blob/azure_blob.h (3 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.c (1 hunks)
  • plugins/out_azure_blob/azure_blob_appendblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.c (8 hunks)
  • plugins/out_azure_blob/azure_blob_blockblob.h (1 hunks)
  • plugins/out_azure_blob/azure_blob_conf.c (2 hunks)
  • plugins/out_azure_blob/azure_blob_db.c (18 hunks)
  • plugins/out_azure_blob/azure_blob_db.h (9 hunks)
  • plugins/out_azure_blob/azure_blob_uri.c (2 hunks)
  • plugins/out_azure_blob/azure_blob_uri.h (1 hunks)
  • tests/internal/CMakeLists.txt (2 hunks)
  • tests/internal/azure_blob_path.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • plugins/out_azure_blob/azure_blob_uri.h
  • tests/internal/CMakeLists.txt
  • tests/internal/azure_blob_path.c
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components such as ARROW/PARQUET (which use `#ifdef FLB_HAVE_ARROW` guards), ZSTD support is always available and doesn't need build-time conditionals. ZSTD headers are included directly without guards across multiple plugins and core components.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
  • plugins/out_azure_blob/azure_blob.c
📚 Learning: 2025-08-29T06:24:55.855Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:52-56
Timestamp: 2025-08-29T06:24:55.855Z
Learning: ZSTD compression is always available in Fluent Bit and does not require conditional compilation guards. Unlike Arrow/Parquet which use #ifdef FLB_HAVE_ARROW guards, ZSTD is built unconditionally with flb_zstd.c included directly in src/CMakeLists.txt and a bundled ZSTD library at lib/zstd-1.5.7/.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:02.561Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:7-7
Timestamp: 2025-08-29T06:25:02.561Z
Learning: In Fluent Bit, ZSTD (zstandard) compression library is bundled directly in the source tree at `lib/zstd-1.5.7` and is built unconditionally as a static library. Unlike optional external dependencies, ZSTD does not use conditional compilation guards like `FLB_HAVE_ZSTD` and is always available. Headers like `<fluent-bit/flb_zstd.h>` can be included directly without guards.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-31T12:46:11.940Z
Learnt from: ThomasDevoogdt
Repo: fluent/fluent-bit PR: 9277
File: .github/workflows/pr-compile-check.yaml:147-151
Timestamp: 2025-08-31T12:46:11.940Z
Learning: In fluent-bit CMakeLists.txt, the system library preference flags are defined as FLB_PREFER_SYSTEM_LIB_ZSTD and FLB_PREFER_SYSTEM_LIB_KAFKA with the FLB_ prefix.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:26.170Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:39-42
Timestamp: 2025-08-29T06:24:26.170Z
Learning: In Fluent Bit, ZSTD compression support is enabled by default and does not require conditional compilation guards (like #ifdef FLB_HAVE_ZSTD) around ZSTD-related code declarations and implementations.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components, ZSTD support is always available and doesn't need build-time conditionals.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-08-29T06:24:44.797Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:26-26
Timestamp: 2025-08-29T06:24:44.797Z
Learning: In Fluent Bit, ZSTD support is always available and enabled by default. The build system automatically detects and uses either the system libzstd library or builds the bundled ZSTD version. Unlike other optional dependencies like Arrow which use conditional compilation guards (e.g., FLB_HAVE_ARROW), ZSTD does not require conditional includes or build flags.

Applied to files:

  • plugins/out_azure_blob/azure_blob.h
📚 Learning: 2025-10-23T07:43:16.216Z
Learnt from: cosmo0920
Repo: fluent/fluent-bit PR: 11059
File: plugins/in_tail/tail_file.c:1618-1640
Timestamp: 2025-10-23T07:43:16.216Z
Learning: In plugins/in_tail/tail_file.c, when truncate_long_lines is enabled and the buffer is full, the early truncation path uses `lines > 0` as the validation pattern to confirm whether process_content successfully processed content. This is intentional to track occurrences of line processing rather than byte consumption, and consuming bytes based on `processed_bytes > 0` would be overkill for this validation purpose.

Applied to files:

  • plugins/out_azure_blob/azure_blob_conf.c
🧬 Code graph analysis (6)
plugins/out_azure_blob/azure_blob.h (1)
plugins/out_azure_blob/azure_blob.c (2)
  • azb_resolve_path (544-665)
  • azb_commit_prefix_with_fallback (219-236)
plugins/out_azure_blob/azure_blob_db.h (1)
plugins/out_azure_blob/azure_blob_db.c (4)
  • azb_db_file_get_next_stale (546-609)
  • azb_db_file_part_uploaded (919-944)
  • azb_db_file_part_delivery_attempts (946-977)
  • azb_db_file_oldest_ready (979-1067)
plugins/out_azure_blob/azure_blob.c (3)
plugins/out_azure_blob/azure_blob_uri.c (1)
  • azb_uri_create_blob (165-200)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-62)
plugins/out_azure_blob/azure_blob_blockblob.c (1)
  • azb_block_blob_uri (63-124)
plugins/out_azure_blob/azure_blob_blockblob.c (1)
plugins/out_azure_blob/azure_blob_uri.c (2)
  • azb_uri_container (107-121)
  • azb_effective_path (147-163)
plugins/out_azure_blob/azure_blob_db.c (2)
src/flb_sqldb.c (1)
  • flb_sqldb_close (129-149)
lib/cfl/src/cfl_sds.c (2)
  • cfl_sds_create (113-125)
  • cfl_sds_destroy (127-137)
plugins/out_azure_blob/azure_blob_appendblob.h (1)
plugins/out_azure_blob/azure_blob_appendblob.c (1)
  • azb_append_blob_uri (27-62)
🔇 Additional comments (26)
plugins/out_azure_blob/azure_blob_uri.c (1)

116-119: LGTM!

The NULL checks for flb_sds_printf are correct, ensuring cleanup on allocation failures. The effective_path logic properly centralizes path resolution for URI construction.

Also applies to: 132-141, 179-196

plugins/out_azure_blob/azure_blob_db.c (3)

30-71: Well-designed migration logic.

The ensure_path_prefix_column function properly checks for column existence before attempting to add it, ensuring idempotent schema migration. The error handling includes proper statement cleanup on all paths.


287-291: Verify migration executes before statement preparation.

The migration call occurs after table creation and foreign key enablement but before prepared statements are created. This ensures the column exists when statements referencing it are prepared. Good ordering.


388-393: Correct NULL handling for path_prefix throughout database operations.

All database operations consistently:

  • Bind NULL when path_prefix is absent (insert)
  • Check for NULL before creating SDS (retrieval)
  • Initialize output to NULL on error paths
  • Include path_prefix in cleanup on allocation failures

The error handling ensures no leaks when path_prefix allocation fails after other fields are allocated.

Also applies to: 578-588, 648-658, 871-876

plugins/out_azure_blob/azure_blob_blockblob.c (5)

34-61: LGTM: Path prefix correctly threaded through blocklist URI construction.

The function now accepts path_prefix, determines the effective_path via azb_effective_path, and correctly incorporates it into the blocklist URI when present. SAS token handling is preserved.


63-124: LGTM: Block blob URI construction properly uses path prefix.

The function correctly determines effective_path from path_prefix and applies it consistently across all URI construction branches (with/without timestamp, with/without effective_path).


126-169: LGTM: Commit URI now includes path prefix with added safety checks.

The function properly incorporates path_prefix via azb_effective_path. The added null checks for ctx, tag, and str (Lines 136-138) improve robustness.


358-397: LGTM: Path prefix properly propagated to commit URI.

The function correctly forwards path_prefix to azb_block_blob_uri_commit, ensuring consistent path resolution throughout the commit flow.


399-464: LGTM: Block list commit now uses path prefix.

The function correctly forwards path_prefix to azb_block_blob_blocklist_uri at Line 453, addressing previous concerns about block list commits targeting incorrect blob paths.

plugins/out_azure_blob/azure_blob.c (17)

162-200: LGTM: Improved random string generation with proper fallback.

The rewritten implementation uses flb_random_bytes for cryptographic-quality randomness and gracefully falls back to a time-seeded PRNG if that fails. Memory management is correct, and the zero-length edge case is handled.


202-217: LGTM: Token detection helper is straightforward.

Simple utility to detect template tokens in paths. Null-safe and correctly identifies $ or % characters.


219-236: LGTM: Fallback logic addresses legacy buffer concerns.

This function correctly prioritizes db_prefix, then falls back to ctx->path only when safe (templating disabled or no tokens present). Returning NULL for templated paths without a resolved prefix prevents committing to incorrect blob locations, addressing the concerns in past reviews about legacy buffered uploads.


238-312: LGTM: UUID replacement correctly uses single random value.

All $UUID tokens in the path are replaced with the same 8-character random string, ensuring consistency. Memory management is correct (destroys input, returns new SDS), and the function handles allocation failures.


314-364: LGTM: Simple single-replacement helper is correct.

Replaces the first occurrence of token with replacement. Memory management is proper (destroys input, returns new SDS). Null-safe.


366-405: Time token expansion works correctly but note the single-replacement behavior.

The function expands %3N (milliseconds), %9N (nanoseconds), and %L (nanoseconds). Since azb_simple_replace only replaces the first occurrence, paths with multiple instances of the same time token will only have the first one expanded. This is likely acceptable but worth noting if users report unexpected behavior.


407-506: LGTM: strftime expansion with proper error handling for invalid formats.

Lines 481-492 correctly address the past review concern by treating out_len == 0 (invalid or too-long strftime format) as an error with explicit logging, rather than silently creating an empty path. Buffer growth and cleanup are correct.


541-665: LGTM: Path resolution with defensive null handling.

Lines 569-571 add a defensive check for NULL ctx->path when templating is enabled, and Lines 635-645 synthesize an empty string when tag is NULL (for BLOB uploads), both addressing previous review feedback. The resolution sequence (UUID → time tokens → strftime → record accessor → trim) is correct, and all resources are properly cleaned up on error paths.


667-747: LGTM: Blob creation now uses path prefix.

The function correctly accepts and forwards path_prefix to azb_uri_create_blob. The cleanup logic using goto and a status variable ensures resources are properly released on all exit paths.


749-826: LGTM: Blob deletion now includes path prefix.

The function now accepts and forwards path_prefix to azb_uri_create_blob at Line 760, addressing the previous concern about DELETE operations omitting the configured prefix for templated paths.


953-1089: LGTM: Blob upload with resolved path prefix and proper commit handling.

Lines 973-981 resolve the path prefix once if not provided, storing it in tmp_path_prefix. The function correctly propagates path_prefix through all URI construction calls. Lines 1065-1070 ensure that block uploads following blob creation are also committed, addressing the previous concern about uncommitted blocks after the CREATE_BLOB retry path. Memory management properly cleans up tmp_path_prefix on all exit paths.


1385-1424: LGTM: Blob chunk processing resolves and persists path prefix.

Lines 1393-1407 resolve the path prefix for each blob file using the event timestamp, and Line 1410 stores it in the database via azb_db_file_insert. This ensures that multi-part blob uploads can be committed with the correct resolved prefix. Cleanup of path_prefix is correct.


1461-1762: LGTM: File upload callback comprehensively handles path prefixes.

The callback now retrieves path_prefix from the database for all blob operations (stale cleanup at Line 1496, aborted cleanup at Line 1523, commit at Line 1574, and part upload at Line 1652). Line 1585 uses azb_commit_prefix_with_fallback to safely handle NULL prefixes from legacy database rows, addressing previous concerns. All path_prefix variables are properly cleaned up.


1872-1872: LGTM: Blob ingestion delegates path resolution to send_blob.

The call site passes NULL for resolved_path_prefix, allowing send_blob to resolve the path once internally and use it consistently throughout the upload and commit flow.


1993-1994: LGTM: Chunk ingestion delegates path resolution to send_blob.

Passing NULL for resolved_path_prefix is correct; send_blob will resolve the path internally at Lines 973-981.


2157-2158: LGTM: Buffered flush delegates path resolution.

The buffered upload path correctly passes NULL for resolved_path_prefix, relying on send_blob to resolve the path. Note that the outer CREATE_BLOB retry logic has been removed, eliminating the risk of double path resolution mentioned in past reviews.


2237-2237: LGTM: Non-buffered flush delegates path resolution.

Consistent with other call sites, this passes NULL for resolved_path_prefix, allowing send_blob to handle path resolution internally.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@nberlee
Copy link
Copy Markdown
Contributor Author

nberlee commented Dec 15, 2025

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@nberlee
Copy link
Copy Markdown
Contributor Author

nberlee commented Dec 15, 2025

@edsiper I fixed all codex and coderabbit findings

@nberlee
Copy link
Copy Markdown
Contributor Author

nberlee commented Mar 22, 2026

Rebase to resolve merge conflicts

nberlee added 2 commits March 22, 2026 20:34
Signed-off-by: Nico Berlee <nico.berlee@on2it.net>
fixes fluent#7515

Signed-off-by: Nico Berlee <nico.berlee@on2it.net>
@edsiper
Copy link
Copy Markdown
Member

edsiper commented Apr 1, 2026

Thanks for the patience and work on this. Merging it.

@edsiper edsiper merged commit 3fbb894 into fluent:master Apr 1, 2026
42 of 46 checks passed
nberlee added a commit to nberlee/fluent-bit-docs that referenced this pull request Apr 1, 2026
(refs fluent/fluent-bit#11178)

Signed-off-by: Nico Berlee <nico.berlee@on2it.net>
eschabell pushed a commit to fluent/fluent-bit-docs that referenced this pull request Apr 1, 2026
(refs fluent/fluent-bit#11178)

Signed-off-by: Nico Berlee <nico.berlee@on2it.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support key format strings for Azure Blob as supported on Amazon S3

2 participants