Effect 里怎么关掉局部追踪或调整日志级别?
我用一个计数的 tracer 验证过:在局部把 TracerEnabled 设为 false 之后,tracer 的 span 方法一次都没有被调用,业务代码一行没改。
用 Effect.provideService 覆盖 effect 的 References 模块里对应的内置 Reference 即可:References.TracerEnabled 管 span 是否注册,References.MinimumLogLevel 管日志级别阈值。
这些内置项在 v3 里是各个 FiberRef,v4 里它们都是 Context.Reference,也就是带默认值的服务键,覆盖方式和你自定义的完全一致,如果这个概念还不熟,可以先看 Effect v4 里 FiberRef 去哪了?。下面先列清单,再看日志和追踪各一个例子。
有哪些内置的 References?
常用的几个:
MinimumLogLevel:日志级别阈值,低于它的日志被丢弃,默认"Info"。CurrentLogAnnotations:附加到每条日志上的注解,默认空对象。CurrentLogLevel:Effect.log不指定级别时用的级别。TracerEnabled:是否注册 span,默认true。TracerSpanAnnotations、TracerSpanLinks:附加到之后创建的每个 span 上。Tracer:当前使用的 tracer 服务。MaxOpsBeforeYield、PreventSchedulerYield:调度器让出 CPU 的预算,属于底层调优,一般不碰。
怎么局部调整日志级别?
覆盖 MinimumLogLevel:
import { Effect, References } from "effect"
const work = Effect.gen(function*() {
yield* Effect.logDebug("debug")
yield* Effect.logInfo("info")
yield* Effect.logWarning("warn")
})
const program = Effect.gen(function*() {
console.log("默认值", yield* References.MinimumLogLevel, yield* References.TracerEnabled)
console.log("-- MinimumLogLevel = Debug")
yield* Effect.provideService(work, References.MinimumLogLevel, "Debug")
console.log("-- MinimumLogLevel = Warn")
yield* Effect.provideService(work, References.MinimumLogLevel, "Warn")
})
Effect.runPromise(program)输出(时间戳略):
默认值 Info true
-- MinimumLogLevel = Debug
DEBUG debug
INFO info
WARN warn
-- MinimumLogLevel = Warn
WARN warn默认阈值是 Info,所以不覆盖时 debug 那条不会出现;设成 Debug 三条都有,设成 Warn 只剩警告。覆盖只对被包住的那个 effect 生效。
怎么在局部关闭 span?
覆盖 TracerEnabled。我用一个计数的 tracer 验证:
import { Effect, References, Tracer } from "effect"
const program = Effect.gen(function*() {
const base = yield* References.Tracer
let created = 0
const counting = Tracer.make({
span(options) {
created++
return base.span.call(base, options)
}
})
const traced = Effect.withSpan(Effect.void, "work")
const run = (effect: Effect.Effect<void>) => Effect.provideService(effect, References.Tracer, counting)
yield* run(traced)
console.log("TracerEnabled=true 创建的 span 数", created)
yield* run(Effect.provideService(traced, References.TracerEnabled, false))
console.log("关闭后累计 span 数", created)
})
Effect.runPromise(program)输出两行都是 1:开启时创建了一个 span,在局部把 TracerEnabled 设为 false 之后,tracer 的 span 方法根本没有被调用。典型用途是高频的内部循环或健康检查端点,不想给它们产生 span 又不想改业务代码,在入口局部关掉就行。
日志注解和 span 命名还有什么要注意的?
直接覆盖 CurrentLogAnnotations 是整体替换而不是合并,细节见 覆盖 CurrentLogAnnotations 为什么会丢注解?。给函数加 span 的写法见 Effect 里怎么给函数加 span?,可观测性整体怎么搭,见 Effect 可观测性:Effect.fn 命名、Metric 基数与错误上报的边界。
版本是 effect@4.0.5。上面两个例子,以及各内置项的默认值(MinimumLogLevel为 Info、TracerEnabled为 true),都在本地跑过。清单里CurrentLogLevel、TracerSpanAnnotations、TracerSpanLinks、Tracer、MaxOpsBeforeYield、PreventSchedulerYield的作用来自对模块导出的描述,没有逐个单独运行验证。