AmilyBus注入初始化

This commit is contained in:
2026-01-16 00:25:41 +08:00
parent e370ce7d3f
commit 3d051d69a1
3 changed files with 103 additions and 184 deletions

View File

@@ -1,9 +1,12 @@
import { Logger } from '/core/logger.js';
import { FilePipe } from '/core/file-pipe.js';
class Amily2Bus {
constructor() {
/** @type {Logger|null} */
this.Logger = null;
this.Logger = new Logger();
/** @type {FilePipe|null} */
this.FilePipe = null;
this.FilePipe = new FilePipe();
// 已注册插件列表,防止重复注册
this.registry = new Set();

View File

@@ -1,5 +1,6 @@
/**
* 日志总类,用于记录日志信息
* 支持基于位运算的自定义日志级别控制
*/
class Logger {
@@ -8,52 +9,121 @@ class Logger {
static LOG_HEADER_WARN = '[WARN]';
static LOG_HEADER_ERROR = '[ERROR]';
static LEVEL_WEIGHTS = {
'debug': 0,
'info': 1,
'warn': 2,
'error': 3
static LOG_LEVEL_CODE = {
none: 0,
debug: 1 << 0, // 1
info: 1 << 1, // 2
warn: 1 << 2, // 4
error: 1 << 3, // 8
all: (1 << 4) - 1 // 15
};
constructor() {
// 全局默认级别
this.globalLevel = 'info';
// 全局默认级别 (默认开启 info, warn, error)
this.globalLevel = Logger.LOG_LEVEL_CODE.info | Logger.LOG_LEVEL_CODE.warn | Logger.LOG_LEVEL_CODE.error;
// 针对特定插件或模块的配置
// 结构示例:
// {
// "PluginA": "debug", // PluginA 下所有模块默认为 debug
// "PluginB::ModuleX": "error" // 仅 PluginB 下的 ModuleX error
// "PluginA": 3, // PluginA 下所有模块掩码为 3 (debug | info)
// "PluginB::ModuleX": 8 // 仅 PluginB 下的 ModuleX 掩码为 8 (error)
// }
this.levelConfig = {};
}
/**
* 设置日志级别
* @param {string} target 目标范围,可以是 'Global'、'PluginName' 或 'PluginName::ModuleName'
* @param {string} level 'debug' | 'info' | 'warn' | 'error'
* 将输入转换为对应的日志级别掩码
* @param {number|string|string[]} levelInput
* @returns {number} 掩码
*/
setLevel(target, level) {
if (!Logger.LEVEL_WEIGHTS.hasOwnProperty(level)) {
console.warn(`[Logger] Invalid log level: ${level}`);
return;
_parseLevelInput(levelInput) {
if (typeof levelInput === 'number') {
return levelInput;
}
if (typeof levelInput === 'string') {
if (Logger.LOG_LEVEL_CODE.hasOwnProperty(levelInput)) {
return Logger.LOG_LEVEL_CODE[levelInput];
}
// 支持 "debug|info" 这种写法
if (levelInput.includes('|')) {
return levelInput.split('|').reduce((mask, l) => mask | (Logger.LOG_LEVEL_CODE[l.trim()] || 0), 0);
}
console.warn(`[Logger] Unknown log level string: ${levelInput}`);
return 0;
}
if (Array.isArray(levelInput)) {
return levelInput.reduce((mask, l) => mask | (Logger.LOG_LEVEL_CODE[l] || 0), 0);
}
return 0;
}
/**
* 设置日志级别(覆盖模式)
* @param {string} target 目标范围,可以是 'Global'、'PluginName' 或 'PluginName::ModuleName'
* @param {number|string|string[]} level 输入的级别配置
*/
setLevel(target, level) {
const mask = this._parseLevelInput(level);
if (target === 'Global') {
this.globalLevel = level;
console.log(`[Logger] Global log level set to: ${level}`);
this.globalLevel = mask;
console.log(`[Logger] Global log level mask set to: ${mask.toString(2)}`);
} else {
this.levelConfig[target] = level;
console.log(`[Logger] Log level for '${target}' set to: ${level}`);
this.levelConfig[target] = mask;
console.log(`[Logger] Log level mask for '${target}' set to: ${mask.toString(2)}`);
}
}
/**
* 获取指定上下文的生效日志级别(级联查找
* 添加日志级别(增量模式
* @param {string} target
* @param {number|string|string[]} level
*/
addLevel(target, level) {
const maskToAdd = this._parseLevelInput(level);
let currentMask;
if (target === 'Global') {
currentMask = this.globalLevel;
this.globalLevel = currentMask | maskToAdd;
console.log(`[Logger] Added level to Global. New mask: ${this.globalLevel.toString(2)}`);
} else {
currentMask = this.levelConfig[target] !== undefined ? this.levelConfig[target] : this.globalLevel;
this.levelConfig[target] = currentMask | maskToAdd;
console.log(`[Logger] Added level to '${target}'. New mask: ${this.levelConfig[target].toString(2)}`);
}
}
/**
* 移除日志级别(减量模式)
* @param {string} target
* @param {number|string|string[]} level
*/
removeLevel(target, level) {
const maskToRemove = this._parseLevelInput(level);
let currentMask;
if (target === 'Global') {
currentMask = this.globalLevel;
// 使用 & ~mask 实现移除
this.globalLevel = currentMask & ~maskToRemove;
console.log(`[Logger] Removed level from Global. New mask: ${this.globalLevel.toString(2)}`);
} else {
currentMask = this.levelConfig[target] !== undefined ? this.levelConfig[target] : this.globalLevel;
this.levelConfig[target] = currentMask & ~maskToRemove;
console.log(`[Logger] Removed level from '${target}'. New mask: ${this.levelConfig[target].toString(2)}`);
}
}
/**
* 获取指定上下文的生效日志级别掩码(级联查找)
* @param {string} plugin
* @param {string} origin (Module)
*/
_getEffectiveLevel(plugin, origin) {
_getEffectiveLevelMask(plugin, origin) {
// 1. 检查精确匹配 "Plugin::Module"
const specificKey = `${plugin}::${origin}`;
if (this.levelConfig.hasOwnProperty(specificKey)) {
@@ -70,14 +140,14 @@ class Logger {
}
log(plugin, origin, type, message, inFile = false) {
// 获取当前上下文生效的日志级别权重
const effectiveLevelName = this._getEffectiveLevel(plugin, origin);
const currentWeight = Logger.LEVEL_WEIGHTS[effectiveLevelName];
// 获取当前上下文生效的日志级别掩码
const effectiveMask = this._getEffectiveLevelMask(plugin, origin);
const weight = Logger.LEVEL_WEIGHTS[type] !== undefined ? Logger.LEVEL_WEIGHTS[type] : 1;
// 获取当前日志类型的位码
const typeCode = Logger.LOG_LEVEL_CODE[type];
// 级别筛选
if (weight < currentWeight) {
// 级别筛选位与运算结果为0则表示该级别未开启
if (typeCode === undefined || (effectiveMask & typeCode) === 0) {
return;
}
@@ -107,7 +177,6 @@ class Logger {
// 2. File Output (via FilePipe)
if (inFile) {
// Logger 自身也需要作为系统组件注册,获取写入权限
// 注意:为了性能,建议在 constructor 里注册一次保存起来,这里为了逻辑展示暂时简化
if (!this.sysBus) {
if (window.Amily2Bus && window.Amily2Bus.register) {
this.sysBus = window.Amily2Bus.register('SystemLogger');
@@ -116,7 +185,6 @@ class Logger {
if (this.sysBus && this.sysBus.file) {
// 使用注册后的安全接口写入,无需再手动传 'SystemLogger'
// TODO: 这里的路径 'runtime.log' 后续可以做成配置项
this.sysBus.file.write('runtime.log', fullMessage + '\n');
} else {
// Fallback: 如果总线未就绪,仅在控制台警告一次,避免死循环