Conversation
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…ate tags handling
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…ipeline implement opentelemetry logging
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds OpenTelemetry log export (pino + OTEL transport), OTEL test stack and Vector pipeline, docs and env examples for OTEL; numerous dependency and toolchain bumps; Node/pnpm pinning; GitHub Actions Docker action version updates; Dockerfile base image pins; various minor config and i18n edits. Changes
Sequence Diagram(s)sequenceDiagram
participant API as "API (pino + OTEL transport)"
participant Vector as "Vector (OTLP collector)"
participant OpenSearch as "OpenSearch (+Dashboards)"
API->>Vector: Export logs via OTLP HTTP/gRPC (OTEL_EXPORTER_OTLP_LOGS_ENDPOINT)
Vector->>Vector: Transform & enrich logs (remap)
Vector->>OpenSearch: Index logs (Elasticsearch-compatible sink)
Vector->>API: Console JSON sink (optional)
Note right of OpenSearch: Dashboards reads indexed logs for visualization
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (5)
apps/api/.env.example (1)
42-42: Add a trailing newline at end of file.The file is missing a blank line at the end, which is a POSIX convention and flagged by dotenv-linter.
Proposed fix
# OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://localhost:4319/v1/logs # OTEL_RESOURCE_ATTRIBUTES=service.name=abc-user-feedback-api,service.version=1.0.0 +🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api/.env.example` at line 42, The file apps/api/.env.example is missing a trailing newline (POSIX convention) which causes dotenv-linter to flag the file; open the file and add a single blank line at the end of file (after the existing OTEL_RESOURCE_ATTRIBUTES line) so the file ends with a newline character, then commit the change.docker/docker-compose.otel-test.yml (3)
40-40: Consider pinning Vector image version.Using
timberio/vector:latest-alpinemay lead to unexpected behavior changes when the image is updated. For a test stack, pinning to a specific version improves reproducibility.💡 Example version pinning
- image: timberio/vector:latest-alpine + image: timberio/vector:0.46.0-alpine🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docker/docker-compose.otel-test.yml` at line 40, Replace the floating image tag "timberio/vector:latest-alpine" used in the docker-compose service with a pinned, specific Vector release (e.g., a concrete semver-alpine tag) to ensure reproducible test behavior; update the image value referenced in the compose file (the line containing image: timberio/vector:latest-alpine) to the chosen pinned tag and document the chosen version in the compose file or repo README.
39-49: Vector service missing OpenSearch environment variables.The Vector configuration in
docker/vector.ymlexpectsOPENSEARCH_ENDPOINT,OPENSEARCH_USERNAME, andOPENSEARCH_PASSWORDenvironment variables. WhileOPENSEARCH_ENDPOINTdefaults tohttp://opensearch-node:9200which matches this setup, explicitly setting these would be clearer and more maintainable.Additionally, since
plugins.security.disabled=trueon OpenSearch, the empty auth defaults should work, but this isn't immediately obvious.💡 Suggested environment configuration for Vector
vector: image: timberio/vector:latest-alpine command: ['--config', '/etc/vector/vector.yml'] volumes: - ./vector.yml:/etc/vector/vector.yml:ro ports: - '4319:4319' # OTLP HTTP - '4317:4317' # OTLP gRPC + environment: + - OPENSEARCH_ENDPOINT=http://opensearch-node:9200 + # Auth not required since OpenSearch security is disabled depends_on: - opensearch-node restart: unless-stopped🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docker/docker-compose.otel-test.yml` around lines 39 - 49, The Vector service definition (service name "vector") is missing explicit OpenSearch environment variables; update the vector service in the docker-compose entry to set OPENSEARCH_ENDPOINT (e.g., http://opensearch-node:9200), OPENSEARCH_USERNAME (empty string when plugins.security.disabled=true) and OPENSEARCH_PASSWORD (empty string when plugins.security.disabled=true) so the docker/vector.yml config can resolve them clearly and maintainably; include brief comments or values to indicate that empty username/password are deliberate when OpenSearch security is disabled.
4-26: Consider adding healthcheck for OpenSearch reliability.Vector depends on
opensearch-nodebut Docker Compose'sdepends_ononly waits for container start, not service readiness. This can cause transient connection failures during startup.💡 Suggested healthcheck addition
opensearch-node: image: opensearchproject/opensearch:2.19.4 restart: unless-stopped environment: - cluster.name=opensearch-cluster - node.name=opensearch-node - discovery.type=single-node - bootstrap.memory_lock=true - 'OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m' - plugins.security.disabled=true - OPENSEARCH_INITIAL_ADMIN_PASSWORD=UserFeedback123!@# + healthcheck: + test: ['CMD-SHELL', 'curl -s http://localhost:9200/_cluster/health | grep -q "status"] + interval: 10s + timeout: 5s + retries: 5Then update Vector's depends_on:
depends_on: - - opensearch-node + opensearch-node: + condition: service_healthy🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docker/docker-compose.otel-test.yml` around lines 4 - 26, Add a Docker healthcheck to the opensearch-node service so Compose can detect readiness (use a curl or wget against the node's HTTP endpoint such as http://localhost:9200/_cluster/health or /_cluster/health?timeout=1s, with a sensible interval, timeout, retries and start_period), and then update Vector's depends_on to require opensearch-node: condition: service_healthy so Vector waits for the OpenSearch cluster to be healthy before starting; reference the opensearch-node service name and Vector's depends_on entry when applying the change.docker/vector.yml (1)
85-88: Empty default credentials may cause authentication issues.The OpenSearch sink auth configuration defaults to empty strings for
userandpassword:user: '${OPENSEARCH_USERNAME:-}' password: '${OPENSEARCH_PASSWORD:-}'When
OPENSEARCH_USERNAMEandOPENSEARCH_PASSWORDare not set (as in the test compose file where security is disabled), Vector will attempt basic auth with empty credentials. This may work when OpenSearch security is disabled, but could cause confusing errors if security is later enabled.Consider either:
- Using a conditional auth strategy, or
- Documenting that these variables must be set when security is enabled
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docker/vector.yml` around lines 85 - 88, The Vector OpenSearch sink currently always sets auth.strategy: basic with user:'${OPENSEARCH_USERNAME:-}' and password:'${OPENSEARCH_PASSWORD:-}', which supplies empty credentials when env vars are missing; change this to either make auth conditional (only add the auth block or set strategy when OPENSEARCH_USERNAME/OPENSEARCH_PASSWORD are provided) or explicitly fail/require the variables by removing the empty default, and add documentation in the compose file/readme that OPENSEARCH_USERNAME and OPENSEARCH_PASSWORD must be set when OpenSearch security is enabled; update the auth block (auth, strategy, user, password) and related docs accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/api/package.json`:
- Around line 48-51: The package.json currently pins non-existent OpenTelemetry
versions for `@opentelemetry/exporter-logs-otlp-http` and `@opentelemetry/sdk-logs`
(shown as "^0.213.0"); update those dependency entries to valid published
versions (for example "^0.57.2") while leaving `@opentelemetry/resources` at
"^2.6.0" unchanged so npm install resolves correctly; locate the dependency
lines for "@opentelemetry/exporter-logs-otlp-http" and "@opentelemetry/sdk-logs"
and replace their version strings with a valid version like "^0.57.2".
In `@apps/api/README.md`:
- Line 47: Replace the typo "expored" with "exported" in the README sentence
"Builds the app for production. The distributable is expored to the `dist`
folder in the repository's root folder." so it reads "The distributable is
exported to the `dist` folder in the repository's root folder."
In `@apps/api/src/configs/otel-log.config.ts`:
- Around line 24-30: The transport is always created by createOtelLogTransport()
even when OTEL_EXPORTER_OTLP_LOGS_ENDPOINT is not set; update
createOtelLogTransport so it checks process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
and only returns a TransportTargetOptions when that env var is defined
(otherwise return null/undefined), and update callers in app.module.ts and
main.ts to register the transport conditionally; alternatively, add a clear
comment/docstring in createOtelLogTransport describing the runtime behavior
(errors/buffering/dropping) when the endpoint is absent if you choose to keep
unconditional creation.
In `@apps/api/src/main.ts`:
- Around line 57-62: The OTEL transport is always added to the pino "transport"
targets via createOtelLogTransport(), which tries to connect even when
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT isn't configured; update the transport
construction to only include createOtelLogTransport() when the
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT env var (or equivalent config method) is
present and non-empty, i.e., check process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
(or your config.get) before pushing createOtelLogTransport() into the targets
array; apply the same conditional pattern where transport is built (the
transport variable and any usage in main bootstrap and AppModule) so OTEL is
only initialized when the endpoint is set.
In `@turbo.json`:
- Line 53: The APP_VERSION entry in turbo.json is unused; either remove
"APP_VERSION" from turbo.json or wire it into the app by reading
process.env.APP_VERSION where the globalEnv is consumed (e.g., in the
configuration/bootstrap code that references globalEnv) and propagate it into
logs/headers/health endpoints as needed; update any type/interface that
represents globalEnv to include APP_VERSION if you choose to consume it so
references like process.env.APP_VERSION or globalEnv.APP_VERSION are valid
throughout the codebase.
- Line 77: The globalEnv list used by the Turbo cache currently contains
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT" but is missing "OTEL_RESOURCE_ATTRIBUTES",
causing changes to that env var to be ignored by Turbo; update the globalEnv
array to include the string "OTEL_RESOURCE_ATTRIBUTES" alongside
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT" so Turbo invalidates caches when
OTEL_RESOURCE_ATTRIBUTES changes.
---
Nitpick comments:
In `@apps/api/.env.example`:
- Line 42: The file apps/api/.env.example is missing a trailing newline (POSIX
convention) which causes dotenv-linter to flag the file; open the file and add a
single blank line at the end of file (after the existing
OTEL_RESOURCE_ATTRIBUTES line) so the file ends with a newline character, then
commit the change.
In `@docker/docker-compose.otel-test.yml`:
- Line 40: Replace the floating image tag "timberio/vector:latest-alpine" used
in the docker-compose service with a pinned, specific Vector release (e.g., a
concrete semver-alpine tag) to ensure reproducible test behavior; update the
image value referenced in the compose file (the line containing image:
timberio/vector:latest-alpine) to the chosen pinned tag and document the chosen
version in the compose file or repo README.
- Around line 39-49: The Vector service definition (service name "vector") is
missing explicit OpenSearch environment variables; update the vector service in
the docker-compose entry to set OPENSEARCH_ENDPOINT (e.g.,
http://opensearch-node:9200), OPENSEARCH_USERNAME (empty string when
plugins.security.disabled=true) and OPENSEARCH_PASSWORD (empty string when
plugins.security.disabled=true) so the docker/vector.yml config can resolve them
clearly and maintainably; include brief comments or values to indicate that
empty username/password are deliberate when OpenSearch security is disabled.
- Around line 4-26: Add a Docker healthcheck to the opensearch-node service so
Compose can detect readiness (use a curl or wget against the node's HTTP
endpoint such as http://localhost:9200/_cluster/health or
/_cluster/health?timeout=1s, with a sensible interval, timeout, retries and
start_period), and then update Vector's depends_on to require opensearch-node:
condition: service_healthy so Vector waits for the OpenSearch cluster to be
healthy before starting; reference the opensearch-node service name and Vector's
depends_on entry when applying the change.
In `@docker/vector.yml`:
- Around line 85-88: The Vector OpenSearch sink currently always sets
auth.strategy: basic with user:'${OPENSEARCH_USERNAME:-}' and
password:'${OPENSEARCH_PASSWORD:-}', which supplies empty credentials when env
vars are missing; change this to either make auth conditional (only add the auth
block or set strategy when OPENSEARCH_USERNAME/OPENSEARCH_PASSWORD are provided)
or explicitly fail/require the variables by removing the empty default, and add
documentation in the compose file/readme that OPENSEARCH_USERNAME and
OPENSEARCH_PASSWORD must be set when OpenSearch security is enabled; update the
auth block (auth, strategy, user, password) and related docs accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 1dcf3a97-187b-435e-b189-36de0b0e10d1
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (33)
.github/workflows/docker-dev-image.yml.github/workflows/docker-prod-image.yml.nvmrcapps/api/.env.exampleapps/api/README.mdapps/api/package.jsonapps/api/src/app.module.tsapps/api/src/configs/otel-log.config.tsapps/api/src/main.tsapps/cli/package.jsonapps/docs/docs/02-developer-guide/01-installation/05-configuration.mdapps/docs/i18n/en/docusaurus-plugin-content-docs/current/02-developer-guide/01-installation/05-configuration.mdapps/docs/i18n/ja/docusaurus-plugin-content-docs/current/02-developer-guide/01-installation/05-configuration.mdapps/docs/i18n/ko/docusaurus-plugin-content-blog/options.jsonapps/docs/package.jsonapps/e2e/package.jsonapps/web/.prettierignoreapps/web/next-env.d.tsapps/web/package.jsondocker/api.dockerfiledocker/docker-compose.otel-test.ymldocker/docs.dockerfiledocker/vector.ymldocker/web.dockerfilepackage.jsonpackages/ufb-react/package.jsonpackages/ufb-shared/package.jsonpackages/ufb-tailwindcss/package.jsonpnpm-workspace.yamltooling/eslint/package.jsontooling/github/setup/action.ymltooling/prettier/package.jsonturbo.json
💤 Files with no reviewable changes (1)
- apps/docs/i18n/ko/docusaurus-plugin-content-blog/options.json
| "@opentelemetry/exporter-logs-otlp-http": "^0.213.0", | ||
| "@opentelemetry/resources": "^2.6.0", | ||
| "@opentelemetry/sdk-logs": "^0.213.0", | ||
| "@opentelemetry/semantic-conventions": "^1.40.0", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify the OpenTelemetry package versions exist on npm
echo "=== Checking `@opentelemetry/exporter-logs-otlp-http` versions ==="
curl -s https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http | jq '.["dist-tags"], .versions | keys[-5:]'
echo ""
echo "=== Checking `@opentelemetry/sdk-logs` versions ==="
curl -s https://registry.npmjs.org/@opentelemetry/sdk-logs | jq '.["dist-tags"], .versions | keys[-5:]'
echo ""
echo "=== Checking `@opentelemetry/resources` versions ==="
curl -s https://registry.npmjs.org/@opentelemetry/resources | jq '.["dist-tags"], .versions | keys[-5:]'Repository: line/abc-user-feedback
Length of output: 508
Fix non-existent OpenTelemetry package versions.
The versions ^0.213.0 specified for @opentelemetry/exporter-logs-otlp-http and @opentelemetry/sdk-logs do not exist on npm. The latest available versions are 0.57.2. Update these dependencies to valid versions (e.g., ^0.57.2). The @opentelemetry/resources version ^2.6.0 is correct.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/api/package.json` around lines 48 - 51, The package.json currently pins
non-existent OpenTelemetry versions for `@opentelemetry/exporter-logs-otlp-http`
and `@opentelemetry/sdk-logs` (shown as "^0.213.0"); update those dependency
entries to valid published versions (for example "^0.57.2") while leaving
`@opentelemetry/resources` at "^2.6.0" unchanged so npm install resolves
correctly; locate the dependency lines for
"@opentelemetry/exporter-logs-otlp-http" and "@opentelemetry/sdk-logs" and
replace their version strings with a valid version like "^0.57.2".
| export function createOtelLogTransport(): TransportTargetOptions { | ||
| return { | ||
| target: 'pino-opentelemetry-transport', | ||
| options: { | ||
| loggerName: 'abc-user-feedback-api', | ||
| }, | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
pino-opentelemetry-transport behavior when OTEL_EXPORTER_OTLP_LOGS_ENDPOINT not set
💡 Result:
When the OTEL_EXPORTER_OTLP_LOGS_ENDPOINT environment variable is not set for pino-opentelemetry-transport, the transport attempts to create an OTLP exporter using standard OpenTelemetry environment variable detection. The official documentation presents all examples with the endpoint explicitly set via environment variables and states that the collector URL is set using OTEL_EXPORTER_OTLP_LOGS_ENDPOINT or OTEL_EXPORTER_OTLP_ENDPOINT, implying it is required for export. No sources explicitly state the exact failure behavior (e.g., logs dropped silently, errors thrown, fallback to console), but OpenTelemetry OTLP exporters typically fail to export (logs buffered/dropped depending on processor config, possible errors logged) if no valid endpoint is configured, as seen in related OTEL JS exporter issues where connection failures lead to errors but do not crash the app. The transport runs in a Pino worker thread/process, so errors may not propagate to the main process. To use the transport effectively, set the endpoint; otherwise, logs will not be exported successfully.
Citations:
- 1: https://www.npmjs.com/package/pino-opentelemetry-transport
- 2: https://registry.npmjs.org/pino-opentelemetry-transport
- 3: https://github.com/pinojs/pino-opentelemetry-transport
- 4: OTLPExporterBase causes unhandled rejection on DNS resolution error open-telemetry/opentelemetry-js#4946
- 5: OTLPExporterBase reports connection issues to otel sink open-telemetry/opentelemetry-js#4444
🏁 Script executed:
#!/bin/bash
# Check the actual calls to createOtelLogTransport in app.module.ts and main.ts
echo "=== Checking app.module.ts ==="
find . -name "app.module.ts" -type f 2>/dev/null | head -1 | xargs cat -n 2>/dev/null | grep -A 5 -B 5 "createOtelLogTransport\|otel-log.config"
echo -e "\n=== Checking main.ts ==="
find . -name "main.ts" -type f 2>/dev/null | xargs cat -n 2>/dev/null | grep -A 5 -B 5 "createOtelLogTransport\|otel-log.config"
echo -e "\n=== Looking for OTEL configuration ==="
find . -type f \( -name "*config*" -o -name "*env*" \) 2>/dev/null | grep -i otel | head -5Repository: line/abc-user-feedback
Length of output: 2238
🏁 Script executed:
#!/bin/bash
# Read the full otel-log.config.ts file to see the implementation details
echo "=== Full otel-log.config.ts content ==="
cat apps/api/src/configs/otel-log.config.ts
echo -e "\n=== Searching for OTEL_EXPORTER_OTLP_LOGS_ENDPOINT usage ==="
rg "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT|OTEL_EXPORTER_OTLP_ENDPOINT" -A 2 -B 2
echo -e "\n=== Checking environment/configuration patterns ==="
find . -name ".env*" -o -name "*.env.example" 2>/dev/null | head -5
rg "OTEL_EXPORTER" --type ts --type js 2>/dev/null | head -20Repository: line/abc-user-feedback
Length of output: 15965
Transport is created unconditionally, but expected behavior when OTEL_EXPORTER_OTLP_LOGS_ENDPOINT is not set lacks clarity.
The createOtelLogTransport() function is called unconditionally in both app.module.ts and main.ts without checking whether OTEL_EXPORTER_OTLP_LOGS_ENDPOINT is configured. While the documentation marks this endpoint as optional, the expected behavior when it's missing is unclear. According to OpenTelemetry specifications, the pino-opentelemetry-transport package may log errors or silently buffer logs when the endpoint is unavailable.
Consider either:
- Adding a runtime check to conditionally register the transport only when the endpoint is configured, or
- Documenting the exact behavior when the endpoint is absent (e.g., whether error logs appear, logs are silently dropped, or export is gracefully skipped) to ensure operations understand the impact of missing configuration.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/api/src/configs/otel-log.config.ts` around lines 24 - 30, The transport
is always created by createOtelLogTransport() even when
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT is not set; update createOtelLogTransport so it
checks process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT and only returns a
TransportTargetOptions when that env var is defined (otherwise return
null/undefined), and update callers in app.module.ts and main.ts to register the
transport conditionally; alternatively, add a clear comment/docstring in
createOtelLogTransport describing the runtime behavior
(errors/buffering/dropping) when the endpoint is absent if you choose to keep
unconditional creation.
| const transport: pino.TransportMultiOptions = { | ||
| targets: [ | ||
| { target: 'pino-pretty', options: { singleLine: true } }, | ||
| createOtelLogTransport(), | ||
| ], | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check how the OTEL transport behaves when endpoint is not set
echo "=== Checking createOtelLogTransport implementation ==="
cat apps/api/src/configs/otel-log.config.ts
echo ""
echo "=== Checking if pino-opentelemetry-transport handles missing endpoint gracefully ==="
rg -n "OTEL_EXPORTER" apps/api/src/Repository: line/abc-user-feedback
Length of output: 1435
🏁 Script executed:
#!/bin/bash
# Check for error handling around transport initialization and config
echo "=== Checking main.ts around transport initialization ==="
sed -n '40,100p' apps/api/src/main.ts
echo ""
echo "=== Check if configService validates OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ==="
rg -n "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT" apps/api/src/ -A 2 -B 2
echo ""
echo "=== Check for try-catch or error handling patterns around transport ==="
rg -n "transport|createOtelLogTransport" apps/api/src/main.ts -A 2 -B 2Repository: line/abc-user-feedback
Length of output: 2900
🏁 Script executed:
#!/bin/bash
# Check app module for any OTEL config validation
echo "=== Check app.module.ts for OTEL config ==="
rg -n "otel\|OTEL" apps/api/src/app.module.ts -i
echo ""
echo "=== Check package.json for pino-opentelemetry-transport version ==="
cat package.json | grep -A 2 -B 2 "pino-opentelemetry"
echo ""
echo "=== Check for environment validation in config files ==="
find apps/api/src/configs -type f -name "*.ts" | head -10 | xargs grep -l "OTEL" 2>/dev/null
echo ""
echo "=== Look for any initialization or error handling patterns ==="
rg -n "throw|error|warn|Error" apps/api/src/main.ts | head -20Repository: line/abc-user-feedback
Length of output: 798
🏁 Script executed:
#!/bin/bash
# Check package.json directly
echo "=== Full package.json ==="
cat package.json | grep -A 500 '"dependencies"' | head -100Repository: line/abc-user-feedback
Length of output: 91
🏁 Script executed:
#!/bin/bash
# Find package.json
echo "=== Locate package.json ==="
find . -name "package.json" -type f | head -5
echo ""
echo "=== Check root package.json for pino-opentelemetry-transport ==="
if [ -f "package.json" ]; then
cat package.json | head -100
fiRepository: line/abc-user-feedback
Length of output: 1881
🏁 Script executed:
#!/bin/bash
# Check apps/api/package.json for pino-opentelemetry-transport
echo "=== apps/api/package.json dependencies ==="
cat apps/api/package.jsonRepository: line/abc-user-feedback
Length of output: 4619
🏁 Script executed:
#!/bin/bash
# Check if pino-opentelemetry-transport has any initialization checks
echo "=== Search for how pino-opentelemetry-transport handles missing endpoint ==="
rg -n "pino-opentelemetry-transport" apps/api/src/ -A 5 -B 5
echo ""
echo "=== Check if there's any try-catch or error handling in app module startup ==="
rg -n "PinoHttp\|transport" apps/api/src/main.ts -A 3 -B 1 | head -50
echo ""
echo "=== Check if there's any documentation or comments about OTEL setup ==="
find apps/api/src -name "*.ts" -type f | xargs grep -l "opentelemetry\|OTEL" -iRepository: line/abc-user-feedback
Length of output: 1188
🏁 Script executed:
#!/bin/bash
# Check app.module.ts for OTEL initialization
echo "=== Check app.module.ts for OTEL setup ==="
cat apps/api/src/app.module.ts | head -200
echo ""
echo "=== Search for any initialization or validation of OTEL endpoint ==="
rg -n "OTEL_EXPORTER\|endpoint\|Endpoint" apps/api/src/ -iRepository: line/abc-user-feedback
Length of output: 5918
OTEL transport is unconditionally added in multiple locations without checking if the endpoint is configured.
The transport configuration includes createOtelLogTransport() unconditionally in both apps/api/src/main.ts (lines 57-62) and apps/api/src/app.module.ts. The createOtelLogTransport() function has no defensive checks and always returns a transport config that attempts connection, even when OTEL_EXPORTER_OTLP_LOGS_ENDPOINT is not set.
This may cause:
- Unnecessary overhead when OTEL is not desired
- Connection errors or warnings in logs when the endpoint is unavailable
Consider conditionally including the OTEL transport only when the endpoint is configured.
💡 Proposed fix to conditionally include OTEL transport
+ const targets: pino.TransportTargetOptions[] = [
+ { target: 'pino-pretty', options: { singleLine: true } },
+ ];
+
+ if (process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {
+ targets.push(createOtelLogTransport());
+ }
+
const transport: pino.TransportMultiOptions = {
- targets: [
- { target: 'pino-pretty', options: { singleLine: true } },
- createOtelLogTransport(),
- ],
+ targets,
};📝 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.
| const transport: pino.TransportMultiOptions = { | |
| targets: [ | |
| { target: 'pino-pretty', options: { singleLine: true } }, | |
| createOtelLogTransport(), | |
| ], | |
| }; | |
| const targets: pino.TransportTargetOptions[] = [ | |
| { target: 'pino-pretty', options: { singleLine: true } }, | |
| ]; | |
| if (process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) { | |
| targets.push(createOtelLogTransport()); | |
| } | |
| const transport: pino.TransportMultiOptions = { | |
| targets, | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/api/src/main.ts` around lines 57 - 62, The OTEL transport is always
added to the pino "transport" targets via createOtelLogTransport(), which tries
to connect even when OTEL_EXPORTER_OTLP_LOGS_ENDPOINT isn't configured; update
the transport construction to only include createOtelLogTransport() when the
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT env var (or equivalent config method) is
present and non-empty, i.e., check process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
(or your config.get) before pushing createOtelLogTransport() into the targets
array; apply the same conditional pattern where transport is built (the
transport variable and any usage in main bootstrap and AppModule) so OTEL is
only initialized when the endpoint is set.
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…al environment variables
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Summary by CodeRabbit
New Features
Bug Fixes & Improvements
Documentation
Chores