diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json
index a881e0d18..951f71920 100644
--- a/src/i18n/locales/en.json
+++ b/src/i18n/locales/en.json
@@ -531,6 +531,7 @@
"lyrics": "lyrics",
"transcoding": "transcoding",
"discord": "discord",
+ "logger": "logger",
"playerFilters": "player filters"
},
"sidebar": {
@@ -780,6 +781,12 @@
"lyricFetchProvider": "providers to fetch lyrics from",
"lyricOffset_description": "offset the lyric by the specified amount of milliseconds",
"lyricOffset": "lyric offset (ms)",
+ "logLevel": "log level",
+ "logLevel_description": "sets the minimum log level to display. debug shows all logs, error only shows errors",
+ "logLevel_optionDebug": "debug",
+ "logLevel_optionError": "error",
+ "logLevel_optionInfo": "info",
+ "logLevel_optionWarn": "warn",
"minimizeToTray_description": "minimize the application to the system tray",
"minimizeToTray": "minimize to tray",
"minimumScrobblePercentage_description": "the minimum percentage of the song that must be played before it is scrobbled",
diff --git a/src/renderer/features/settings/components/advanced/advanced-tab.tsx b/src/renderer/features/settings/components/advanced/advanced-tab.tsx
index ff1f0e8d4..4c2b23971 100644
--- a/src/renderer/features/settings/components/advanced/advanced-tab.tsx
+++ b/src/renderer/features/settings/components/advanced/advanced-tab.tsx
@@ -2,6 +2,7 @@ import { Fragment } from 'react/jsx-runtime';
import { AnalyticsSettings } from '/@/renderer/features/settings/components/advanced/analytics-settings';
import { ExportImportSettings } from '/@/renderer/features/settings/components/advanced/export-import-settings';
+import { LoggerSettings } from '/@/renderer/features/settings/components/advanced/logger-settings';
import { CacheSettings } from '/@/renderer/features/settings/components/window/cache-settngs';
import { UpdateSettings } from '/@/renderer/features/settings/components/window/update-settings';
import { Divider } from '/@/shared/components/divider/divider';
@@ -11,6 +12,7 @@ const sections = [
{ component: UpdateSettings, key: 'update' },
{ component: AnalyticsSettings, key: 'analytics' },
{ component: ExportImportSettings, key: 'export-import' },
+ { component: LoggerSettings, key: 'logger' },
{ component: CacheSettings, key: 'cache' },
];
diff --git a/src/renderer/features/settings/components/advanced/logger-settings.tsx b/src/renderer/features/settings/components/advanced/logger-settings.tsx
new file mode 100644
index 000000000..c1424bb8f
--- /dev/null
+++ b/src/renderer/features/settings/components/advanced/logger-settings.tsx
@@ -0,0 +1,87 @@
+import { useTranslation } from 'react-i18next';
+
+import {
+ SettingOption,
+ SettingsSection,
+} from '/@/renderer/features/settings/components/settings-section';
+import { logFn, LogLevel } from '/@/renderer/utils/logger';
+import { Select } from '/@/shared/components/select/select';
+
+const DEFAULT_LOG_LEVEL: LogLevel = process.env.NODE_ENV === 'production' ? 'info' : 'debug';
+
+export const LoggerSettings = () => {
+ const { t } = useTranslation();
+
+ const getCurrentLogLevel = (): LogLevel => {
+ const stored = localStorage.getItem('log_level');
+ if (stored && ['debug', 'error', 'info', 'warn'].includes(stored)) {
+ return stored as LogLevel;
+ }
+ return DEFAULT_LOG_LEVEL;
+ };
+
+ const handleLogLevelChange = (value: null | string) => {
+ if (!value) return;
+
+ const logLevel = value as LogLevel;
+ localStorage.setItem('log_level', logLevel);
+
+ // Update the logger dynamically
+ if (logFn.updateLogLevel) {
+ logFn.updateLogLevel(logLevel);
+ }
+ };
+
+ const loggerOptions: SettingOption[] = [
+ {
+ control: (
+
+ ),
+ description: t('setting.logLevel', {
+ context: 'description',
+ postProcess: 'sentenceCase',
+ }),
+ title: t('setting.logLevel', { postProcess: 'sentenceCase' }),
+ },
+ ];
+
+ return (
+
+ );
+};
diff --git a/src/renderer/utils/logger.ts b/src/renderer/utils/logger.ts
index 15835de62..6f0aa7091 100644
--- a/src/renderer/utils/logger.ts
+++ b/src/renderer/utils/logger.ts
@@ -27,6 +27,7 @@ interface Logger {
debug: LogFn;
error: LogFn;
info: LogFn;
+ updateLogLevel: (level: LogLevel) => void;
warn: LogFn;
}
@@ -73,14 +74,21 @@ setInterval(() => {
}, DEBOUNCE_INTERVAL);
class ConsoleLogger implements Logger {
- readonly debug: LogFn;
- readonly error: LogFn;
- readonly info: LogFn;
- readonly warn: LogFn;
+ debug: LogFn = NO_OP;
+ error: LogFn = NO_OP;
+ info: LogFn = NO_OP;
+ updateLogLevel: (level: LogLevel) => void;
+ warn: LogFn = NO_OP;
constructor() {
- const level = localStorage.getItem('log_level') || DEFAULT_LOG_LEVEL;
+ const level = (localStorage.getItem('log_level') || DEFAULT_LOG_LEVEL) as LogLevel;
+ this.initializeLoggers(level);
+ this.updateLogLevel = (newLevel: LogLevel) => {
+ this.initializeLoggers(newLevel);
+ };
+ }
+ private initializeLoggers(level: LogLevel) {
// Create timestamp wrapper function with colors and debouncing
const withTimestamp = (logLevel: string): LogFn => {
return (message?: any, options?: { category?: string; meta?: any }) => {