Skip to content

Commit 6bf8b3a

Browse files
indietypeffect-bot
authored andcommitted
Add Effect.whenLogLevel (#4342)
1 parent 16e2271 commit 6bf8b3a

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"
@@ -10680,7 +10680,7 @@ export const log: (...message: ReadonlyArray<any>) => Effect<void, never, never>
1068010680
* @category Logging
1068110681
*/
1068210682
export const logWithLevel = (
10683-
level: LogLevel,
10683+
level: LogLevel.LogLevel,
1068410684
...message: ReadonlyArray<any>
1068510685
): Effect<void> => effect.logWithLevel(level)(...message)
1068610686

@@ -10974,10 +10974,46 @@ export const logAnnotations: Effect<HashMap.HashMap<string, unknown>> = effect.l
1097410974
* @category Logging
1097510975
*/
1097610976
export const withUnhandledErrorLogLevel: {
10977-
(level: Option.Option<LogLevel>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>
10978-
<A, E, R>(self: Effect<A, E, R>, level: Option.Option<LogLevel>): Effect<A, E, R>
10977+
(level: Option.Option<LogLevel.LogLevel>): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>
10978+
<A, E, R>(self: Effect<A, E, R>, level: Option.Option<LogLevel.LogLevel>): Effect<A, E, R>
1097910979
} = core.withUnhandledErrorLogLevel
1098010980

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