Skip to content

Conversation

@alecholmes
Copy link
Contributor

@alecholmes alecholmes commented Aug 15, 2025

Problem

The fleet plugin polls a backend for the latest config. Due to the backend consisting of multiple processes, each with its own in-memory fleet config cache, the fleet plugin may encounter out-of-order configs until caches cohere.

Example:

  • Config stored in server db is X
  • User updates config to Y (saved in server db)
  • Fleet client polls backend, gets X back (it hit process P1 where X is cached)
  • Fleet client polls backend, gets Y back (it hit process P2 where X is not cached)
  • Fleet client polls backend, gets X back (it hit process P1 where X is still cached)
  • Server cache timeout period passes, so all future calls to the backend return Y

Change

This updates the fleet config fetch logic to ignore received files with timestamps at or before any locally saved configs. This is fairly straightforward since the server sends a last modified timestamp and our local config file naming scheme is timestamp-based.

cc @pwhelan who did an initial review here.


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
  • Debug log output from testing the change (see comment)
  • Attached Valgrind output that shows no leaks or memory corruption was found (see comment)

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

  • Run local packaging test showing all targets (including any new ones) build.
  • Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

  • Documentation required for this feature

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

  • Bug Fixes

    • Prevents creating fleet config files when an equal or newer timestamp already exists by scanning existing timestamped files before writing.
    • Respects Last-Modified timestamps to only write truly newer configurations, reducing unnecessary disk writes and duplicates.
    • Improves debug/info logging for skipped creations and successful file generation to aid troubleshooting.
  • Refactor

    • Centralized and hardened timestamp comparison logic to enforce strict newer-only writes.
  • Documentation

    • Clarified timestamp-checking behavior in an internal docstring.

@coderabbitai
Copy link

coderabbitai bot commented Aug 15, 2025

Walkthrough

Adds timestamp-aware gating for fleet config files: new helper parses numeric timestamps from config filenames, scans existing timestamped files, and requires an incoming Last-Modified timestamp to be strictly newer before creating a timestamped config file. No public API changes.

Changes

Cohort / File(s) Summary of Changes
Fleet config timestamp gating
plugins/in_calyptia_fleet/in_calyptia_fleet.c
Added #include <errno.h> and <limits.h> and a forward declaration for read_glob; implemented fleet_config_path_timestamp(...) (returns numeric timestamp or 0) with docstring; replaced boolean path checks with numeric comparisons; added check_timestamp_is_newer(...) to glob existing *.conf/*.yaml, extract timestamps and verify incoming timestamp is strictly newer; expanded get_calyptia_file(...) signature to accept dst and time_last_modified, compute timestamped filenames when dst is NULL, abort creation when timestamp isn't newer, and propagate time_last_modified; updated call sites (e.g., get_calyptia_files) to pass new params; added debug/info logs and ensured resource cleanup on error.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant FleetPlugin as get_calyptia_file
    participant Checker as check_timestamp_is_newer
    participant FS as Filesystem

    Client->>FleetPlugin: Request config URL + Last-Modified header
    FleetPlugin->>Checker: Is Last-Modified strictly newer?
    Checker->>FS: Glob files (*.conf / *.yaml)
    FS-->>Checker: File list
    Checker->>Checker: Extract numeric timestamps
    Checker-->>FleetPlugin: FLB_TRUE / FLB_FALSE
    alt Newer
        FleetPlugin->>FS: Create timestamped config file (time-based name)
        FS-->>FleetPlugin: Creation result
    else Not newer
        FleetPlugin-->>Client: Skip creation (debug log)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I twitch my nose at ticking time,
Only newer moments earn my rhyme.
Old configs sleep beneath the loam,
I hop and write a fresher home. 🐰⌚️

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Status, Documentation and Community

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

@alecholmes
Copy link
Contributor Author

Valgrind output. The Conditional jump or move depends on uninitialised value(s) is a longstanding issue unrelated to my change.

==1156907== Memcheck, a memory error detector
==1156907== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1156907== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1156907== Command: /home/alec/dev/fluent-bit/build/bin/fluent-bit --config local.yaml
==1156907==
Fluent Bit v4.1.0
* Copyright (C) 2015-2025 The Fluent Bit Authors
* Fluent Bit is a CNCF sub-project under the umbrella of Fluentd
* https://fluentbit.io

______ _                  _    ______ _ _             ___  _____
|  ___| |                | |   | ___ (_) |           /   ||  _  |
| |_  | |_   _  ___ _ __ | |_  | |_/ /_| |_  __   __/ /| || |/' |
|  _| | | | | |/ _ \ '_ \| __| | ___ \ | __| \ \ / / /_| ||  /| |
| |   | | |_| |  __/ | | | |_  | |_/ / | |_   \ V /\___  |\ |_/ /
\_|   |_|\__,_|\___|_| |_|\__| \____/|_|\__|   \_/     |_(_)___/


[2025/08/15 12:51:00.522259185] [ info] [fluent bit] version=4.1.0, commit=420ab74d0c, pid=1156907
[2025/08/15 12:51:00.562978471] [ info] [custom:calyptia:calyptia.0] read UUID (be1831c6-4b82-4323-90e3-3a06741ab925) from file: /tmp/calyptia-fleet/machine-id.conf
[2025/08/15 12:51:00.736185947] [ info] [custom:calyptia:calyptia.0] custom initialized!
[2025/08/15 12:51:00.741206298] [ info] [storage] ver=1.5.3, type=memory, sync=normal, checksum=off, max_chunks_up=128
[2025/08/15 12:51:00.741862978] [ info] [simd    ] disabled
[2025/08/15 12:51:00.742316654] [ info] [cmetrics] version=1.0.5
[2025/08/15 12:51:00.742730538] [ info] [ctraces ] version=0.6.6
[2025/08/15 12:51:00.755799261] [ info] [input:fluentbit_metrics:fluentbit_metrics.0] initializing
[2025/08/15 12:51:00.756752573] [ info] [input:fluentbit_metrics:fluentbit_metrics.0] storage_strategy='memory' (memory only)
[2025/08/15 12:51:00.898149027] [ info] [input:calyptia_fleet:calyptia_fleet.1] initializing
[2025/08/15 12:51:00.898389366] [ info] [input:calyptia_fleet:calyptia_fleet.1] storage_strategy='memory' (memory only)
[2025/08/15 12:51:00.899364302] [ info] [input:calyptia_fleet:calyptia_fleet.1] initializing calyptia fleet input.
[2025/08/15 12:51:00.920911531] [ info] [input:calyptia_fleet:calyptia_fleet.1] loading configuration from /tmp/calyptia-fleet/4803d408a0d43a9281ef4ae7720dfd7a23003204d98a4a4ffedca2f036db7206/hello/cur.conf.
[2025/08/15 12:51:00.922307685] [ info] [input:calyptia_fleet:calyptia_fleet.1] changing to config dir: /tmp/calyptia-fleet/4803d408a0d43a9281ef4ae7720dfd7a23003204d98a4a4ffedca2f036db7206/hello/1755312617
[2025/08/15 12:51:00.963190598] [ info] [sp] stream processor started
[2025/08/15 12:51:00.966329204] [ info] [engine] Shutdown Grace Period=5, Shutdown Input Grace Period=2
[2025/08/15 12:51:05] [engine] caught signal (SIGHUP)
[2025/08/15 12:51:06.983456566] [ info] reloading instance pid=1156907 tid=0x4852020
[2025/08/15 12:51:07.11055501] [ info] [reload] stop everything of the old context
[2025/08/15 12:51:07.13383715] [ warn] [engine] service will shutdown when all remaining tasks are flushed
[2025/08/15 12:51:07.14515821] [ info] [input] pausing fluentbit_metrics.0
[2025/08/15 12:51:07.15371381] [ info] [input] pausing calyptia_fleet.1
[2025/08/15 12:51:07.536786678] [ info] [engine] service has stopped (0 pending tasks)
[2025/08/15 12:51:07.537155310] [ info] [input] pausing fluentbit_metrics.0
[2025/08/15 12:51:07.537370148] [ info] [input] pausing calyptia_fleet.1
[2025/08/15 12:51:07.588988446] [ info] [reload] start everything
[2025/08/15 12:51:07.590673855] [ info] [fluent bit] version=4.1.0, commit=420ab74d0c, pid=1156907
[2025/08/15 12:51:07.591565665] [ info] [custom:calyptia:calyptia.0] read UUID (be1831c6-4b82-4323-90e3-3a06741ab925) from file: /tmp/calyptia-fleet/machine-id.conf
[2025/08/15 12:51:07.599324864] [ info] [custom:calyptia:calyptia.0] custom initialized!
[2025/08/15 12:51:07.599471159] [ info] [storage] ver=1.5.3, type=memory, sync=normal, checksum=off, max_chunks_up=128
[2025/08/15 12:51:07.599563411] [ info] [simd    ] disabled
[2025/08/15 12:51:07.599644163] [ info] [cmetrics] version=1.0.5
[2025/08/15 12:51:07.599724123] [ info] [ctraces ] version=0.6.6
[2025/08/15 12:51:07.601054483] [ info] [input:dummy:dummy.0] initializing
[2025/08/15 12:51:07.601177652] [ info] [input:dummy:dummy.0] storage_strategy='memory' (memory only)
[2025/08/15 12:51:07.613014601] [ info] [input:fluentbit_metrics:fluentbit_metrics.1] initializing
[2025/08/15 12:51:07.613159770] [ info] [input:fluentbit_metrics:fluentbit_metrics.1] storage_strategy='memory' (memory only)
[2025/08/15 12:51:07.626139617] [ info] [input:calyptia_fleet:calyptia_fleet.2] initializing
[2025/08/15 12:51:07.626313121] [ info] [input:calyptia_fleet:calyptia_fleet.2] storage_strategy='memory' (memory only)
[2025/08/15 12:51:07.626462957] [ info] [input:calyptia_fleet:calyptia_fleet.2] initializing calyptia fleet input.
[2025/08/15 12:51:07.639953189] [ info] [input:calyptia_fleet:calyptia_fleet.2] fleet collector initialized with interval: 5 sec 0 nsec
[2025/08/15 12:51:07.706010323] [ info] [output:stdout:stdout.0] worker #0 started
[2025/08/15 12:51:08.456849487] [ info] [output:calyptia:calyptia.1] connected to Calyptia, agent_id='1207ac86-e1d7-48ce-8b1c-359b3b4e2c38'
[2025/08/15 12:51:08.469031318] [ info] [output:calyptia:calyptia.1] agent registration successful
[2025/08/15 12:51:08.470697060] [ info] [sp] stream processor started
[2025/08/15 12:51:08.470929607] [ info] [engine] Shutdown Grace Period=5, Shutdown Input Grace Period=2
[0] dummy.0: [[1755287468.536862529, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287469.538228531, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287470.535299113, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287471.535813806, {}], {"message"=>"dummy-v2"}]
[2025/08/15 12:51:12.976106639] [ info] [input:calyptia_fleet:calyptia_fleet.2] not creating file with timestamp 1755312617 since it is not newer than existing files
[0] dummy.0: [[1755287472.731787678, {}], {"message"=>"dummy-v2"}]
==1156907== Thread 2 flb-pipeline:
==1156907== Conditional jump or move depends on uninitialised value(s)
==1156907==    at 0x28283C: output_pre_cb_flush (flb_output.h:682)
==1156907==    by 0x152C453: co_switch (aarch64.c:133)
==1156907==    by 0xFFFFFFFFFFFFFFFF: ???
==1156907==  Uninitialised value was created by a heap allocation
==1156907==    at 0x4865058: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==1156907==    by 0x2C6073: flb_malloc (flb_mem.h:80)
==1156907==    by 0x2C7087: flb_task_create (flb_task.c:422)
==1156907==    by 0x2C1B8F: flb_engine_dispatch (flb_engine_dispatch.c:311)
==1156907==    by 0x2BAA07: flb_engine_flush (flb_engine.c:175)
==1156907==    by 0x2BC4EF: flb_engine_handle_event (flb_engine.c:580)
==1156907==    by 0x2BC4EF: flb_engine_start (flb_engine.c:1003)
==1156907==    by 0x23A6F3: flb_lib_worker (flb_lib.c:835)
==1156907==    by 0x50DD5B7: start_thread (pthread_create.c:442)
==1156907==    by 0x5145EDB: thread_start (clone.S:79)
==1156907==
[0] dummy.0: [[1755287473.540568894, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287474.536181321, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287475.535880748, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287476.535456797, {}], {"message"=>"dummy-v2"}]
[2025/08/15 12:51:17.765647822] [ info] [input:calyptia_fleet:calyptia_fleet.2] not creating file with timestamp 1755312617 since it is not newer than existing files
[0] dummy.0: [[1755287477.537935031, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287478.534827317, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287479.535325343, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287480.536359714, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287481.536223894, {}], {"message"=>"dummy-v2"}]
[2025/08/15 12:51:22.751935791] [ info] [input:calyptia_fleet:calyptia_fleet.2] not creating file with timestamp 1755312617 since it is not newer than existing files
[0] dummy.0: [[1755287482.547349928, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287483.535864628, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287484.536138941, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287485.535178771, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287486.536445355, {}], {"message"=>"dummy-v2"}]
[2025/08/15 12:51:27.783271259] [ info] [input:calyptia_fleet:calyptia_fleet.2] not creating file with timestamp 1755312617 since it is not newer than existing files
[0] dummy.0: [[1755287487.544901501, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287488.535402366, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287489.535115919, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287490.535504901, {}], {"message"=>"dummy-v2"}]
[0] dummy.0: [[1755287491.535992594, {}], {"message"=>"dummy-v2"}]
[2025/08/15 12:51:33.97791186] [ info] [input:calyptia_fleet:calyptia_fleet.2] not creating file with timestamp 1755312617 since it is not newer than existing files
^C[2025/08/15 12:51:33] [engine] caught signal (SIGINT)
[0] dummy.0: [[1755287492.537632435, {}], {"message"=>"dummy-v2"}]
[2025/08/15 12:51:33.402123491] [ warn] [engine] service will shutdown in max 5 seconds
[2025/08/15 12:51:33.404681418] [ info] [input] pausing dummy.0
[2025/08/15 12:51:33.405047634] [ info] [input] pausing fluentbit_metrics.1
[2025/08/15 12:51:33.405203012] [ info] [input] pausing calyptia_fleet.2
[2025/08/15 12:51:33.534630515] [ info] [engine] service has stopped (0 pending tasks)
[2025/08/15 12:51:33.534878646] [ info] [input] pausing dummy.0
[2025/08/15 12:51:33.535092733] [ info] [input] pausing fluentbit_metrics.1
[2025/08/15 12:51:33.535291029] [ info] [input] pausing calyptia_fleet.2
[2025/08/15 12:51:33.537725287] [ info] [output:stdout:stdout.0] thread worker #0 stopping...
[2025/08/15 12:51:33.540782224] [ info] [output:stdout:stdout.0] thread worker #0 stopped
==1156907==
==1156907== HEAP SUMMARY:
==1156907==     in use at exit: 0 bytes in 0 blocks
==1156907==   total heap usage: 44,180 allocs, 44,180 frees, 22,466,535 bytes allocated
==1156907==
==1156907== All heap blocks were freed -- no leaks are possible
==1156907==
==1156907== For lists of detected and suppressed errors, rerun with: -s
==1156907== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (1)

1088-1104: Fix HTTP date parsing and avoid parsing a non-terminated buffer; treat “not newer” as non-error

  • HTTP Last-Modified is RFC 1123 (e.g., “Mon, 02 Jan 2006 …”), so month should be %b (abbrev), not %B (full). Parsing with %B can silently fail and yield a 0 timestamp.
  • fbit_last_modified is not null-terminated; copy and terminate before flb_strptime to avoid reading past CRLF.
  • Returning -1 for the “not newer” path overloads error semantics. Returning 0 makes it clear to callers that nothing was created but no error occurred.

Apply this diff:

-        flb_strptime(fbit_last_modified, "%a, %d %B %Y %H:%M:%S GMT", &tm_last_modified);
-        last_modified = mktime(&tm_last_modified.tm);
+        /* Copy and null-terminate header before parsing */
+        char *lm_buf = flb_malloc((size_t) fbit_last_modified_len + 1);
+        if (lm_buf == NULL) {
+            ret = -1;
+            goto client_error;
+        }
+        memcpy(lm_buf, fbit_last_modified, (size_t) fbit_last_modified_len);
+        lm_buf[fbit_last_modified_len] = '\0';
+
+        /* RFC 1123: abbreviated month name (%b) */
+        if (flb_strptime(lm_buf, "%a, %d %b %Y %H:%M:%S GMT", &tm_last_modified) == NULL) {
+            flb_plg_warn(ctx->ins, "failed to parse Last-Modified header: %s", lm_buf);
+            flb_free(lm_buf);
+            ret = -1;
+            goto client_error;
+        }
+        flb_free(lm_buf);
+        last_modified = mktime(&tm_last_modified.tm);

And consider making the “not newer” return neutral:

-            ret = -1;
+            ret = 0;
             goto client_error;
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c51a9e4 and f941a6b.

📒 Files selected for processing (1)
  • plugins/in_calyptia_fleet/in_calyptia_fleet.c (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: PR - fuzzing test
  • GitHub Check: pr-compile-centos-7
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
🔇 Additional comments (1)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (1)

67-67: Forward declaration for read_glob is appropriate

This resolves earlier references and avoids implicit declaration warnings. Signature matches both platform-specific implementations below.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (3)

323-361: Avoid 32-bit truncation: return time_t from fleet_config_path_timestamp()

The function parses a timestamp into a long, but returns int. This downcast risks truncation on platforms where time_t/long exceed 32 bits (2038+ and/or LLP64). Returning time_t aligns with the semantic intent and avoids narrowing.

Apply:

-/**
- * Returns the timestamp of the fleet config file if it is a timestamped file,
- * or 0 if it is not a timestamped file.
- */
-static int fleet_config_path_timestamp(struct flb_in_calyptia_fleet_config *ctx, const char *path)
+/**
+ * Returns the timestamp of the fleet config file if it is a timestamped file,
+ * or 0 if it is not a timestamped file.
+ */
+static time_t fleet_config_path_timestamp(struct flb_in_calyptia_fleet_config *ctx, const char *path)
 {
     char *fname;
     char *end;
     long val;
@@
-    if (ctx->fleet_config_legacy_format) {
+    if (ctx->fleet_config_legacy_format) {
         if (strcmp(end, ".conf") == 0) {
-           return val;
+           return (time_t) val;
         }
     }
     else if (strcmp(end, ".yaml") == 0) {
-        return val;
+        return (time_t) val;
     }
 
     return 0;
 }

Follow-up: Update any local variables that store this return value to time_t (see suggestion below in check_timestamp_is_newer()).


973-1042: Tighten types, remove unused vars, and confirm glob-failure semantics

  • file_timestamp should be time_t to match the value being compared (and to match the proposed return type).
  • ext, fname, path_copy are unused; remove them to avoid warnings and improve clarity.
  • Semantics: treating a glob failure as “no existing files” (return FLB_TRUE) is acceptable for resilience, but it means we may accept older configs if directory reads fail. If that’s intended, consider a short comment to document it.

Apply:

 static int check_timestamp_is_newer(struct flb_in_calyptia_fleet_config *ctx, time_t new_timestamp)
 {
     flb_sds_t base_dir = NULL;
     flb_sds_t glob_pattern = NULL;
     struct cfl_array *files = NULL;
     size_t idx;
     int ret;
-    long file_timestamp;
-    char *ext;
-    char *fname;
-    char *path_copy = NULL;
+    time_t file_timestamp;
     const char *file_extension;
@@
-    files = read_glob(glob_pattern);
+    files = read_glob(glob_pattern);
     if (files == NULL) {
-        /* No existing files found - could be empty directory or glob failure */
+        /* No existing files found or glob failure; treat as “newer” to stay resilient */
         flb_plg_debug(ctx->ins, "no existing config files found in %s", base_dir);
         flb_sds_destroy(base_dir);
         flb_sds_destroy(glob_pattern);
         return FLB_TRUE;
     }
@@
-        file_timestamp = fleet_config_path_timestamp(ctx, files->entries[idx]->data.as_string);
+        file_timestamp = fleet_config_path_timestamp(ctx, files->entries[idx]->data.as_string);
         if (file_timestamp == 0) {
             continue;
         }
 
         /* Check if existing file timestamp is greater than or equal to new timestamp */
-        if (file_timestamp >= (long)new_timestamp) {
+        if (file_timestamp >= new_timestamp) {
             flb_plg_debug(ctx->ins,
                           "existing file with timestamp %ld >= new timestamp %ld",
-                          file_timestamp, (long)new_timestamp);
+                          (long) file_timestamp, (long) new_timestamp);
             ret = FLB_FALSE;
             break;
         }
     }

Optional: for performance, you could compare only against the newest timestamped file (via calyptia_config_get_newest()) instead of scanning all entries.


1081-1092: Return a non-error when skipping older/equal config

When the incoming Last-Modified is not strictly newer, this is a normal “no-op,” not an error. Prefer returning 0 over -1 to avoid conflating expected behavior with failure in upstream callers or metrics.

Apply:

-        if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
+        if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
             flb_plg_debug(ctx->ins, "not creating file with timestamp %ld since it is not newer than existing files",
                          (long)last_modified);
-            ret = -1;
+            ret = 0;
             goto client_error;
         }
         else {
             flb_plg_info(ctx->ins, "creating config file with timestamp %ld",
                          (long)last_modified);
         }
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f941a6b and e2b4767.

📒 Files selected for processing (1)
  • plugins/in_calyptia_fleet/in_calyptia_fleet.c (7 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (2)
src/flb_sds.c (3)
  • flb_sds_create_size (92-95)
  • flb_sds_destroy (389-399)
  • flb_sds_printf (336-387)
lib/cfl/src/cfl_array.c (1)
  • cfl_array_destroy (51-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: PR - fuzzing test
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-centos-7
🔇 Additional comments (4)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (4)

67-67: Forward declaration for read_glob is correct and necessary

This unblocks earlier call sites across POSIX/Windows variants. No issues.


373-374: Switch to timestamp check via fleet_config_path_timestamp() looks good

Using a numeric timestamp check (> 0) is clearer than a boolean filename check.


1446-1448: Good switch to numeric timestamp check in delete_old

Filtering by fleet_config_path_timestamp(...) > 0 avoids accidental deletions of non-conforming files.


1512-1515: Newest-config selection now properly guards with timestamp parsing

Using fleet_config_path_timestamp(...) > 0 keeps the selection restricted to timestamped files. Looks good.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (2)

323-361: Make timestamp parsing 64-bit-safe and reject non-positive values

On LLP64 platforms (e.g., Windows), long is 32-bit while time_t is 64-bit. Parsing filenames with strtol into long risks overflow around 2038 and loses range headroom. Also, negative or zero timestamps should be rejected explicitly.

  • Parse with strtoll and check end==fname, ERANGE, and val <= 0.
  • Keep returning 0 for “not timestamped”.

Apply this diff:

 static time_t fleet_config_path_timestamp(struct flb_in_calyptia_fleet_config *ctx, const char *path)
 {
     char *fname;
     char *end;
-    long val;
+    long long val;

     if (path == NULL || ctx == NULL) {
         return 0;
     }

     fname = strrchr(path, PATH_SEPARATOR[0]);

     if (fname == NULL) {
         return 0;
     }

     fname++;

     errno = 0;
-    val = strtol(fname, &end, 10);
-    if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) {
+    val = strtoll(fname, &end, 10);
+    if (errno == ERANGE) {
+        return 0;
+    }
+    /* No digits parsed or non-positive timestamp is not considered valid */
+    if (end == fname || val <= 0) {
         return 0;
     }

     if (ctx->fleet_config_legacy_format) {
         if (strcmp(end, ".conf") == 0) {
-           return (time_t) val;
+            return (time_t) val;
         }
     }
     else if (strcmp(end, ".yaml") == 0) {
-        return (time_t) val;
+        return (time_t) val;
     }

     return 0;
 }

1078-1089: Return “no-op” (0) instead of -1 when skipping older/equal configs; fix timestamp logging format

Skipping creation for older/equal timestamps is not an error. Returning 0 keeps get_calyptia_fleet_config() semantics clearer (no new file) and avoids conflating “intentional skip” with errors. Also, print timestamps in a 64-bit-safe way.

Apply this diff:

-        if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
-            flb_plg_debug(ctx->ins, "not creating file with timestamp %ld since it is not newer than existing files",
-                         (long)last_modified);
-            ret = -1;
-            goto client_error;
-        }
-        else {
-            flb_plg_info(ctx->ins, "creating config file with timestamp %ld",
-                         (long)last_modified);
-        }
+        if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
+            flb_plg_debug(ctx->ins,
+                          "not creating file with timestamp %lld since it is not newer than existing files",
+                          (long long) last_modified);
+            ret = 0; /* no new file created */
+            goto client_error;
+        }
+        else {
+            flb_plg_info(ctx->ins, "creating config file with timestamp %lld",
+                         (long long) last_modified);
+        }
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e2b4767 and 5412519.

📒 Files selected for processing (1)
  • plugins/in_calyptia_fleet/in_calyptia_fleet.c (7 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (2)
src/flb_sds.c (3)
  • flb_sds_create_size (92-95)
  • flb_sds_destroy (389-399)
  • flb_sds_printf (336-387)
lib/cfl/src/cfl_array.c (1)
  • cfl_array_destroy (51-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: PR - fuzzing test
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-centos-7
🔇 Additional comments (4)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (4)

67-67: Forward declaration for read_glob is appropriate

Prevents implicit declaration warnings and clarifies intent ahead of platform-specific implementations.


373-374: LGTM: reuse of fleet_config_path_timestamp for timestamped detection

Clearer and avoids duplicate logic.


1443-1445: LGTM: robust filtering using numeric timestamp extraction

Switching to fleet_config_path_timestamp(ctx, ...) > 0 ensures non-conforming files (e.g., header) are excluded before deletion.


1509-1512: LGTM: newest config selection now ignores non-timestamped entries

Using fleet_config_path_timestamp(ctx, curconf) > 0 avoids accidentally picking header or other non-timestamped files as “newest”.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (2)

973-1040: Fix UB: mismatched printf format specifiers vs. casted arguments

The debug log uses "%ld" but passes (long long) values. That’s undefined behavior on multiple platforms and can garble logs or crash.

Apply:

-            flb_plg_debug(ctx->ins,
-                          "existing file with timestamp %ld >= new timestamp %ld",
-                          (long long)file_timestamp, (long long)new_timestamp);
+            flb_plg_debug(ctx->ins,
+                          "existing file with timestamp %lld >= new timestamp %lld",
+                          (long long) file_timestamp, (long long) new_timestamp);

Optional (perf): instead of scanning all files, compare only against the newest timestamped config (via calyptia_config_get_newest + fleet_config_path_timestamp) to reduce I/O as the directory grows.


1078-1089: Use 64-bit-safe formatting for time_t in logs

On LLP64 platforms, time_t is 64-bit while long is 32-bit. Logging with %ld can truncate or misinterpret the argument. Cast to long long and use %lld consistently.

-        if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
-            flb_plg_debug(ctx->ins, "not creating file with timestamp %ld since it is not newer than existing files",
-                         (long)last_modified);
+        if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
+            flb_plg_debug(ctx->ins,
+                          "not creating file with timestamp %lld since it is not newer than existing files",
+                          (long long) last_modified);
             ret = -1;
             goto client_error;
         }
         else {
-            flb_plg_info(ctx->ins, "creating config file with timestamp %ld",
-                         (long)last_modified);
+            flb_plg_info(ctx->ins,
+                         "creating config file with timestamp %lld",
+                         (long long) last_modified);
         }
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5412519 and 0f5c4cc.

📒 Files selected for processing (1)
  • plugins/in_calyptia_fleet/in_calyptia_fleet.c (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-centos-7
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: PR - fuzzing test
🔇 Additional comments (4)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (4)

67-67: Forward declaration unblocks cross-OS use of read_glob

Good addition; it makes later calls compile on both POSIX and Windows sections.


373-374: Simplified timestamped-config check looks good

Switching to a numeric timestamp test via fleet_config_path_timestamp(...) > 0 is clearer and avoids duplicating logic.


1443-1446: Filtering to timestamped files before deletion is correct

This avoids accidental deletion of non-conforming files. Good guard.


1509-1513: Selecting the newest by numeric timestamp is robust

Using fleet_config_path_timestamp(...) to gate the selection ensures symlinks or non-timestamped files don’t interfere.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (1)

231-237: Avoid truncating time_t when naming files (Y2038/LLP64 safety)

snprintf("%d", (int)t) can truncate 64-bit time_t on many platforms, risking wrong filenames and incorrect gating decisions. Emit the full width.

Proposed replacement outside this hunk:

static flb_sds_t time_fleet_config_filename(struct flb_in_calyptia_fleet_config *ctx, time_t t)
{
    char s_last_modified[32];

    /* Use long long to safely format 64-bit time_t */
    snprintf(s_last_modified, sizeof(s_last_modified) - 1, "%lld", (long long) t);
    return fleet_config_filename(ctx, s_last_modified);
}
♻️ Duplicate comments (2)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (2)

324-362: Harden timestamp parsing: fix ERANGE/overflow checks and reject negative/partial matches

Current checks are still tied to LONG_* while using strtoll and may admit invalid/partial parses. Also negative timestamps should be rejected.

Apply this diff:

 static time_t fleet_config_path_timestamp(struct flb_in_calyptia_fleet_config *ctx, const char *path)
 {
     char *fname;
     char *end;
-    long long val;
+    long long val64;
@@
-    errno = 0;
-    val = strtoll(fname, &end, 10);
-    if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) {
-        return 0;
-    }
+    errno = 0;
+    val64 = strtoll(fname, &end, 10);
+    /* No digits parsed, out of range, or negative values are invalid */
+    if (end == fname || errno == ERANGE || val64 < 0) {
+        return 0;
+    }
@@
-        if (strcmp(end, ".conf") == 0) {
-           return (time_t)val;
+        if (strcmp(end, ".conf") == 0) {
+           return (time_t) val64;
         }
@@
-    else if (strcmp(end, ".yaml") == 0) {
-        return (time_t)val;
+    else if (strcmp(end, ".yaml") == 0) {
+        return (time_t) val64;
     }

974-1040: Printf format bug: %ld used with long long arguments → undefined behavior in logs

At Line 1028, the format string uses %ld while the arguments are cast to long long. This is UB and can garble logs. Use %lld (or switch to inttypes macros).

Apply this diff:

-            flb_plg_debug(ctx->ins,
-                          "existing file with timestamp %ld >= new timestamp %ld",
-                          (long long)file_timestamp, (long long)new_timestamp);
+            flb_plg_debug(ctx->ins,
+                          "existing file with timestamp %lld >= new timestamp %lld",
+                          (long long) file_timestamp, (long long) new_timestamp);

Optional follow-up (perf): Instead of scanning all files, compare new_timestamp only against the newest timestamped file (via calyptia_config_get_newest + fleet_config_path_timestamp). This scales better as files accumulate.

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0f5c4cc and f652952.

📒 Files selected for processing (1)
  • plugins/in_calyptia_fleet/in_calyptia_fleet.c (8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: PR - fuzzing test
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-centos-7
🔇 Additional comments (5)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (5)

25-26: Good: errno/limits includes add portability for parsing

These headers are required for robust errno- and range-based parsing. Looks good.


69-69: Good: forward declaration prevents implicit-declaration issues

Declaring read_glob early avoids build order problems. LGTM.


374-374: LGTM: unified timestamped-check via numeric parser

Replacing the boolean path-check with a numeric timestamp > 0 is clearer and re-usable.


1444-1444: LGTM: filter delete-old using numeric timestamp parser

Skipping non-timestamped files before pruning is correct and safer.


1510-1510: LGTM: newest-config selection now ignores non-timestamped files

Picking the newest strictly among timestamped files is correct and aligns with the gating logic.

Comment on lines +1079 to +1090
/* Check if there are existing files with timestamps >= new timestamp */
if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
flb_plg_debug(ctx->ins, "not creating file with timestamp %lld since it is not newer than existing files",
(long long)last_modified);
ret = -1;
goto client_error;
}
else {
flb_plg_info(ctx->ins, "creating config file with timestamp %lld",
(long long)last_modified);
}

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Parse Last-Modified as RFC 1123 and convert in UTC; current code uses %B and mktime (local time)

  • HTTP-date is RFC 1123 (e.g., "Sun, 06 Nov 1994 08:49:37 GMT") with abbreviated month (%b), not full month (%B).
  • mktime interprets tm as local time. For a “GMT” timestamp, use timegm (POSIX) or _mkgmtime (Windows). Otherwise gating can be wrong in non-UTC timezones.

Apply this diff:

-        flb_strptime(fbit_last_modified, "%a, %d %B %Y %H:%M:%S GMT", &tm_last_modified);
-        last_modified = mktime(&tm_last_modified.tm);
+        /* RFC 1123 format (IMF-fixdate): abbreviated month and GMT */
+        flb_strptime(fbit_last_modified, "%a, %d %b %Y %H:%M:%S GMT", &tm_last_modified);
+#ifndef _WIN32
+        last_modified = timegm(&tm_last_modified.tm);
+#else
+        last_modified = _mkgmtime(&tm_last_modified.tm);
+#endif
+        if (last_modified <= 0) {
+            flb_plg_warn(ctx->ins, "invalid Last-Modified header: %.*s",
+                         fbit_last_modified_len, fbit_last_modified);
+            ret = -1;
+            goto client_error;
+        }
📝 Committable suggestion

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

Suggested change
/* Check if there are existing files with timestamps >= new timestamp */
if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
flb_plg_debug(ctx->ins, "not creating file with timestamp %lld since it is not newer than existing files",
(long long)last_modified);
ret = -1;
goto client_error;
}
else {
flb_plg_info(ctx->ins, "creating config file with timestamp %lld",
(long long)last_modified);
}
/* RFC 1123 format (IMF-fixdate): abbreviated month and GMT */
flb_strptime(fbit_last_modified, "%a, %d %b %Y %H:%M:%S GMT", &tm_last_modified);
#ifndef _WIN32
last_modified = timegm(&tm_last_modified.tm);
#else
last_modified = _mkgmtime(&tm_last_modified.tm);
#endif
if (last_modified <= 0) {
flb_plg_warn(ctx->ins, "invalid Last-Modified header: %.*s",
fbit_last_modified_len, fbit_last_modified);
ret = -1;
goto client_error;
}
/* Check if there are existing files with timestamps >= new timestamp */
if (check_timestamp_is_newer(ctx, last_modified) == FLB_FALSE) {
flb_plg_debug(ctx->ins, "not creating file with timestamp %lld since it is not newer than existing files",
(long long)last_modified);
ret = -1;
goto client_error;
}
else {
flb_plg_info(ctx->ins, "creating config file with timestamp %lld",
(long long)last_modified);
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (4)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (4)

1001-1006: Good: guard sds formatting failure

Nice catch adding a return-value check for flb_sds_printf and cleaning up allocations before returning.


1074-1078: Parse Last-Modified as RFC 1123 and convert in UTC; mktime + %B is incorrect

  • HTTP-date uses RFC 1123 (IMF-fixdate) with abbreviated month (%b), not %B.
  • mktime interprets local time; the header is GMT. Use timegm (POSIX) or _mkgmtime (Windows). Otherwise gating can be wrong across timezones and lead to accepting/rejecting incorrect configs.

Apply:

-        flb_strptime(fbit_last_modified, "%a, %d %B %Y %H:%M:%S GMT", &tm_last_modified);
-        last_modified = mktime(&tm_last_modified.tm);
+        flb_strptime(fbit_last_modified, "%a, %d %b %Y %H:%M:%S GMT", &tm_last_modified);
+#ifndef _WIN32
+        last_modified = timegm(&tm_last_modified.tm);
+#else
+        last_modified = _mkgmtime(&tm_last_modified.tm);
+#endif
+        if (last_modified <= 0) {
+            flb_plg_warn(ctx->ins, "invalid Last-Modified header: %.*s",
+                         fbit_last_modified_len, fbit_last_modified);
+            ret = -1;
+            goto client_error;
+        }

Note: Consider checking the return of flb_strptime as well to catch malformed dates earlier.


324-362: Fix strtoll overflow/errno handling; avoid 32-bit LONG_ pitfalls*

Current ERANGE check compares strtoll’s return value against LONG_MAX/LONG_MIN, which won’t catch overflow (strtoll returns LLONG_MAX/LLONG_MIN on ERANGE). Also, negative timestamps should be rejected. This can misclassify filenames and corrupt gating on LLP64/Windows or large timestamps.

Apply:

 static time_t fleet_config_path_timestamp(struct flb_in_calyptia_fleet_config *ctx, const char *path)
 {
     char *fname;
     char *end;
-    long long val;
+    long long val64;
@@
     errno = 0;
-    val = strtoll(fname, &end, 10);
-    if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) {
+    val64 = strtoll(fname, &end, 10);
+    if (errno == ERANGE || val64 < 0) {
         return 0;
     }
@@
         if (strcmp(end, ".conf") == 0) {
-           return (time_t)val;
+           return (time_t) val64;
         }
@@
     else if (strcmp(end, ".yaml") == 0) {
-        return (time_t)val;
+        return (time_t) val64;
     }

1026-1030: Fix printf format specifiers: %ld with long long is UB

You’re casting to (long long) but using %ld. That’s undefined behavior and can print garbage or crash on some platforms.

Apply:

-            flb_plg_debug(ctx->ins,
-                          "existing file with timestamp %ld >= new timestamp %ld",
-                          (long long)file_timestamp, (long long)new_timestamp);
+            flb_plg_debug(ctx->ins,
+                          "existing file with timestamp %lld >= new timestamp %lld",
+                          (long long) file_timestamp, (long long) new_timestamp);
🧹 Nitpick comments (2)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (2)

1008-1015: Differentiate “no match” vs. “glob error” to avoid masking failures

read_glob() returns NULL both for GLOB_NOMATCH and real errors. Treating both as “no existing files” can accidentally greenlight stale configs if a permission or IO error occurs.

Option: have read_glob return a status code or emit/propagate a flag (e.g., via an out param) so you can distinguish and log/warn accordingly.


1017-1033: Optional: compare against only the newest timestamped file

Scanning all files is O(n). Given you only need the maximum timestamp, consider:

  • Fetch newest via calyptia_config_get_newest() and compare once, or
  • Track max(file_timestamp) while iterating and early break when you see any >= new_timestamp.

This reduces IO and CPU with many historical configs.

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2f08b28 and c81ca20.

📒 Files selected for processing (1)
  • plugins/in_calyptia_fleet/in_calyptia_fleet.c (8 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (2)
src/flb_sds.c (3)
  • flb_sds_create_size (92-95)
  • flb_sds_destroy (389-399)
  • flb_sds_printf (336-387)
lib/cfl/src/cfl_array.c (1)
  • cfl_array_destroy (51-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: PR - fuzzing test
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-centos-7
🔇 Additional comments (6)
plugins/in_calyptia_fleet/in_calyptia_fleet.c (6)

25-26: LGTM: required headers added

Including errno.h and limits.h is necessary for robust numeric parsing and error checks.


69-69: LGTM: forward declaration unblocks callers

Forward-declaring read_glob avoids implicit declarations and keeps usage sites type-checked.


374-375: LGTM: timestamp classification tightened

Swapping to fleet_config_path_timestamp(...) > 0 makes the intent explicit and de-duplicates logic.


1081-1089: LGTM: clear, actionable logs for gating outcome

The info/debug messages around creating or skipping a config based on timestamp make the behavior observable and debuggable.


1444-1446: LGTM: consistent timestamped-file filtering

Using fleet_config_path_timestamp(...) > 0 centrally avoids false positives from non-conforming filenames.


1510-1513: LGTM: newest-config selection respects timestamped naming

This keeps “newest” aligned with your gating semantics.

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.

2 participants