Skip to content

release 8.2612.110#2706

Merged
chiol merged 235 commits intomainfrom
dev
Mar 24, 2026
Merged

release 8.2612.110#2706
chiol merged 235 commits intomainfrom
dev

Conversation

@chiol
Copy link
Copy Markdown
Contributor

@chiol chiol commented Mar 20, 2026

Summary by CodeRabbit

  • New Features

    • Optional OpenTelemetry log export for the API and a local OTEL test stack for verification.
  • Bug Fixes & Improvements

    • Bumped Node/toolchain and many package versions for stability and tooling; pinned runtime images.
  • Documentation

    • Added multilingual OpenTelemetry setup, local verification steps, usage examples, and troubleshooting guidance.
  • Chores

    • Updated CI Docker action versions and build tooling, added a Vector observability pipeline and OTEL compose setup, and sample env entries for OTEL.

renovate bot and others added 30 commits January 20, 2026 04:23
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>
renovate bot and others added 5 commits March 19, 2026 12:48
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>
@chiol chiol requested a review from jihun March 20, 2026 06:51
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 20, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds 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

Cohort / File(s) Summary
GitHub Actions Workflows
​.github/workflows/docker-dev-image.yml, ​.github/workflows/docker-prod-image.yml
Bumped Docker action majors: setup-buildx-action v3→v4, metadata-action v5→v6, login-action v3→v4, bake-action v6→v7. Removed bake-target inputs from prod metadata steps.
Node & Toolchain
.nvmrc, package.json, pnpm-workspace.yaml, tooling/github/setup/action.yml
Node/pnpm/tooling pins updated: Node → 24.14.0, packageManagerpnpm@10.32.1, engines updated, pnpm workspace/catalog and action-setup bumped.
API — OTEL logging code
apps/api/src/configs/otel-log.config.ts, apps/api/src/app.module.ts, apps/api/src/main.ts, apps/api/.env.example
Added createOtelLogTransport() and async logger setup; configured pino to use both pretty console and OTEL transport; added OTEL env examples.
API package changes
apps/api/package.json
Bumped many dependencies and added OpenTelemetry logging packages (@opentelemetry/*, pino-opentelemetry-transport).
OTEL test stack & Vector config
docker/docker-compose.otel-test.yml, docker/vector.yml
Added Docker Compose stack (OpenSearch, Dashboards, Vector) and Vector pipeline to accept OTLP (gRPC/HTTP), remap/enrich logs, sink to OpenSearch and console.
Docs & Guides (multi-locale)
apps/api/README.md, apps/docs/docs/.../05-configuration.md, apps/docs/i18n/.../05-configuration.md
Inserted OTEL log export section, local verification using new docker-compose, env var docs, updated code fences, troubleshooting entries, and renumbered sections.
Dockerfiles
docker/api.dockerfile, docker/docs.dockerfile, docker/web.dockerfile
Pinned base image from node:24-alpinenode:24.14.0-alpine.
Web & CLI updates
apps/web/package.json, apps/cli/package.json, apps/web/.prettierignore, apps/web/next-env.d.ts
Bumped web/cli deps, added next-env.d.ts to prettierignore, updated Next routes typing path.
Other packages & tooling
apps/e2e/package.json, apps/docs/package.json, packages/*, tooling/*
Various dependency version bumps across e2e, docs, shared packages, and tooling (Playwright, React, PostCSS, eslint plugins, etc.).
Monorepo config
turbo.json
Added APP_VERSION and OTEL_EXPORTER_OTLP_LOGS_ENDPOINT to globalEnv.
i18n cleanup
apps/docs/i18n/ko/docusaurus-plugin-content-blog/options.json
Removed Korean blog plugin translation/options entries.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • jihun
  • chiol
🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'release 8.2612.110' is a version number that doesn't describe the actual changes in the pull request. The PR contains dependency upgrades, Docker image updates, OpenTelemetry logging setup, documentation updates, and workflow configuration changes—none of which are conveyed by the title. Use a descriptive title that summarizes the main changes, such as 'Add OpenTelemetry logging support and update dependencies' or 'chore: upgrade dependencies and configure OTEL log export'.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

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.

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@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: 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-alpine may 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.yml expects OPENSEARCH_ENDPOINT, OPENSEARCH_USERNAME, and OPENSEARCH_PASSWORD environment variables. While OPENSEARCH_ENDPOINT defaults to http://opensearch-node:9200 which matches this setup, explicitly setting these would be clearer and more maintainable.

Additionally, since plugins.security.disabled=true on 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-node but Docker Compose's depends_on only 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: 5

Then 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 user and password:

user: '${OPENSEARCH_USERNAME:-}'
password: '${OPENSEARCH_PASSWORD:-}'

When OPENSEARCH_USERNAME and OPENSEARCH_PASSWORD are 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:

  1. Using a conditional auth strategy, or
  2. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 200f693 and d678984.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (33)
  • .github/workflows/docker-dev-image.yml
  • .github/workflows/docker-prod-image.yml
  • .nvmrc
  • apps/api/.env.example
  • apps/api/README.md
  • apps/api/package.json
  • apps/api/src/app.module.ts
  • apps/api/src/configs/otel-log.config.ts
  • apps/api/src/main.ts
  • apps/cli/package.json
  • apps/docs/docs/02-developer-guide/01-installation/05-configuration.md
  • apps/docs/i18n/en/docusaurus-plugin-content-docs/current/02-developer-guide/01-installation/05-configuration.md
  • apps/docs/i18n/ja/docusaurus-plugin-content-docs/current/02-developer-guide/01-installation/05-configuration.md
  • apps/docs/i18n/ko/docusaurus-plugin-content-blog/options.json
  • apps/docs/package.json
  • apps/e2e/package.json
  • apps/web/.prettierignore
  • apps/web/next-env.d.ts
  • apps/web/package.json
  • docker/api.dockerfile
  • docker/docker-compose.otel-test.yml
  • docker/docs.dockerfile
  • docker/vector.yml
  • docker/web.dockerfile
  • package.json
  • packages/ufb-react/package.json
  • packages/ufb-shared/package.json
  • packages/ufb-tailwindcss/package.json
  • pnpm-workspace.yaml
  • tooling/eslint/package.json
  • tooling/github/setup/action.yml
  • tooling/prettier/package.json
  • turbo.json
💤 Files with no reviewable changes (1)
  • apps/docs/i18n/ko/docusaurus-plugin-content-blog/options.json

Comment on lines +48 to +51
"@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",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 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".

Comment on lines +24 to +30
export function createOtelLogTransport(): TransportTargetOptions {
return {
target: 'pino-opentelemetry-transport',
options: {
loggerName: 'abc-user-feedback-api',
},
};
Copy link
Copy Markdown
Contributor

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

🌐 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:


🏁 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 -5

Repository: 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 -20

Repository: 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:

  1. Adding a runtime check to conditionally register the transport only when the endpoint is configured, or
  2. 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.

Comment on lines +57 to +62
const transport: pino.TransportMultiOptions = {
targets: [
{ target: 'pino-pretty', options: { singleLine: true } },
createOtelLogTransport(),
],
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 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 2

Repository: 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 -20

Repository: 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 -100

Repository: 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
fi

Repository: 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.json

Repository: 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" -i

Repository: 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/ -i

Repository: 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.

Suggested change
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.

renovate bot and others added 19 commits March 20, 2026 13:34
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>
@chiol chiol merged commit a1ecb95 into main Mar 24, 2026
8 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