docs: 添加 Rustdoc 注释

This commit is contained in:
爱特每羊队
2026-08-05 21:46:47 +08:00
parent bbdfca1a1c
commit f461235f04
158 changed files with 1440 additions and 15 deletions
+13
View File
@@ -1,3 +1,9 @@
//! 按子系统过滤日志事件的 `tracing` 层过滤器。
//!
//! [`SubsystemFilter`] 为每个子系统保存一个独立的原子级别槽位,并实现
//! [`Filter<S>`](tracing_subscriber::layer::Filter)。`tracing` 事件的 target
//! (形如 `oxide::vm::...`)先被映射到子系统,再按该子系统当前级别决定是否放行。
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc;
@@ -7,22 +13,29 @@ use tracing_subscriber::layer::Filter;
use crate::level::Level;
use crate::subsystem::{SubsystemId, SUBSYSTEM_COUNT};
/// 按子系统维护日志级别的过滤层。
///
/// `Clone` 为浅拷贝(内部 `Arc`),多个 subscriber 层可共享同一份级别状态,
/// 因此 [`set_level`](SubsystemFilter::set_level) 对已初始化的 subscriber 即时生效。
#[derive(Clone)]
pub struct SubsystemFilter {
levels: Arc<[AtomicU8; SUBSYSTEM_COUNT]>,
}
impl SubsystemFilter {
/// 创建全部子系统级别为 `Off` 的过滤器。
pub fn new() -> Self {
Self {
levels: Arc::new([AtomicU8::new(0), AtomicU8::new(0), AtomicU8::new(0), AtomicU8::new(0)]),
}
}
/// 设置子系统的日志级别(原子写,`Relaxed` 序足够)。
pub fn set_level(&self, id: SubsystemId, level: Level) {
self.levels[id as usize].store(level as u8, Ordering::Relaxed);
}
/// 读取子系统的当前日志级别。
pub fn get_level(&self, id: SubsystemId) -> Level {
let raw = self.levels[id as usize].load(Ordering::Relaxed);
match raw {
+26
View File
@@ -1,3 +1,9 @@
//! 日志初始化。
//!
//! `init` 一次性初始化全局 `tracing` subscriber,输出可定向到 stderr / stdout /
//! 按日滚动的文件;[`set_level`] 与 `get_subsystem` 提供运行期级别控制。
//! 重复调用 `init` 幂等(内部 `Once`),后续调用不生效。
use std::io;
use std::path::PathBuf;
use std::sync::{Once, OnceLock};
@@ -11,13 +17,21 @@ use crate::filter::SubsystemFilter;
use crate::level::Level;
use crate::subsystem::{self, SubsystemId, SUBSYSTEM_COUNT};
/// 日志输出目标。
#[derive(Debug, Clone)]
pub enum Output {
/// 写到标准错误(默认)。
Stderr,
/// 写到标准输出。
Stdout,
/// 按日滚动写入 `dir` 目录下的 `oxide.log`。
File(PathBuf),
}
/// 日志初始化配置。
///
/// `levels` 按 [`SubsystemId`] 的下标顺序给出各子系统初始级别;
/// 默认值为输出到 stderr 且全部子系统关闭。
pub struct LogConfig {
pub output: Output,
pub levels: [Level; SUBSYSTEM_COUNT],
@@ -36,14 +50,26 @@ static INIT: Once = Once::new();
static SUBSYSTEM: OnceLock<SubsystemFilter> = OnceLock::new();
static FILE_GUARD: OnceLock<tracing_appender::non_blocking::WorkerGuard> = OnceLock::new();
/// 获取全局 [`SubsystemFilter`],供日志宏在检查级别时使用。
///
/// # Panics
///
/// 若在调用 [`init`] 之前调用会 panic——日志宏必须发生在初始化之后。
pub fn get_subsystem() -> &'static SubsystemFilter {
SUBSYSTEM.get().expect("oxide_log::init() must be called before logging")
}
/// 运行期调整指定子系统的日志级别。
///
/// 直接写全局过滤器,无需重新初始化 subscriber。
pub fn set_level(id: SubsystemId, level: Level) {
get_subsystem().set_level(id, level);
}
/// 初始化全局日志 subscriber。
///
/// 按 [`LogConfig::levels`] 设置各子系统初始级别,再读取 `OXIDE_LOG` 环境变量
/// 覆盖,最后按 `output` 组装 subscriber。内部以 `Once` 保证只执行一次。
pub fn init(config: &LogConfig) {
INIT.call_once(|| {
let filter = SubsystemFilter::new();
+15
View File
@@ -1,3 +1,13 @@
//! 日志级别定义。
//!
//! [`Level`] 是引擎内部使用的日志级别枚举,与 `tracing` 的级别一一对应,
//! 通过 [`Level::as_tracing_level`] 转换。值以 `u8` 存储(`repr(u8)`),
//! 可直接写入 `SubsystemFilter` 的原子级别槽位。
/// 日志级别。
///
/// 由低到高:`Off` < `Error` < `Warn` < `Info` < `Debug` < `Trace`。
/// `Off` 表示完全关闭,仅由 `SubsystemFilter` 判读,不映射到 `tracing` 级别。
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Level {
@@ -10,6 +20,11 @@ pub enum Level {
}
impl Level {
/// 转换为 `tracing` 的 [`tracing::Level`]。
///
/// `Off` 与 `Error` 都映射到 `ERROR`——关闭语义由
/// [`SubsystemFilter`](crate::SubsystemFilter) 的 `Off` 分支单独处理,
/// 这里仅保证其余级别 1:1 对齐。
pub const fn as_tracing_level(self) -> tracing::Level {
match self {
Level::Off | Level::Error => tracing::Level::ERROR,
+18
View File
@@ -1,12 +1,30 @@
//! OxideJS 统一日志基础设施。
//!
//! 基于 `tracing` / `tracing-subscriber` 实现,日志按子系统(VM / IC / Kernel /
//! Builtins)独立配置级别。入口为 `init`:传入 [`LogConfig`] 后一次性初始化
//! 全局 subscriber;运行期可用 [`set_level`] 动态调整各子系统级别。
//!
//! 环境变量 `OXIDE_LOG` 可在进程启动时覆盖配置,格式与 `RUST_LOG` 类似,
//! 见 `subsystem::apply_env_levels`。
/// 按子系统过滤 `tracing` 事件的订阅者过滤器。
pub mod filter;
/// 日志初始化与运行期级别控制入口。
pub mod init;
/// 日志级别定义。
pub mod level;
/// 内部日志转发宏。
pub mod macros;
/// 子系统标识与 `OXIDE_LOG` 环境变量解析。
pub mod subsystem;
/// 重导出 [`filter::SubsystemFilter`]。
pub use filter::SubsystemFilter;
/// 重导出 `init` 模块的初始化入口与配置类型。
pub use init::{init, set_level, LogConfig, Output};
/// 重导出 [`level::Level`]。
pub use level::Level;
/// 重导出 [`subsystem`] 模块的子系统标识。
pub use subsystem::{SubsystemId, SUBSYSTEM_COUNT};
#[doc(hidden)]
+5
View File
@@ -1,3 +1,8 @@
//! 内部日志转发宏。
//!
//! [`__log_event`] 是 `$crate::tracing::event!` 的薄封装,供外部 crate 统一
//! 转发日志事件,避免各处直接依赖 `tracing` 的路径。
#[macro_export]
macro_rules! __log_event {
($target:expr, $level:expr, $($arg:tt)*) => {
+24
View File
@@ -1,16 +1,35 @@
//! 子系统标识与日志级别解析。
//!
//! 引擎日志按子系统划分(VM / IC / Kernel / Builtins),各子系统可独立设置
//! 级别。`parse_level` 把字符串解析为 [`Level`];`apply_env_levels` 读取
//! `OXIDE_LOG` 环境变量并按 `oxide=<level>` 形式的指令批量覆盖级别。
use crate::level::Level;
/// 引擎子系统标识。
///
/// `repr(usize)` 的值同时用作 [`SubsystemFilter`](crate::SubsystemFilter)
/// 内部原子级别数组的下标,故枚举顺序不可随意调整。
#[repr(usize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SubsystemId {
/// 虚拟机执行循环(字节码解释器)。
Vm = 0,
/// 内联缓存(inline cache)相关路径。
Ic = 1,
/// 内核:对象模型、GC、运行时服务。
Kernel = 2,
/// 内置对象与内置函数实现。
Builtins = 3,
}
/// 子系统总数,即 [`SubsystemId`] 变体个数,也是 `SubsystemFilter` 级别数组长度。
pub const SUBSYSTEM_COUNT: usize = 4;
/// 把级别字符串解析为 [`Level`],大小写不敏感。
///
/// 接受 `off` / `error` / `warn` / `info` / `debug` / `trace`,未知字符串返回
/// `None`。
pub fn parse_level(s: &str) -> Option<Level> {
if s.eq_ignore_ascii_case("off") {
Some(Level::Off)
@@ -29,6 +48,11 @@ pub fn parse_level(s: &str) -> Option<Level> {
}
}
/// 从环境变量 `OXIDE_LOG` 应用启动时级别覆盖。
///
/// 指令格式为逗号分隔的 `target=level` 列表,如 `oxide::vm=debug,oxide::ic=info`;
/// `oxide=<level>` 为所有子系统的快捷写法。无效指令被静默跳过,
/// 若环境变量缺失则直接返回。
pub fn apply_env_levels() {
let Ok(spec) = std::env::var("OXIDE_LOG") else {
return;