日志说明
orion-error 的日志能力围绕 OperationContext 和 OperationScope 展开。
1. Feature
[dependencies]
orion-error = { version = "0.8.0", features = ["log"] }
# 或
orion-error = { version = "0.8.0", features = ["tracing"] }
默认 feature 已包含 log。
行为规则:
- 只启用
log:使用log宏输出 - 启用
tracing:优先走tracing - 同时启用:走
tracing
2. 基本用法
#![allow(unused)]
fn main() {
use orion_error::OperationContext;
let ctx = OperationContext::doing("order_processing")
.with_field("order_id", "123")
.with_field("amount", "100.0")
.with_meta("component.name", "order_service");
ctx.info("start");
ctx.debug("payload prepared");
ctx.warn("slow upstream");
ctx.error("final failure");
ctx.trace("verbose trace");
}
也可以使用别名:
log_infolog_debuglog_warnlog_errorlog_trace
3. 自动结果日志
#![allow(unused)]
fn main() {
use orion_error::OperationContext;
let mut ctx = OperationContext::doing("sync_user")
.with_auto_log()
.with_field("user_id", "42");
do_sync()?;
ctx.mark_suc();
}
默认结果是失败。
如果启用了 with_auto_log(),但离开作用域前没有调用:
mark_suc()mark_cancel()
那么 Drop 时会输出失败日志。
4. OperationScope
OperationScope 是面向一个局部作用域的 guard。
#![allow(unused)]
fn main() {
use orion_error::OperationContext;
let mut ctx = OperationContext::doing("sync_user").with_auto_log();
{
let mut scope = ctx.scope();
scope.with_field("user_id", "42");
validate()?;
scope.mark_success();
}
}
方法:
scope():默认失败,只有显式mark_success()才会成功scoped_success():创建后默认成功,除非后续显式mark_failure()或cancel()mark_success():标记成功mark_failure():恢复为失败cancel():标记取消
5. scoped_success() 的使用边界
scoped_success() 适合这种场景:
- 作用域里的逻辑已经自行处理完失败分支
- 失败时会明确调用
mark_failure() - 或者这段逻辑本身不会通过
?提前返回
例如:
#![allow(unused)]
fn main() {
let mut ctx = OperationContext::doing("process_order").with_auto_log();
{
let mut scope = ctx.scoped_success();
let ok = validate_order();
if !ok {
scope.mark_failure();
}
}
}
不推荐这样写:
let mut scope = ctx.scoped_success();
validate()?;
因为当前实现里 scoped_success() 一创建就默认成功,如果 ? 提前返回,Drop 仍会把该作用域标记为成功。
对可能早退的 fallible 流程,优先使用:
#![allow(unused)]
fn main() {
let mut scope = ctx.scope();
validate()?;
scope.mark_success();
}
6. op_context! 宏
#![allow(unused)]
fn main() {
use orion_error::op_context;
let ctx = op_context!("load_config").with_auto_log().with_field("path", "config.toml");
}
这个宏会在调用点展开 module_path!(),让自动结果日志带上更准确的模块路径。
7. 推荐实践
- 用
doing(...)命名操作 - 用
with_field(...)/with_meta(...)做链式构建 record_field(...)/record_meta(...)只在已有可变引用时使用- 用
with_auto_log()只包裹真正需要结果日志的作用域 - 对可能
?提前返回的逻辑,优先scope() + mark_success() - 只有在失败路径已被显式处理时,再使用
scoped_success()