Skip to content

Commit 3362b25

Browse files
indietypeffect-bot
authored andcommitted
Add Effect.whenLogLevel (#4342)
1 parent ffa302c commit 3362b25

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

.changeset/dirty-ways-dress.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": minor
3+
---
4+
5+
Add `Effect.whenLogLevel`, which conditionally executes an effect if the specified log level is enabled

packages/effect/src/Effect.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import * as runtime_ from "./internal/runtime.js"
4040
import * as schedule_ from "./internal/schedule.js"
4141
import * as internalTracer from "./internal/tracer.js"
4242
import type * as Layer from "./Layer.js"
43-
import type { LogLevel } from "./LogLevel.js"
43+
import type * as LogLevel from "./LogLevel.js"
4444
import type * as ManagedRuntime from "./ManagedRuntime.js"
4545
import type * as Metric from "./Metric.js"
4646
import type * as MetricLabel from "./MetricLabel.js"
@@ -10685,7 +10685,7 @@ export const log: (...message: ReadonlyArray<any>) => Effect<void, never, never>
1068510685
* @category Logging
1068610686
*/
1068710687
export const logWithLevel = (
10688-
level: LogLevel,
10688+
level: LogLevel.LogLevel,
1068910689
...message: ReadonlyArray<any>
1069010690
): Effect<void> => effect.logWithLevel(level)(...message)
1069110691

@@ -10979,10 +10979,46 @@ export const logAnnotations: Effect<HashMap.HashMap<string, unknown>> = effect.l
1097910979
* @category Logging
1098010980
*/
1098110981
export const withUnhandledErrorLogLevel: {
10982-
(level: Option.Option<LogLevel>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>
10983-
<A, E, R>(self: Effect<A, E, R>, level: Option.Option<LogLevel>): Effect<A, E, R>
10982+
(level: Option.Option<LogLevel.LogLevel>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>
10983+
<A, E, R>(self: Effect<A, E, R>, level: Option.Option<LogLevel.LogLevel>): Effect<A, E, R>
1098410984
} = core.withUnhandledErrorLogLevel
1098510985

10986+
/**
10987+
* Conditionally executes an effect based on the specified log level and currently enabled log level.
10988+
*
10989+
* **Details**
10990+
*
10991+
* This function runs the provided effect only if the specified log level is
10992+
* enabled. If the log level is enabled, the effect is executed and its result
10993+
* is wrapped in `Some`. If the log level is not enabled, the effect is not
10994+
* executed and `None` is returned.
10995+
*
10996+
* This function is useful for conditionally executing logging-related effects
10997+
* or other operations that depend on the current log level configuration.
10998+
*
10999+
* @example
11000+
* ```ts
11001+
* import { Effect, Logger, LogLevel } from "effect"
11002+
*
11003+
* const program = Effect.gen(function* () {
11004+
* yield* Effect.whenLogLevel(Effect.logTrace("message1"), LogLevel.Trace); // returns `None`
11005+
* yield* Effect.whenLogLevel(Effect.logDebug("message2"), LogLevel.Debug); // returns `Some`
11006+
* }).pipe(Logger.withMinimumLogLevel(LogLevel.Debug));
11007+
*
11008+
* // Effect.runFork(program)
11009+
* // timestamp=... level=DEBUG fiber=#0 message=message2
11010+
* ```
11011+
*
11012+
* @see {@link FiberRef.minimumLogLevel} to retrieve the current minimum log level.
11013+
*
11014+
* @since 3.13.0
11015+
* @category Logging
11016+
*/
11017+
export const whenLogLevel: {
11018+
(level: LogLevel.LogLevel | LogLevel.Literal): <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>, E, R>
11019+
<A, E, R>(self: Effect<A, E, R>, level: LogLevel.LogLevel | LogLevel.Literal): Effect<Option.Option<A>, E, R>
11020+
} = fiberRuntime.whenLogLevel
11021+
1098611022
/**
1098711023
* Converts an effect's failure into a fiber termination, removing the error
1098811024
* from the effect's type.

packages/effect/src/internal/fiberRuntime.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,30 @@ export const annotateLogsScoped: {
16311631
)
16321632
}
16331633

1634+
/** @internal */
1635+
export const whenLogLevel = dual<
1636+
(
1637+
level: LogLevel.LogLevel | LogLevel.Literal
1638+
) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<Option.Option<A>, E, R>,
1639+
<A, E, R>(
1640+
effect: Effect.Effect<A, E, R>,
1641+
level: LogLevel.LogLevel | LogLevel.Literal
1642+
) => Effect.Effect<Option.Option<A>, E, R>
1643+
>(2, (effect, level) => {
1644+
const requiredLogLevel = typeof level === "string" ? LogLevel.fromLiteral(level) : level
1645+
1646+
return core.withFiberRuntime((fiberState) => {
1647+
const minimumLogLevel = fiberState.getFiberRef(currentMinimumLogLevel)
1648+
1649+
// Imitate the behaviour of `FiberRuntime.log`
1650+
if (LogLevel.greaterThan(minimumLogLevel, requiredLogLevel)) {
1651+
return core.succeed(Option.none())
1652+
}
1653+
1654+
return core.map(effect, Option.some)
1655+
})
1656+
})
1657+
16341658
// circular with Effect
16351659

16361660
/* @internal */

0 commit comments

Comments
 (0)