Skip to content

feat: add server log file management to performance settings - #3369

Merged
seefs001 merged 4 commits into
QuantumNous:mainfrom
RedwindA:feat/logsManagement
Mar 21, 2026
Merged

feat: add server log file management to performance settings#3369
seefs001 merged 4 commits into
QuantumNous:mainfrom
RedwindA:feat/logsManagement

Conversation

@RedwindA

@RedwindA RedwindA commented Mar 21, 2026

Copy link
Copy Markdown
Contributor

📝 变更描述 / Description

在性能设置中新增了服务器日志文件管理功能。后端新增两个 API:查询日志文件列表(GET /performance/logs)和清理日志文件(DELETE /performance/logs),支持按文件数量保留和按天数保留两种清理模式,清理时会跳过当前正在写入的日志文件。前端在性能设置页面中新增日志管理卡片,展示日志目录、文件数 、总大小、时间范围等信息,并提供可视化的清理操作入口。

🚀 变更类型 / Type of change

  • ✨ 新功能 (New feature)

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自撰写此描述,去除了 AI 原始输出的冗余。
  • 深度理解: 我已完全理解这些更改的工作原理及潜在影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过了测试或手动验证。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

开发环境:

PixPin_2026-03-21_19-56-39.mp4

容器环境:

PixPin_2026-03-21_20-04-05.mp4

Summary by CodeRabbit

  • New Features

    • Server log management: view log directory, file count, total size and date range; clean up logs by keeping last N files or deleting logs older than N days; validation, confirmations and cleanup summaries.
  • New API

    • Endpoints to list log files and perform cleanup, returning counts, freed space and failure details.
  • Bug Fixes / Reliability

    • Safer runtime logging to avoid races during log rotation.
  • Documentation

    • Added translations for log management in EN/FR/JA/RU/VI/ZH-CN/ZH-TW.

Add API endpoints (GET/DELETE /api/performance/logs) to list and clean up
server log files by count or by age. Track the active log file path in
the logger to prevent deleting the currently open log. Add a management
UI section in the performance settings page with log directory info,
file statistics, and cleanup controls. Includes i18n translations for
all supported languages (en, fr, ja, ru, vi, zh-CN, zh-TW).
@coderabbitai

coderabbitai Bot commented Mar 21, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds server log inspection and cleanup endpoints, exposes current active log path in the logger, registers new API routes, updates frontend settings to display/manage logs, and adds i18n strings across multiple locales for log-management UI.

Changes

Cohort / File(s) Summary
Backend Log Management
controller/performance.go
Added GetLogFiles and CleanupLogFiles handlers, types LogFileInfo/LogFilesResponse, and getLogFiles() to scan common.LogDir, filter oneapi-*.log, sort by filename desc, compute stats, and delete files by count or age while excluding the active log.
Logger State & Writers
logger/logger.go, common/sys_log.go
Added exported GetCurrentLogPath() and RW-mutex-protected currentLogPath/currentLogFile; SetupLogger() atomically swaps/updates current file and closes previous handle; added common.LogWriterMu and wrapped log writes with RLock/RUnlock to avoid races during rotation.
API Routing
router/api-router.go
Registered GET /api/performance/logscontroller.GetLogFiles and DELETE /api/performance/logscontroller.CleanupLogFiles under /api/performance with RootAuth.
Frontend UI
web/src/pages/Setting/Performance/SettingsPerformance.jsx
Added logInfo state, fetchLogInfo() and cleanupLogFiles() flows, UI section showing log directory/size/count/date-range, cleanup controls (mode/value), confirmation dialog, and refresh after cleanup.
Internationalization
web/src/i18n/locales/{en,fr,ja,ru,vi,zh-CN,zh-TW}.json
Added translations for log retention/cleanup UI, labels for log metadata, confirmation/prompts, and success summaries using {{value}}, {{count}}, {{size}} placeholders across locales.

Sequence Diagram(s)

sequenceDiagram
    participant UI as Frontend UI
    participant Router as API Router
    participant Controller as Performance Controller
    participant Logger as Logger
    participant FS as File System

    rect rgba(100,150,200,0.5)
    Note over UI,FS: Get Log Files Flow
    UI->>Router: GET /api/performance/logs
    Router->>Controller: GetLogFiles()
    Controller->>Logger: GetCurrentLogPath()
    Logger-->>Controller: current log path
    Controller->>FS: scan `common.LogDir`
    FS-->>Controller: file list
    Controller->>Controller: filter/sort/aggregate
    Controller-->>Router: LogFilesResponse
    Router-->>UI: {enabled,count,totalSize,files[]}
    end

    rect rgba(200,100,100,0.5)
    Note over UI,FS: Cleanup Log Files Flow
    UI->>Router: DELETE /api/performance/logs?mode=X&value=Y
    Router->>Controller: CleanupLogFiles(mode,value)
    Controller->>Logger: GetCurrentLogPath()
    Logger-->>Controller: current log path
    Controller->>FS: identify eligible files (exclude active)
    Controller->>FS: delete files per policy
    FS-->>Controller: deletion results (deleted, failed, freed bytes)
    Controller-->>Router: cleanup response
    Router-->>UI: {deleted_count,freed_bytes,failed[]}
    UI->>Router: GET /api/performance/logs (refresh)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Calcium-Ion
  • seefs001

Poem

🐰 I hop through folders, counting each log,
I leave the live one, and clear the old clog.
With careful paws I prune by days or by count,
Freed space and tidy logs — a small happy amount.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.32% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add server log file management to performance settings' accurately and concisely summarizes the main change: introducing log file management functionality to the performance settings UI and backend APIs.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
controller/performance.go (1)

223-226: Sort the “keep latest N files” list by ModTime, not filename.

by_count is defined in time terms (“最近”), but the implementation currently relies on lexicographic Name ordering. That couples retention correctness to the log filename format and can keep older files if naming ever drifts.

💡 Suggested adjustment
-	// 按文件名降序排列(最新在前)
+	// 按修改时间降序排列(最新在前)
 	sort.Slice(files, func(i, j int) bool {
-		return files[i].Name > files[j].Name
+		if files[i].ModTime.Equal(files[j].ModTime) {
+			return files[i].Name > files[j].Name
+		}
+		return files[i].ModTime.After(files[j].ModTime)
 	})

Also applies to: 293-305

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controller/performance.go` around lines 223 - 226, The retention sorting
currently orders the files slice by Name; change both sort.Slice usages to sort
by modification time so we keep the most recent files by ModTime (newest first).
Replace the comparison using files[i].Name > files[j].Name with one that
compares modification timestamps (e.g.,
files[i].ModTime().After(files[j].ModTime()) or compare UnixNano) for the files
slice used in the "keep latest N files" logic, and apply the same change in the
second occurrence around the later block (the other sort.Slice call).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@controller/performance.go`:
- Around line 319-340: The current delete loop in the performance cleanup
handler always returns success: true and an empty message even when some
deletions failed; update the response logic (around variables toDelete,
deletedCount, freedBytes, failedFiles) so that if len(failedFiles) > 0 the JSON
response either sets "success": false or sets a non-empty "message" describing
the partial failure and listing/counting failed files; ensure the response still
includes deleted_count, freed_bytes and failed_files so the caller can show an
error/warning toast in SettingsPerformance.jsx.

In `@logger/logger.go`:
- Around line 60-69: There is a race where
gin.DefaultWriter/gin.DefaultErrorWriter are swapped and the old file closed
without synchronizing concurrent writes from logHelper and common/sys_log.go;
add a package-level logWriterMu sync.RWMutex and use it to protect the
swap/close sequence and all read/write uses: in the swap code around
currentLogPath/currentLogFile and gin.DefaultWriter/gin.DefaultErrorWriter (the
block that currently uses currentLogPathMu) acquire logWriterMu.Lock() before
changing writers and closing oldFile and release after close, and in logHelper
(and the six direct writes in common/sys_log.go) wrap accesses to
gin.DefaultWriter/gin.DefaultErrorWriter and the actual fmt.Fprintf calls with
logWriterMu.RLock()/RUnlock() so writers cannot be closed while being used.

In `@web/src/i18n/locales/en.json`:
- Line 2775: Update the English translation for the key "请输入有效的数值" to use
numeric-specific wording: change the value from "Please enter a valid value" to
"Please enter a valid number" so numeric validation messages are precise (locate
the mapping with key "请输入有效的数值" in en.json and replace the string value).

In `@web/src/i18n/locales/fr.json`:
- Line 1210: The French locale entry for the cleanup success message only has a
single form for the key "已清理 {{count}} 个日志文件,释放 {{size}}" but
SettingsPerformance (SettingsPerformance.jsx) passes a numeric count, so you
must provide plural variants for that key; update fr.json to include singular
and plural (and other locale-specific plural forms if your i18n library requires
them) that interpolate both {{count}} and {{size}} (e.g., a singular form for
count==1 and a plural form for other counts) so deleting one file uses the
singular wording and multiple files use the plural wording.

In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx`:
- Around line 177-185: The component currently treats an empty initial logInfo
as “logging disabled” because fetchLogInfo leaves state empty on errors; change
the logic so the UI only shows the “未启用” warning after a successful API response
that explicitly indicates logging is disabled — e.g., initialize logInfo to null
(or add an isLogInfoLoaded boolean), update fetchLogInfo (the async function) to
setLogInfo only on success and set the loaded flag on both success/failure, and
update the render condition to show the disabled message only when logInfo is
non-null and its property indicates disabled (or when isLogInfoLoaded is true
and the response says disabled). Ensure references to setLogInfo and
fetchLogInfo are updated accordingly.

---

Nitpick comments:
In `@controller/performance.go`:
- Around line 223-226: The retention sorting currently orders the files slice by
Name; change both sort.Slice usages to sort by modification time so we keep the
most recent files by ModTime (newest first). Replace the comparison using
files[i].Name > files[j].Name with one that compares modification timestamps
(e.g., files[i].ModTime().After(files[j].ModTime()) or compare UnixNano) for the
files slice used in the "keep latest N files" logic, and apply the same change
in the second occurrence around the later block (the other sort.Slice call).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 27ef6d68-4496-4b6c-b511-e931727abd4c

📥 Commits

Reviewing files that changed from the base of the PR and between 42846c6 and e904579.

📒 Files selected for processing (11)
  • controller/performance.go
  • logger/logger.go
  • router/api-router.go
  • web/src/i18n/locales/en.json
  • web/src/i18n/locales/fr.json
  • web/src/i18n/locales/ja.json
  • web/src/i18n/locales/ru.json
  • web/src/i18n/locales/vi.json
  • web/src/i18n/locales/zh-CN.json
  • web/src/i18n/locales/zh-TW.json
  • web/src/pages/Setting/Performance/SettingsPerformance.jsx

Comment thread controller/performance.go
Comment thread logger/logger.go
Comment thread web/src/i18n/locales/en.json Outdated
"已添加到白名单": "Ajouté à la liste blanche",
"已清空": "Vidé",
"已清空测试结果": "Résultats de test effacés",
"已清理 {{count}} 个日志文件,释放 {{size}}": "{{count}} fichiers journaux nettoyés, {{size}} libérés",

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

Add plural variants for the cleanup success message.

This key already receives count from web/src/pages/Setting/Performance/SettingsPerformance.jsx Lines 201-203, but the French locale only defines one form. Deleting a single file will still render the plural wording here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/i18n/locales/fr.json` at line 1210, The French locale entry for the
cleanup success message only has a single form for the key "已清理 {{count}}
个日志文件,释放 {{size}}" but SettingsPerformance (SettingsPerformance.jsx) passes a
numeric count, so you must provide plural variants for that key; update fr.json
to include singular and plural (and other locale-specific plural forms if your
i18n library requires them) that interpolate both {{count}} and {{size}} (e.g.,
a singular form for count==1 and a plural form for other counts) so deleting one
file uses the singular wording and multiple files use the plural wording.

Comment on lines +177 to +185
async function fetchLogInfo() {
try {
const res = await API.get('/api/performance/logs');
if (res.data.success) {
setLogInfo(res.data.data);
}
} catch (error) {
console.error('Failed to fetch log info:', error);
}

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

Don’t render the “logging disabled” warning until the API has actually said so.

logInfo starts out empty, and fetchLogInfo() leaves it that way on request errors. The current fallback therefore shows the “未启用” warning during first load and after /api/performance/logs failures.

💡 Minimal fix
-        {logInfo && logInfo.enabled ? (
+        {logInfo?.enabled ? (
           <>
             ...
           </>
-        ) : (
+        ) : logInfo?.enabled === false ? (
           <Banner
             type='warning'
             description={t('服务器日志功能未启用(未配置日志目录)')}
           />
         )}

Also applies to: 411-500

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx` around lines 177 -
185, The component currently treats an empty initial logInfo as “logging
disabled” because fetchLogInfo leaves state empty on errors; change the logic so
the UI only shows the “未启用” warning after a successful API response that
explicitly indicates logging is disabled — e.g., initialize logInfo to null (or
add an isLogInfoLoaded boolean), update fetchLogInfo (the async function) to
setLogInfo only on success and set the loaded flag on both success/failure, and
update the render condition to show the disabled message only when logInfo is
non-null and its property indicates disabled (or when isLogInfoLoaded is true
and the response says disabled). Ensure references to setLogInfo and
fetchLogInfo are updated accordingly.

…issues

- Fix data race on gin.DefaultWriter during log rotation by adding LogWriterMu
- Report partial failure when some log files fail to delete instead of always returning success
- Fix misleading "logging disabled" banner shown before API responds
- Fix en.json translation for numeric validation message

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

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

Inline comments:
In `@controller/performance.go`:
- Around line 291-331: The deletion logic records activeLogPath once via
logger.GetCurrentLogPath() and can race with logger.SetupLogger() rotation;
instead, ensure the active-path exclusion is checked atomically at remove time
by calling a logger helper that queries the current active path under the same
lock used in logger.SetupLogger() (e.g., add logger.IsActivePath(path) or
logger.GetCurrentLogPathLocked()) and use that check immediately before
os.Remove in the deletion loop (inside the for _, f := range toDelete loop) to
skip removing any file that is currently active; alternatively move the
active-path update into the same critical section as the writer swap in
logger.SetupLogger() so GetCurrentLogPath() cannot advance before writers are
swapped.

In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx`:
- Around line 198-214: The log card isn't refreshed when DELETE
/api/performance/logs returns success: false but still deletes some files;
ensure fetchLogInfo() is always called after the request so counts/sizes update:
in the handler in SettingsPerformance.jsx (the block using fetchLogInfo,
showSuccess, showError, setLogCleanupLoading), move or add a call to
fetchLogInfo() so it runs for both the success and failure branches (or call it
in the finally block before setLogCleanupLoading(false)); optionally use
res.data.data.deleted_count/freed_bytes to include a partial-success message but
always invoke fetchLogInfo() to refresh the UI.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 95cc60e2-549b-477b-9d0f-eb41e0c0b376

📥 Commits

Reviewing files that changed from the base of the PR and between e904579 and dcd0911.

📒 Files selected for processing (5)
  • common/sys_log.go
  • controller/performance.go
  • logger/logger.go
  • web/src/i18n/locales/en.json
  • web/src/pages/Setting/Performance/SettingsPerformance.jsx
✅ Files skipped from review due to trivial changes (1)
  • web/src/i18n/locales/en.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • logger/logger.go

Comment thread controller/performance.go
Comment thread web/src/pages/Setting/Performance/SettingsPerformance.jsx

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
web/src/pages/Setting/Performance/SettingsPerformance.jsx (1)

189-192: Consider using strict equality for null check.

Line 189 uses loose equality (== null), which also matches undefined. While this may be intentional given InputNumber can return either, using strict checks with explicit handling is clearer.

♻️ Optional: Use explicit strict checks
-    if (logCleanupValue == null || isNaN(logCleanupValue) || logCleanupValue < 1) {
+    if (logCleanupValue === null || logCleanupValue === undefined || isNaN(logCleanupValue) || logCleanupValue < 1) {

Or use Number.isNaN() which is stricter and handles null/undefined naturally:

-    if (logCleanupValue == null || isNaN(logCleanupValue) || logCleanupValue < 1) {
+    if (logCleanupValue == null || !Number.isFinite(logCleanupValue) || logCleanupValue < 1) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx` around lines 189 -
192, The null check on logCleanupValue uses loose equality (logCleanupValue ==
null) which also matches undefined; update the validation in the
SettingsPerformance.jsx handler to use strict checks: explicitly test for
logCleanupValue === null || logCleanupValue === undefined (or use a single
undefined check if null is impossible), and replace isNaN(logCleanupValue) with
Number.isNaN(logCleanupValue) to avoid coercion; keep the existing conditions
(logCleanupValue < 1) and call showError(t(...)) and return when any of these
stricter checks fail.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx`:
- Around line 189-192: The null check on logCleanupValue uses loose equality
(logCleanupValue == null) which also matches undefined; update the validation in
the SettingsPerformance.jsx handler to use strict checks: explicitly test for
logCleanupValue === null || logCleanupValue === undefined (or use a single
undefined check if null is impossible), and replace isNaN(logCleanupValue) with
Number.isNaN(logCleanupValue) to avoid coercion; keep the existing conditions
(logCleanupValue < 1) and call showError(t(...)) and return when any of these
stricter checks fail.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d7218971-ab08-410e-9c6c-bdc3fd1c1e66

📥 Commits

Reviewing files that changed from the base of the PR and between dcd0911 and 13122aa.

📒 Files selected for processing (1)
  • web/src/pages/Setting/Performance/SettingsPerformance.jsx

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
web/src/pages/Setting/Performance/SettingsPerformance.jsx (2)

177-186: Consider surfacing API error state to the user.

When the API returns success: false or throws an error, logInfo remains null and the user sees a blank section with no indication of failure. While this gracefully hides the feature, it may be confusing if the log management capability exists but fails to load.

A simple enhancement would be to track an error state to optionally show a brief message.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx` around lines 177 -
186, fetchLogInfo currently swallows API failures and leaves logInfo null,
producing a blank UI; add an error state (e.g. logError via useState) and update
fetchLogInfo to set logError when res.data.success is false or inside the catch
block (clear logInfo when error occurs), then update the component render logic
to display a concise error message when logError is set (and optionally a retry
button that calls fetchLogInfo); refer to fetchLogInfo, setLogInfo and the
logInfo state to locate where to set/clear the new logError state and where to
render the message.

468-477: Consider using CSS for vertical alignment instead of a hidden placeholder.

The hidden Text element is a workaround for aligning the button with adjacent inputs. This can be achieved more cleanly with flexbox alignment on the parent container.

♻️ Alternative approach using flexbox
-              <Col xs={24} sm={12} md={8}>
-                <div style={{ marginBottom: 12 }}>
-                  <Text
-                    strong
-                    style={{
-                      display: 'block',
-                      marginBottom: 8,
-                      visibility: 'hidden',
-                    }}
-                  >
-                    &nbsp;
-                  </Text>
+              <Col xs={24} sm={12} md={8} style={{ display: 'flex', alignItems: 'flex-end' }}>
+                <div style={{ marginBottom: 12 }}>
                 <Popconfirm
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx` around lines 468 -
477, Replace the hidden Text placeholder used to vertically align the button by
applying flexbox alignment on the parent container: remove the Text element with
style visibility: 'hidden' and instead set the parent wrapper (the element
containing the inputs and the button in SettingsPerformance.jsx) to display:
'flex' with alignItems: 'center' (or an appropriate alignItems value) and
gap/margin adjustments so the button lines up with adjacent inputs; update any
inline styles or classNames accordingly so Button and Text components align
without dummy elements.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx`:
- Around line 424-431: The date-range rendering can produce "Invalid Date" if
logInfo.oldest_time or logInfo.newest_time are invalid; update the ternary that
builds the object for key t('日志时间范围') to validate both values (e.g. use
Date.parse(...) or new Date(...).toString() !== 'Invalid Date') before
formatting with toLocaleDateString(); if either date is invalid, show a safe
fallback (empty string or '-' or localized "未知") instead of calling
toLocaleDateString() directly so the UI never displays "Invalid Date".

---

Nitpick comments:
In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx`:
- Around line 177-186: fetchLogInfo currently swallows API failures and leaves
logInfo null, producing a blank UI; add an error state (e.g. logError via
useState) and update fetchLogInfo to set logError when res.data.success is false
or inside the catch block (clear logInfo when error occurs), then update the
component render logic to display a concise error message when logError is set
(and optionally a retry button that calls fetchLogInfo); refer to fetchLogInfo,
setLogInfo and the logInfo state to locate where to set/clear the new logError
state and where to render the message.
- Around line 468-477: Replace the hidden Text placeholder used to vertically
align the button by applying flexbox alignment on the parent container: remove
the Text element with style visibility: 'hidden' and instead set the parent
wrapper (the element containing the inputs and the button in
SettingsPerformance.jsx) to display: 'flex' with alignItems: 'center' (or an
appropriate alignItems value) and gap/margin adjustments so the button lines up
with adjacent inputs; update any inline styles or classNames accordingly so
Button and Text components align without dummy elements.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6a65f997-c65e-440f-b7ef-cf10a56f7cf1

📥 Commits

Reviewing files that changed from the base of the PR and between 13122aa and 49db514.

📒 Files selected for processing (1)
  • web/src/pages/Setting/Performance/SettingsPerformance.jsx

Comment on lines +424 to +431
...(logInfo.oldest_time && logInfo.newest_time
? [
{
key: t('日志时间范围'),
value: `${new Date(logInfo.oldest_time).toLocaleDateString()} ~ ${new Date(logInfo.newest_time).toLocaleDateString()}`,
},
]
: []),

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

Add defensive check for date parsing.

If oldest_time or newest_time contain invalid values, new Date(...).toLocaleDateString() will render "Invalid Date" in the UI. Consider validating the dates before displaying.

🛡️ Proposed defensive fix
-                ...(logInfo.oldest_time && logInfo.newest_time
-                  ? [
-                      {
-                        key: t('日志时间范围'),
-                        value: `${new Date(logInfo.oldest_time).toLocaleDateString()} ~ ${new Date(logInfo.newest_time).toLocaleDateString()}`,
-                      },
-                    ]
-                  : []),
+                ...(() => {
+                  const oldest = new Date(logInfo.oldest_time);
+                  const newest = new Date(logInfo.newest_time);
+                  if (logInfo.oldest_time && logInfo.newest_time && !isNaN(oldest) && !isNaN(newest)) {
+                    return [{
+                      key: t('日志时间范围'),
+                      value: `${oldest.toLocaleDateString()} ~ ${newest.toLocaleDateString()}`,
+                    }];
+                  }
+                  return [];
+                })(),
📝 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
...(logInfo.oldest_time && logInfo.newest_time
? [
{
key: t('日志时间范围'),
value: `${new Date(logInfo.oldest_time).toLocaleDateString()} ~ ${new Date(logInfo.newest_time).toLocaleDateString()}`,
},
]
: []),
...((() => {
const oldest = new Date(logInfo.oldest_time);
const newest = new Date(logInfo.newest_time);
if (logInfo.oldest_time && logInfo.newest_time && !isNaN(oldest) && !isNaN(newest)) {
return [{
key: t('日志时间范围'),
value: `${oldest.toLocaleDateString()} ~ ${newest.toLocaleDateString()}`,
}];
}
return [];
})()),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/pages/Setting/Performance/SettingsPerformance.jsx` around lines 424 -
431, The date-range rendering can produce "Invalid Date" if logInfo.oldest_time
or logInfo.newest_time are invalid; update the ternary that builds the object
for key t('日志时间范围') to validate both values (e.g. use Date.parse(...) or new
Date(...).toString() !== 'Invalid Date') before formatting with
toLocaleDateString(); if either date is invalid, show a safe fallback (empty
string or '-' or localized "未知") instead of calling toLocaleDateString()
directly so the UI never displays "Invalid Date".

@seefs001
seefs001 merged commit 87b426f into QuantumNous:main Mar 21, 2026
1 check passed
RoodraNambisa added a commit to RoodraNambisa/new-api that referenced this pull request Mar 24, 2026
commit dbf900a
Author: CaIon <i@caion.me>
Date:   Wed Mar 25 00:04:01 2026 +0800

    fix: restore doubao coding plan deprecation and regex ignored models lost during conflict resolution

commit 7399e47
Author: CaIon <i@caion.me>
Date:   Tue Mar 24 23:56:10 2026 +0800

    feat: add slide-in animations and update translations for new UI elements

    # Conflicts:
    #	web/src/components/table/channels/modals/EditChannelModal.jsx

commit a5e2026
Author: CaIon <i@caion.me>
Date:   Tue Mar 24 23:53:50 2026 +0800

    security: harden Docker and release CI workflows

    - Pin all GitHub Actions to commit SHA to prevent supply chain attacks
    - Enable SLSA provenance attestation (mode=max) and SBOM generation
    - Add cosign keyless signing for Docker images via GitHub OIDC
    - Capture and output image digests to GitHub Job Summary
    - Pin Dockerfile base images to digest (bun:1, golang:1.26.1-alpine, debian:bookworm-slim)
    - Add SHA256 checksum generation for binary releases (Linux/macOS/Windows)
    - Update actions/checkout v3->v4, actions/setup-go v3->v5 in release.yml

commit 9ae9040
Merge: 0191a68 ded4a12
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 15:04:06 2026 +0800

    Merge pull request QuantumNous#3401 from seefs001/fix/convert-openai-detail-field

    fix: the "detail" field is empty, an empty field was sent to upstream

commit 0191a68
Merge: 16221f8 9ecad90
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 15:03:57 2026 +0800

    Merge pull request QuantumNous#3400 from seefs001/fix/openai-usage

    refactor: optimize billing flow for OpenAI-to-Anthropic convert

commit 16221f8
Merge: 763c3ff 929b506
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 15:03:47 2026 +0800

    Merge pull request QuantumNous#3399 from seefs001/refactor/codex-usage

    Refactor/codex usage

commit 763c3ff
Merge: c667e47 e520977
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 15:03:36 2026 +0800

    Merge pull request QuantumNous#3331 from seefs001/fix/claude-beta-query

    fix: apply forced beta query at final upstream URL stage

commit c667e47
Merge: 216b94d b09337e
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 15:03:23 2026 +0800

    Merge pull request QuantumNous#3333 from seefs001/fix/channel-affinity-disable

    fix: honor channel affinity skip-retry when channel is disabled

commit 216b94d
Merge: 49eb533 e9f8f62
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 15:03:01 2026 +0800

    Merge pull request QuantumNous#3335 from seefs001/chore/adjuct-default-settings

    adjuct default settings

commit 49eb533
Merge: 7693eda 45f65c2
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 15:02:44 2026 +0800

    Merge pull request QuantumNous#3381 from seefs001/feature/regex-ignored-upstream-models

    feat: support regex-prefixed ignored upstream models

commit 7693eda
Merge: d6982c8 f40eb4e
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 15:02:34 2026 +0800

    Merge pull request QuantumNous#3393 from seefs001/fix/oauth-bind

    fix: oauth bind callback handling

commit ded4a12
Author: Seefs <i@seefs.me>
Date:   Mon Mar 23 15:00:20 2026 +0800

    fix: the "detail" field is empty, an empty field was sent to the upstream system.

commit d6982c8
Merge: deff59a 6c074ef
Author: Calcium-Ion <i@caion.me>
Date:   Mon Mar 23 14:53:13 2026 +0800

    Merge pull request QuantumNous#3379 from seefs001/refactor/rm-coding-plan

    fix: disable doubao coding plan selection

commit 9ecad90
Author: Seefs <i@seefs.me>
Date:   Mon Mar 23 14:22:12 2026 +0800

    refactor: optimize billing flow for OpenAI-to-Anthropic convert

commit 929b506
Author: Seefs <i@seefs.me>
Date:   Mon Mar 23 13:54:54 2026 +0800

    refactor: simplify codex account modal and collapse raw json by default

commit 755ece2
Author: Seefs <i@seefs.me>
Date:   Mon Mar 23 00:58:59 2026 +0800

    refactor: simplify codex account modal and collapse raw json by default

commit f40eb4e
Author: Seefs <i@seefs.me>
Date:   Mon Mar 23 00:48:55 2026 +0800

    fix: oauth bind callback handling

commit 45f65c2
Author: Seefs <i@seefs.me>
Date:   Sun Mar 22 15:43:03 2026 +0800

    feat: support regex-prefixed ignored upstream models

commit 6c074ef
Author: Seefs <i@seefs.me>
Date:   Sun Mar 22 15:01:09 2026 +0800

    fix: disable doubao coding plan selection

commit deff59a
Author: CaIon <i@caion.me>
Date:   Sun Mar 22 13:55:03 2026 +0800

    fix: increase StreamScannerMaxBufferMB limit and add handling for gpt-5.4-nano prefix

commit 3c51608
Merge: 4d675b4 e80d867
Author: Seefs <40468931+seefs001@users.noreply.github.com>
Date:   Sun Mar 22 00:43:13 2026 +0800

    Merge pull request QuantumNous#3360 from lcq225/docs/improve-bt-installation-guide

    docs: 完善宝塔面板部署教程并修复链接错误

commit 4d675b4
Merge: 87b426f 2c3ae32
Author: Seefs <40468931+seefs001@users.noreply.github.com>
Date:   Sun Mar 22 00:39:49 2026 +0800

    Merge pull request QuantumNous#3357 from wenyifancc/cache_llama_cpp

    feat: Add support for counting cache-hit tokens in llama.cpp

commit 87b426f
Merge: 42846c6 49db514
Author: Seefs <40468931+seefs001@users.noreply.github.com>
Date:   Sun Mar 22 00:32:01 2026 +0800

    Merge pull request QuantumNous#3369 from RedwindA/feat/logsManagement

    feat: add server log file management to performance settings

commit 49db514
Author: RedwindA <austinaosid@gmail.com>
Date:   Sat Mar 21 21:48:31 2026 +0800

    fix: align log cleanup button with other controls in the row

commit 13122aa
Author: RedwindA <austinaosid@gmail.com>
Date:   Sat Mar 21 21:11:52 2026 +0800

    fix: refresh log info on partial delete failure

commit dcd0911
Author: RedwindA <austinaosid@gmail.com>
Date:   Sat Mar 21 20:40:39 2026 +0800

    fix: log management race condition, partial delete reporting, and UX issues

    - Fix data race on gin.DefaultWriter during log rotation by adding LogWriterMu
    - Report partial failure when some log files fail to delete instead of always returning success
    - Fix misleading "logging disabled" banner shown before API responds
    - Fix en.json translation for numeric validation message

commit e904579
Author: RedwindA <austinaosid@gmail.com>
Date:   Sat Mar 21 20:06:49 2026 +0800

    feat: add server log file management to performance settings

    Add API endpoints (GET/DELETE /api/performance/logs) to list and clean up
    server log files by count or by age. Track the active log file path in
    the logger to prevent deleting the currently open log. Add a management
    UI section in the performance settings page with log directory info,
    file statistics, and cleanup controls. Includes i18n translations for
    all supported languages (en, fr, ja, ru, vi, zh-CN, zh-TW).

commit e80d867
Author: mm413 <lcq225@163.com>
Date:   Fri Mar 20 20:13:30 2026 +0800

    Update docs/installation/BT.md

    Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

commit cf86fe5
Author: lcq225 <lcq225@163.com>
Date:   Fri Mar 20 20:06:09 2026 +0800

    docs: 完善宝塔面板部署教程并修复链接错误

    - 完善 docs/installation/BT.md,从 2 行扩展为完整教程
    - 包含前置要求、安装步骤、配置说明、常见问题
    - 修复 README.zh_CN.md 中的链接错误
    - 所有内容基于官方文档 https://docs.newapi.pro 编写

commit 2c3ae32
Author: wenyifan <yifan.wen@eisgroup.com>
Date:   Fri Mar 20 16:48:04 2026 +0800

    fix map

commit 498199b
Author: wenyifan <yifan.wen@eisgroup.com>
Date:   Fri Mar 20 16:38:48 2026 +0800

    fix code quality

commit ff29900
Author: wenyifan <yifan.wen@eisgroup.com>
Date:   Fri Mar 20 16:10:18 2026 +0800

    feat: Add support for counting cache-hit tokens in llama.cpp OpenAI-Compatible API

commit eff5185
Author: Seefs <i@seefs.me>
Date:   Fri Mar 20 16:00:36 2026 +0800

    refactor: show codex account info tag and highlight plan type in usage modal

commit e9f8f62
Author: Seefs <i@seefs.me>
Date:   Thu Mar 19 16:58:13 2026 +0800

    fix: raise default overload disk threshold to 95%

commit 5fe8e98
Author: Seefs <i@seefs.me>
Date:   Thu Mar 19 16:56:28 2026 +0800

    fix: default codex and claude channel affinity templates to skip retry on failure

commit e520977
Author: Seefs <i@seefs.me>
Date:   Thu Mar 19 15:49:50 2026 +0800

    fix: apply forced beta query at final upstream URL stage

commit b09337e
Author: Seefs <i@seefs.me>
Date:   Wed Mar 18 16:08:31 2026 +0800

    fix: honor channel affinity skip-retry when preferred channel is disabled
VeryGoodUser1 pushed a commit to xmz-ai/new-api that referenced this pull request Apr 3, 2026
feat: add server log file management to performance settings
@RedwindA
RedwindA deleted the feat/logsManagement branch July 23, 2026 07:03
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