Skip to content

feat: add configurable log processing parameters to telemetry system#39

Merged
andersonleal merged 3 commits intomainfrom
feat/log-flush-interval
Mar 2, 2026
Merged

feat: add configurable log processing parameters to telemetry system#39
andersonleal merged 3 commits intomainfrom
feat/log-flush-interval

Conversation

@andersonleal
Copy link
Contributor

@andersonleal andersonleal commented Mar 2, 2026

Summary

  • Add configurable OpenTelemetry log batching parameters across Node, Python, and Rust SDKs.
  • Standardize precedence for log batching settings as explicit config > environment variable > default values.
  • Extend telemetry tests in Python and Rust to cover new log flush interval and batch size configuration behavior.

Type of change

  • Feature
  • Bug fix
  • Refactor
  • Tests
  • Documentation

Checklist

  • Changes are scoped to SDK telemetry behavior.
  • Backward compatibility is preserved via sensible defaults.
  • All relevant tests were run locally.

Additional context

  • develop does not exist in this repository; PR is targeted to main (default branch).
  • New env vars introduced for cross-SDK log batch tuning:
  • OTEL_LOGS_FLUSH_INTERVAL_MS
  • OTEL_LOGS_BATCH_SIZE

Summary by CodeRabbit

Release Notes

  • New Features
    • Added configurable OpenTelemetry logging settings across Node.js, Python, and Rust SDKs
    • Log flush interval and batch size can now be customized via configuration or environment variables
    • Configuration values take precedence over environment variables
    • Default flush interval: 100ms; default batch size: 1

- Introduced `logsFlushIntervalMs` and `logsBatchSize` options in the `OtelConfig` interface for customizable log processing behavior.
- Updated the Node.js and Python SDKs to utilize these new configuration options, allowing users to set log flush intervals and batch sizes via environment variables or directly in the configuration.
- Enhanced the Rust SDK to support similar log processing configurations, ensuring consistency across all SDKs.
- Added tests to verify default values and explicit configurations for log processing parameters.
@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

Warning

Rate limit exceeded

@andersonleal has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 58 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 32a4c7e and 5eea383.

⛔ Files ignored due to path filters (1)
  • packages/python/iii/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • packages/node/iii/src/telemetry-system/index.ts
  • packages/node/iii/src/telemetry-system/utils.ts
  • packages/python/iii/src/iii/telemetry.py
  • packages/rust/iii/src/telemetry/mod.rs
📝 Walkthrough

Walkthrough

This PR adds configurable log batching to the OpenTelemetry telemetry system across TypeScript, Python, and Rust implementations. New configuration fields (logsFlushIntervalMs/logs_flush_interval_ms and corresponding batch sizes) are added to each language's config with defaults. Helper utilities parse numeric environment variables with minimum value validation, and the BatchLogRecordProcessor is initialized with resolved config values using a precedence: explicit config > environment variable > default.

Changes

Cohort / File(s) Summary
TypeScript Utilities & Configuration
packages/node/iii/src/telemetry-system/utils.ts, packages/node/iii/src/telemetry-system/types.ts, packages/node/iii/src/telemetry-system/index.ts
Added parseNumberEnv and parseIntegerEnv helper functions with minimum-value validation. Extended OtelConfig interface with logsFlushIntervalMs and logsMaxExportBatchSize fields (defaults: 100, 1). Updated telemetry initialization to resolve and pass these values to BatchLogRecordProcessor.
Python Configuration & Types
packages/python/iii/src/iii/telemetry_types.py, packages/python/iii/src/iii/telemetry.py
Added logs_flush_interval_ms and logs_batch_size to OtelConfig dataclass. Updated _configure_log_provider to accept cfg parameter and resolve batch settings from config/env vars. Introduced _resolve_int helper and _shutdown_provider utility for safe provider shutdown. Refactored enabled-flag logic to prefer cfg.enabled when provided.
Python Tests
packages/python/iii/tests/test_telemetry.py, packages/python/iii/tests/test_telemetry_types.py
Added helper _reset_otel_singleton for uniform singleton reset in teardown. Introduced five new tests validating log batch configuration: defaults, explicit overrides, env var precedence, explicit-beats-env behavior, and invalid env handling. Added tests for new config fields and their defaults.
Rust Configuration & Implementation
packages/rust/iii/src/telemetry/types.rs, packages/rust/iii/src/telemetry/mod.rs
Added logs_flush_interval_ms: Option<u64> and logs_batch_size: Option<usize> to OtelConfig struct. Updated logger provider initialization to resolve config/env var values (with minimum batch size of 1), construct BatchConfig, and initialize SdkLoggerProvider with batch processor. Added tests for env var parsing and batch size filtering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat: enhance OpenTelemetry configuration and logging #21: Modifies telemetry-system initialization and types with environment variable parsing and configuration defaults, establishing the foundational patterns extended by this PR's numeric env-parsing utilities and log-batching configuration.

Suggested reviewers

  • ytallo

Poem

🐰 Log batches hop in config arrays,
Flush intervals now have their say,
From Node to Python, Rust takes the lead,
Environment variables plant the seed, 🌱
A carrot's config, at last, complete! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature added: configurable log processing parameters across the telemetry system in Node, Python, and Rust SDKs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/log-flush-interval

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

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/node/iii/src/telemetry-system/index.ts`:
- Around line 170-188: Run Prettier on the file to fix formatting
inconsistencies: run the suggested command in the package (cd packages/node/iii
&& npx prettier --write src/telemetry-system/index.ts) so the block around
logsScheduledDelayMillis, logsMaxExportBatchSize, parseNumberEnv,
parseIntegerEnv, LoggerProvider and BatchLogRecordProcessor is formatted
according to project style; alternatively, apply the project's Prettier rules to
reflow line breaks and spacing in that section and then commit the updated file.

In `@packages/node/iii/src/telemetry-system/utils.ts`:
- Around line 12-17: The block containing parseIntegerEnv (which calls
parseNumberEnv) is not formatter-compliant; run the project formatter on this
file or reformat the parseIntegerEnv function to match the repository style
(e.g., spacing, semicolons/newlines) so CI passes—locate the parseIntegerEnv
function and apply the project's formatter (or run the project's format
script/Prettier/ESLint --fix) to update the formatting.
- Around line 4-8: parseNumberEnv currently coerces an empty string ("") to 0
via Number("") which can override defaults; update parseNumberEnv to treat
empty-string inputs as undefined before numeric coercion by returning undefined
if value === "" (in addition to value === undefined), then continue parsing with
Number(value) and validate against Number.isFinite(parsed) and parsed < minimum
as before; reference the function parseNumberEnv so reviewers can locate and
update its handling of empty-string env values.

In `@packages/python/iii/src/iii/telemetry.py`:
- Around line 206-212: The type ignore is placed on the closing parenthesis
instead of the actual mismatched argument; move the "# type: ignore[arg-type]"
to the log_exporter argument in the BatchLogRecordProcessor call so the type
checker ignores the EngineLogExporter vs LogRecordExporter incompatibility
(i.e., change the call to pass "log_exporter,  # type: ignore[arg-type]" to the
BatchLogRecordProcessor inside log_provider.add_log_record_processor).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0604e5 and 32a4c7e.

⛔ Files ignored due to path filters (1)
  • packages/rust/iii/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • packages/node/iii/src/telemetry-system/index.ts
  • packages/node/iii/src/telemetry-system/types.ts
  • packages/node/iii/src/telemetry-system/utils.ts
  • packages/python/iii/src/iii/telemetry.py
  • packages/python/iii/src/iii/telemetry_types.py
  • packages/python/iii/tests/test_telemetry.py
  • packages/python/iii/tests/test_telemetry_types.py
  • packages/rust/iii/src/telemetry/mod.rs
  • packages/rust/iii/src/telemetry/types.rs

Comment on lines +4 to +8
export function parseNumberEnv(value: string | undefined, minimum: number = 0): number | undefined {
if (value === undefined) return undefined
const parsed = Number(value)
if (!Number.isFinite(parsed) || parsed < minimum) return undefined
return parsed
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find the file and examine its structure
find . -type f -name "utils.ts" | grep -i telemetry

Repository: iii-hq/sdk

Length of output: 103


🏁 Script executed:

# Also check the overall structure of the packages/node directory
git ls-files packages/node/ | head -30

Repository: iii-hq/sdk

Length of output: 1209


🏁 Script executed:

# Search for parseNumberEnv usage across the codebase
rg -l "parseNumberEnv" --type=ts

Repository: iii-hq/sdk

Length of output: 149


🏁 Script executed:

# Read the utils.ts file to see the implementation
cat -n packages/node/iii/src/telemetry-system/utils.ts

Repository: iii-hq/sdk

Length of output: 840


🏁 Script executed:

# Check the index.ts to see how parseNumberEnv is used
cat -n packages/node/iii/src/telemetry-system/index.ts

Repository: iii-hq/sdk

Length of output: 11461


🏁 Script executed:

# Search for all usages of parseNumberEnv with context
rg -n "parseNumberEnv" -C5 --type=ts

Repository: iii-hq/sdk

Length of output: 3660


🏁 Script executed:

# Search for test files related to this utility
find . -type f \( -name "*test*" -o -name "*spec*" \) -path "*/telemetry-system/*" | head -20

Repository: iii-hq/sdk

Length of output: 36


🏁 Script executed:

# Search for test files in the entire packages/node/iii directory
find packages/node/iii -type f \( -name "*.test.ts" -o -name "*.spec.ts" \)

Repository: iii-hq/sdk

Length of output: 581


🏁 Script executed:

# Search for any tests referencing parseNumberEnv or parseIntegerEnv
rg -n "(parseNumberEnv|parseIntegerEnv)" --type=ts -g "*test*" -g "*spec*"

Repository: iii-hq/sdk

Length of output: 36


🏁 Script executed:

# Check DEFAULT_OTEL_CONFIG to understand the defaults
rg -n "DEFAULT_OTEL_CONFIG\|logsFlushIntervalMs\|logsBatchSize" --type=ts -B2 -A2

Repository: iii-hq/sdk

Length of output: 36


🏁 Script executed:

# Check if there are any guards before the parseNumberEnv calls
rg -n "OTEL_LOGS_FLUSH_INTERVAL_MS\|OTEL_LOGS_BATCH_SIZE" --type=ts -B3 -A3

Repository: iii-hq/sdk

Length of output: 36


🏁 Script executed:

# Look at the otel-defaults test file
cat -n packages/node/iii/tests/otel-defaults.test.ts

Repository: iii-hq/sdk

Length of output: 9587


🏁 Script executed:

# Search for DEFAULT_OTEL_CONFIG definition
rg -n "DEFAULT_OTEL_CONFIG" --type=ts

Repository: iii-hq/sdk

Length of output: 1386


🏁 Script executed:

# Search for logsFlushIntervalMs and logsBatchSize in types.ts
cat packages/node/iii/src/telemetry-system/types.ts

Repository: iii-hq/sdk

Length of output: 3960


🏁 Script executed:

# Test JavaScript Number coercion behavior to confirm the claim
node -e "console.log('Number(\"\") =', Number('')); console.log('Number(\"   \") =', Number('   ')); console.log('Number(\"0\") =', Number('0')); console.log('Number(\"abc\") =', Number('abc'))"

Repository: iii-hq/sdk

Length of output: 122


Add empty-string validation before numeric coercion in parseNumberEnv.

Environment variables like OTEL_LOGS_FLUSH_INTERVAL_MS="" pass Number("") which coerces to 0, silently overriding defaults (e.g., logsFlushIntervalMs: 100, logsBatchSize: 1). This causes incorrect configuration—empty env vars should be treated as unset, not as zero.

Currently called on lines 172 and 176 of index.ts with no upstream guards.

Proposed fix
 export function parseNumberEnv(value: string | undefined, minimum: number = 0): number | undefined {
   if (value === undefined) return undefined
-  const parsed = Number(value)
+  const normalized = value.trim()
+  if (normalized.length === 0) return undefined
+  const parsed = Number(normalized)
   if (!Number.isFinite(parsed) || parsed < minimum) return undefined
   return parsed
 }
📝 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
export function parseNumberEnv(value: string | undefined, minimum: number = 0): number | undefined {
if (value === undefined) return undefined
const parsed = Number(value)
if (!Number.isFinite(parsed) || parsed < minimum) return undefined
return parsed
export function parseNumberEnv(value: string | undefined, minimum: number = 0): number | undefined {
if (value === undefined) return undefined
const normalized = value.trim()
if (normalized.length === 0) return undefined
const parsed = Number(normalized)
if (!Number.isFinite(parsed) || parsed < minimum) return undefined
return parsed
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/node/iii/src/telemetry-system/utils.ts` around lines 4 - 8,
parseNumberEnv currently coerces an empty string ("") to 0 via Number("") which
can override defaults; update parseNumberEnv to treat empty-string inputs as
undefined before numeric coercion by returning undefined if value === "" (in
addition to value === undefined), then continue parsing with Number(value) and
validate against Number.isFinite(parsed) and parsed < minimum as before;
reference the function parseNumberEnv so reviewers can locate and update its
handling of empty-string env values.

- Simplified the logger provider setup logic in the `init_otel` function for improved readability and maintainability.
- Added a new `get_logger_provider` function to retrieve a clone of the logger provider, enhancing the SDK's logging capabilities.
- Removed redundant code and ensured consistent handling of log processing parameters.
- Enhanced readability by adjusting the formatting of the logger provider initialization in the `initOtel` function.
- Updated the `parseIntegerEnv` function to improve its parameter formatting for better clarity.
- Added type casting for `log_exporter` in the Python telemetry module to ensure type safety.
@andersonleal andersonleal merged commit 05fbdfc into main Mar 2, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants