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