feat: support dynamically set log level
This commit is contained in:
@@ -32,7 +32,7 @@ import { trySyncAllSubRules } from "./libs/subRules";
|
||||
import { saveRule } from "./libs/rules";
|
||||
import { getCurTabId } from "./libs/msg";
|
||||
import { injectInlineJs, injectInternalCss } from "./libs/injector";
|
||||
import { kissLog } from "./libs/log";
|
||||
import { kissLog, logger } from "./libs/log";
|
||||
import { chromeDetect, chromeTranslate } from "./libs/builtinAI";
|
||||
|
||||
globalThis.ContextType = "BACKGROUND";
|
||||
@@ -210,11 +210,17 @@ browser.runtime.onInstalled.addListener(() => {
|
||||
* 浏览器启动
|
||||
*/
|
||||
browser.runtime.onStartup.addListener(async () => {
|
||||
// 同步数据
|
||||
await trySyncSettingAndRules();
|
||||
const {
|
||||
clearCache,
|
||||
contextMenuType,
|
||||
subrulesList,
|
||||
csplist,
|
||||
orilist,
|
||||
logLevel,
|
||||
} = await getSettingWithDefault();
|
||||
|
||||
const { clearCache, contextMenuType, subrulesList, csplist, orilist } =
|
||||
await getSettingWithDefault();
|
||||
// 设置日志
|
||||
logger.setLevel(logLevel);
|
||||
|
||||
// 清除缓存
|
||||
if (clearCache) {
|
||||
@@ -233,6 +239,9 @@ browser.runtime.onStartup.addListener(async () => {
|
||||
// 禁用CSP
|
||||
updateCspRules({ csplist, orilist });
|
||||
|
||||
// 同步数据
|
||||
trySyncSettingAndRules();
|
||||
|
||||
// 同步订阅规则
|
||||
trySyncAllSubRules({ subrulesList });
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ import { matchRule } from "./libs/rules";
|
||||
import { trySyncAllSubRules } from "./libs/subRules";
|
||||
import { isInBlacklist } from "./libs/blacklist";
|
||||
import { runSubtitle } from "./subtitle/subtitle";
|
||||
import { logger } from "./libs/log";
|
||||
|
||||
/**
|
||||
* 油猴脚本设置页面
|
||||
@@ -180,6 +181,12 @@ function touchOperation(translator) {
|
||||
*/
|
||||
export async function run(isUserscript = false) {
|
||||
try {
|
||||
// 读取设置信息
|
||||
const setting = await getSettingWithDefault();
|
||||
|
||||
// 日志
|
||||
logger.setLevel(setting.logLevel);
|
||||
|
||||
const href = document.location.href;
|
||||
|
||||
// 设置页面
|
||||
@@ -192,9 +199,6 @@ export async function run(isUserscript = false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 读取设置信息
|
||||
const setting = await getSettingWithDefault();
|
||||
|
||||
// 黑名单
|
||||
if (isInBlacklist(href, setting)) {
|
||||
return;
|
||||
|
||||
@@ -1628,6 +1628,11 @@ export const I18N = {
|
||||
en: `The subtitle data is ready, please click the KT button to load it`,
|
||||
zh_TW: `字幕資料已準備就緒,請點擊KT按鈕加載`,
|
||||
},
|
||||
log_level: {
|
||||
zh: `日志级别`,
|
||||
en: `Log Level`,
|
||||
zh_TW: `日誌等級`,
|
||||
},
|
||||
};
|
||||
|
||||
export const i18n = (lang) => (key) => I18N[key]?.[lang] || "";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { LogLevel } from "../libs/log";
|
||||
import {
|
||||
OPT_DICT_BING,
|
||||
OPT_SUG_YOUDAO,
|
||||
@@ -181,4 +182,5 @@ export const DEFAULT_SETTING = {
|
||||
preInit: true, // 是否预加载脚本
|
||||
transAllnow: false, // 是否立即全部翻译
|
||||
subtitleSetting: DEFAULT_SUBTITLE_SETTING, // 字幕设置
|
||||
logLevel: LogLevel.INFO.value, // 日志级别
|
||||
};
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import { createContext, useCallback, useContext, useMemo } from "react";
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useMemo,
|
||||
useEffect,
|
||||
} from "react";
|
||||
import Alert from "@mui/material/Alert";
|
||||
import { STOKEY_SETTING, DEFAULT_SETTING, KV_SETTING_KEY } from "../config";
|
||||
import { useStorage } from "./Storage";
|
||||
import { debounceSyncMeta } from "../libs/storage";
|
||||
import Loading from "./Loading";
|
||||
import { logger } from "../libs/log";
|
||||
|
||||
const SettingContext = createContext({
|
||||
setting: DEFAULT_SETTING,
|
||||
@@ -19,6 +26,16 @@ export function SettingProvider({ children }) {
|
||||
reload,
|
||||
} = useStorage(STOKEY_SETTING, DEFAULT_SETTING, KV_SETTING_KEY);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
logger.setLevel(setting?.logLevel);
|
||||
} catch (error) {
|
||||
logger.error("Failed to fetch log level, using default.", error);
|
||||
}
|
||||
})();
|
||||
}, [setting]);
|
||||
|
||||
const updateSetting = useCallback(
|
||||
(objOrFn) => {
|
||||
update(objOrFn);
|
||||
|
||||
@@ -7,6 +7,16 @@ export const LogLevel = {
|
||||
SILENT: { value: 4, name: "SILENT" }, // 特殊级别,用于关闭所有日志
|
||||
};
|
||||
|
||||
function findLogLevelByValue(value) {
|
||||
return Object.values(LogLevel).find((level) => level.value === value);
|
||||
}
|
||||
|
||||
function findLogLevelByName(name) {
|
||||
if (typeof name !== "string" || name.length === 0) return undefined;
|
||||
const upperCaseName = name.toUpperCase();
|
||||
return Object.values(LogLevel).find((level) => level.name === upperCaseName);
|
||||
}
|
||||
|
||||
class Logger {
|
||||
/**
|
||||
* @param {object} [options={}] 配置选项
|
||||
@@ -25,10 +35,37 @@ class Logger {
|
||||
* @param {LogLevel} level - 新的日志级别
|
||||
*/
|
||||
setLevel(level) {
|
||||
if (level && typeof level.value === "number") {
|
||||
this.config.level = level;
|
||||
console.log(`[${this.config.prefix}] Log level set to ${level.name}`);
|
||||
let newLevelObject;
|
||||
|
||||
if (typeof level === "string") {
|
||||
newLevelObject = findLogLevelByName(level);
|
||||
if (!newLevelObject) {
|
||||
this.warn(
|
||||
`Invalid log level name provided: "${level}". Keeping current level.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
} else if (typeof level === "number") {
|
||||
newLevelObject = findLogLevelByValue(level);
|
||||
if (!newLevelObject) {
|
||||
this.warn(
|
||||
`Invalid log level value provided: ${level}. Keeping current level.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
} else if (level && typeof level.value === "number") {
|
||||
newLevelObject = level;
|
||||
} else {
|
||||
this.warn(
|
||||
"Invalid argument passed to setLevel. Must be a LogLevel object, number, or string."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.config.level = newLevelObject;
|
||||
console.log(
|
||||
`[${this.config.prefix}] Log level dynamically set to ${this.config.level.name}`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,9 +155,7 @@ class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
const isDevelopment =
|
||||
typeof process === "undefined" || process.env.NODE_ENV !== "development";
|
||||
const defaultLevel = isDevelopment ? LogLevel.DEBUG : LogLevel.INFO;
|
||||
|
||||
export const logger = new Logger({ level: defaultLevel });
|
||||
export const logger = new Logger();
|
||||
export const kissLog = logger.info.bind(logger);
|
||||
|
||||
// todo:debug日志埋点
|
||||
|
||||
@@ -231,6 +231,13 @@ class YouTubeCaptionProvider {
|
||||
try {
|
||||
const events = chunkEvents.filter((item) => item.text);
|
||||
const chunkSign = `${events[0].start} --> ${events[events.length - 1].end}`;
|
||||
logger.debug("Youtube Provider: aiSegment events", {
|
||||
videoId,
|
||||
chunkSign,
|
||||
fromLang,
|
||||
toLang,
|
||||
events,
|
||||
});
|
||||
const subtitles = await apiSubtitle({
|
||||
videoId,
|
||||
chunkSign,
|
||||
@@ -239,6 +246,7 @@ class YouTubeCaptionProvider {
|
||||
events,
|
||||
apiSetting: segApiSetting,
|
||||
});
|
||||
logger.debug("Youtube Provider: aiSegment subtitles", subtitles);
|
||||
if (Array.isArray(subtitles)) {
|
||||
return subtitles;
|
||||
}
|
||||
@@ -300,6 +308,9 @@ class YouTubeCaptionProvider {
|
||||
OPT_LANGS_TO_CODE[OPT_TRANS_MICROSOFT].get(lang.slice(0, 2)) ||
|
||||
"auto";
|
||||
|
||||
logger.debug(
|
||||
`Youtube Provider: fromLang: ${fromLang}, toLang: ${toLang}`
|
||||
);
|
||||
if (this.#isSameLang(fromLang, toLang)) {
|
||||
logger.info("Youtube Provider: skip same lang", fromLang, toLang);
|
||||
return;
|
||||
|
||||
@@ -29,7 +29,7 @@ import { useShortcut } from "../../hooks/Shortcut";
|
||||
import ShortcutInput from "./ShortcutInput";
|
||||
import { useFab } from "../../hooks/Fab";
|
||||
import { sendBgMsg } from "../../libs/msg";
|
||||
import { kissLog } from "../../libs/log";
|
||||
import { kissLog, LogLevel } from "../../libs/log";
|
||||
import UploadButton from "./UploadButton";
|
||||
import DownloadButton from "./DownloadButton";
|
||||
import { getSettingOld } from "../../libs/storage";
|
||||
@@ -99,6 +99,7 @@ export default function Settings() {
|
||||
orilist = DEFAULT_ORILIST.join(",\n"),
|
||||
transInterval = 100,
|
||||
langDetector = "-",
|
||||
logLevel = 1,
|
||||
preInit = true,
|
||||
skipLangs = [],
|
||||
// detectRemote = true,
|
||||
@@ -337,6 +338,23 @@ export default function Settings() {
|
||||
))}
|
||||
</TextField>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={12} md={6} lg={3}>
|
||||
<TextField
|
||||
select
|
||||
fullWidth
|
||||
size="small"
|
||||
name="logLevel"
|
||||
value={logLevel}
|
||||
label={i18n("log_level")}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{Object.values(LogLevel).map(({ value, name }) => (
|
||||
<MenuItem value={value} key={value}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user