Skip to content

fix: debug log level from .env not applied on startup#624

Merged
sj817 merged 2 commits into
mainfrom
copilot/fix-debug-log-level-issue
Mar 24, 2026
Merged

fix: debug log level from .env not applied on startup#624
sj817 merged 2 commits into
mainfrom
copilot/fix-debug-log-level-issue

Conversation

Copilot AI commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

logger is instantiated at module evaluation time — before dotenv.config() runs in start() — so process.env.LOG_LEVEL is unset at that point and the logger defaults to 'info'. The only code path that synced logger.level post-load was the initEnv file-watcher callback, meaning the configured level only took effect after a manual file save triggered the watcher.

Changes

  • packages/core/src/index.ts: After dotenv.config() in start(), explicitly sync logger.level from the now-populated process.env.LOG_LEVEL:
dotenv.config({
  path: `${path.resolve(process.cwd(), process.env.EBV_FILE!)}`,
  override: true,
})
logger.level = (process.env.LOG_LEVEL || 'info') as LoggerLevel

This mirrors the identical assignment already present in the initEnv watch callback (env.ts:90) — just applied at startup rather than only on file change.

Original prompt

This section details on the original issue you should resolve

<issue_title>Bug: debug 日志等级极个别情况下不生效</issue_title>
<issue_description>### 描述问题

使用命令 cross-env EBV_FILE=\"development.env\" tsx watch --include \"src/**/*.ts\" src/app.ts --trace-deprecation 进行插件包开发时

复现步骤

  1. 使用 cross-env EBV_FILE=\"development.env\" tsx watch --include \"src/**/*.ts\" src/app.ts --trace-deprecation 启动开发环境
  2. 启动时没有任何debug等级的日志
  3. development.env 文件中手动进行一次保存后,debug等级的日志才会出现

预期行为

启动即刻打印debug等级日志

实际行为

无debug等级日志

操作系统

win11

Node.js 版本

22.16.0

项目版本

1.10.20

附加信息

file: development.env

# 是否启用HTTP
HTTP_ENABLE="true"
# HTTP监听端口
HTTP_PORT="7777"
# HTTP监听地址
HTTP_HOST="0.0.0.0"
# HTTP鉴权秘钥 仅用于karin自身Api
HTTP_AUTH_KEY="a"
# ws_server鉴权秘钥
WS_SERVER_AUTH_KEY=""
# 是否启用Redis 关闭后将使用内部虚拟Redis
REDIS_ENABLE="true"
# 重启是否调用pm2 如果不调用则会直接关机 此配置适合有进程守护的程序
PM2_RESTART="true"
# 日志等级
LOG_LEVEL="debug"
# 日志保留天数
LOG_DAYS_TO_KEEP="7"
# 日志文件最大大小 如果此项大于0则启用日志分割
LOG_MAX_LOG_SIZE="0"
# 日志函数颜色
LOG_FNC_COLOR="#E1D919"
# 日志实时Api最多支持同时连接数
LOG_MAX_CONNECTIONS="5"
# ffmpeg
FFMPEG_PATH=""
# ffprobe
FFPROBE_PATH=""
# ffplay
FFPLAY_PATH=""
# 这里请勿修改
RUNTIME="tsx"
# 运行模式
NODE_ENV="development"
# tsx watch
TSX_WATCH="false"

</issue_description>

Comments on the Issue (you are @copilot in this section)

@ikenxuan 十四:刚刚有人反馈说 debug 日志等级有点抽象,启动插件开发环境的时候,日志死活不显示,非得手动保存下 env 文件才能刷出来,典中典现场,win11+node22组合拳直接把人送走,估计又得手搓一波配置,兄弟们有类似情况可以关注下,别被阴到。

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Summary by Sourcery

错误修复:

  • 在启动过程中立即将从解析后的 .env 中获取的 LOG_LEVEL 应用于日志记录器,这样调试日志在无需修改 env 文件的情况下就能生效。
Original summary in English

Summary by Sourcery

Bug Fixes:

  • Apply LOG_LEVEL from the parsed .env to the logger immediately during startup so debug logs are effective without requiring an env file change.

Copilot AI changed the title [WIP] Fix debug log level not effective in rare cases fix: debug log level from .env not applied on startup Mar 23, 2026
Copilot AI requested a review from sj817 March 23, 2026 23:34
@sj817
sj817 marked this pull request as ready for review March 24, 2026 04:54
Copilot AI review requested due to automatic review settings March 24, 2026 04:54
@github-actions

Copy link
Copy Markdown
Contributor

你可以通过以下命令安装该版本:

pnpm add https://pkg.pr.new/node-karin@a7521f3 -w

@sourcery-ai

sourcery-ai Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor
审阅者指南(在小型 PR 上折叠)

审阅者指南

确保在启动期间 dotenv 配置运行之后,记录器(logger)的运行时日志级别与 .env 文件中的 LOG_LEVEL 保持同步,这样从进程启动开始就能生效 debug 级别日志,而不是只能在 env 文件变更后才生效。

启动时初始化日志级别的时序图

sequenceDiagram
  actor Developer
  participant NodeProcess
  participant CoreIndex as core_start
  participant Dotenv
  participant Logger

  Developer->>NodeProcess: run dev command
  NodeProcess->>CoreIndex: call start()
  CoreIndex->>Dotenv: dotenv.config(path = EBV_FILE, override = true)
  Dotenv-->>CoreIndex: process.env populated
  CoreIndex->>Logger: set level = (process.env.LOG_LEVEL || 'info') as LoggerLevel
  Logger-->>CoreIndex: level updated before other initialization
  Note over CoreIndex,Logger: Logger now respects LOG_LEVEL from .env at startup
Loading

Logger 与日志级别类型的类图

classDiagram
  class Logger {
    +LoggerLevel level
  }

  class LoggerLevel

  Logger --> LoggerLevel : uses
Loading

文件级变更

变更 详情 文件
在启动时于 dotenv 配置运行之后,从 LOG_LEVEL 环境变量同步 logger 级别。
  • 从 logger 服务的类型模块中导入 LoggerLevel 类型,以便对 logger.level 进行类型安全的赋值。
  • 在 start() 中,在 dotenv 填充完 process.env 后立刻将 logger.level 设置为 LOG_LEVEL(默认为 'info'),与之前仅存在于 env 文件监视器回调中的行为保持一致。
  • 在注释中说明 logger 在解析 env 之前就已实例化,因此需要在配置之后显式同步日志级别,才能在首次运行时让日志级别生效。
packages/core/src/index.ts

与关联 issue 的对照评估

Issue 目标 是否解决 说明
#517 确保 .env(例如 development.env)中的 LOG_LEVEL 在启动时立即应用到 logger 上,这样无需手动保存 env 文件就能打印出 debug 级别日志。

可能关联的 issue


提示与命令

与 Sourcery 交互

  • 触发新的审阅: 在 pull request 上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审阅评论。
  • 从审阅评论生成 GitHub issue: 在审阅评论下回复,要求 Sourcery 从该评论创建一个 issue。你也可以在评论中回复 @sourcery-ai issue,以此从该审阅评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。也可以在 pull request 中评论 @sourcery-ai title,以随时(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文任意位置写上 @sourcery-ai summary,即可在指定位置生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary,以随时(重新)生成摘要。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不想再看到它们,这会非常有用。
  • 关闭所有 Sourcery 审阅: 在 pull request 中评论 @sourcery-ai dismiss,即可关闭所有现有的 Sourcery 审阅。特别适用于你希望从一次全新审阅开始的情况——别忘了再评论 @sourcery-ai review 来触发新的审阅!

自定义你的使用体验

访问你的 控制面板 来:

  • 启用或停用审阅功能,例如 Sourcery 自动生成的 pull request 摘要、审阅者指南等。
  • 更改审阅语言。
  • 添加、删除或编辑自定义审阅指令。
  • 调整其他审阅设置。

获取帮助

Original review guide in English
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Ensures the logger's runtime log level is synchronized with LOG_LEVEL from the .env file immediately after dotenv config runs during startup, so debug-level logging is effective from process start instead of only after an env file change.

Sequence diagram for logger level initialization on startup

sequenceDiagram
  actor Developer
  participant NodeProcess
  participant CoreIndex as core_start
  participant Dotenv
  participant Logger

  Developer->>NodeProcess: run dev command
  NodeProcess->>CoreIndex: call start()
  CoreIndex->>Dotenv: dotenv.config(path = EBV_FILE, override = true)
  Dotenv-->>CoreIndex: process.env populated
  CoreIndex->>Logger: set level = (process.env.LOG_LEVEL || 'info') as LoggerLevel
  Logger-->>CoreIndex: level updated before other initialization
  Note over CoreIndex,Logger: Logger now respects LOG_LEVEL from .env at startup
Loading

Class diagram for logger and log level type

classDiagram
  class Logger {
    +LoggerLevel level
  }

  class LoggerLevel

  Logger --> LoggerLevel : uses
Loading

File-Level Changes

Change Details Files
Synchronize logger level from LOG_LEVEL env var at startup after dotenv config runs.
  • Import LoggerLevel type from the logger service types module for type-safe assignment of logger.level.
  • Set logger.level to LOG_LEVEL (defaulting to 'info') immediately in start() after dotenv has populated process.env, matching the behavior previously only present in the env file watcher callback.
  • Document in comments that logger is instantiated before env parsing, requiring explicit post-config level sync to make log level effective on first run.
packages/core/src/index.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#517 Ensure that the LOG_LEVEL from the .env (e.g., development.env) is applied to the logger immediately on startup, so debug-level logs are printed without needing to manually save the env file.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

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.

Hey - 我在这里给出了一些高层次的反馈:

  • 与其使用 (process.env.LOG_LEVEL || 'info') as LoggerLevel 这样的类型断言,不如考虑通过项目中其他地方用于日志级别的同一套校验/规范化逻辑来处理,这样可以避免意外值在没有任何提示的情况下绕过类型安全。
  • 新增的注释提到 dotenv.config() 已经执行完成,但当前代码片段附近并没有展示这行调用;可能更清晰的做法是要么把这个赋值语句移动到 config 调用之后紧接着的位置,要么重新措辞注释,使其与实际的控制流保持一致。
  • 现在你至少在两个地方从 process.env.LOG_LEVEL 同步 logger.level(启动时以及 env 文件监听器中);可以考虑抽取一个小的辅助方法(例如 syncLoggerLevelFromEnv()),把这部分逻辑集中到一个地方,保证行为一致。
供 AI Agents 使用的提示词
Please address the comments from this code review:

## Overall Comments
- 与其使用 `(process.env.LOG_LEVEL || 'info') as LoggerLevel` 这样的类型断言,不如考虑通过项目中其他地方用于日志级别的同一套校验/规范化逻辑来处理,这样可以避免意外值在没有任何提示的情况下绕过类型安全。
- 新增的注释提到 `dotenv.config()` 已经执行完成,但当前代码片段附近并没有展示这行调用;可能更清晰的做法是要么把这个赋值语句移动到 config 调用之后紧接着的位置,要么重新措辞注释,使其与实际的控制流保持一致。
- 现在你至少在两个地方从 `process.env.LOG_LEVEL` 同步 `logger.level`(启动时以及 env 文件监听器中);可以考虑抽取一个小的辅助方法(例如 `syncLoggerLevelFromEnv()`),把这部分逻辑集中到一个地方,保证行为一致。

Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English

Hey - I've left some high level feedback:

  • Instead of casting (process.env.LOG_LEVEL || 'info') as LoggerLevel, consider routing this through the same validation/normalization logic used elsewhere for log levels so an unexpected value doesn’t silently bypass type safety.
  • The new comment refers to dotenv.config() completing, but the code snippet here doesn’t show that call nearby; it might be clearer to either move this assignment directly after the config call or reword the comment to match the actual control flow.
  • You now have at least two places that sync logger.level from process.env.LOG_LEVEL (startup and the env-file watcher); consider extracting a small helper (e.g. syncLoggerLevelFromEnv()) to keep the behavior consistent in one place.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Instead of casting `(process.env.LOG_LEVEL || 'info') as LoggerLevel`, consider routing this through the same validation/normalization logic used elsewhere for log levels so an unexpected value doesn’t silently bypass type safety.
- The new comment refers to `dotenv.config()` completing, but the code snippet here doesn’t show that call nearby; it might be clearer to either move this assignment directly after the config call or reword the comment to match the actual control flow.
- You now have at least two places that sync `logger.level` from `process.env.LOG_LEVEL` (startup and the env-file watcher); consider extracting a small helper (e.g. `syncLoggerLevelFromEnv()`) to keep the behavior consistent in one place.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copilot AI left a comment

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.

Pull request overview

This PR fixes an initialization-order issue where logger is created before .env variables are loaded, causing LOG_LEVEL=debug (and other non-default levels) to be ignored until the env file watcher triggers.

Changes:

  • After dotenv.config() runs in start(), explicitly synchronize logger.level from process.env.LOG_LEVEL (defaulting to info).
  • Add inline documentation explaining why the explicit sync is required at startup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sj817
sj817 merged commit df39819 into main Mar 24, 2026
8 checks passed
@sj817
sj817 deleted the copilot/fix-debug-log-level-issue branch March 24, 2026 04:58
@github-actions github-actions Bot mentioned this pull request Mar 24, 2026
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.

Bug: debug 日志等级极个别情况下不生效

3 participants