Skip to content
Effect Days 2026 Get your ticket

Logger

44 exports Added in v1.0.0 Source

Console

Signature

declare const withConsoleError: <M, O>(self: Logger<M, O>) => Logger<M, void>

Signature

declare const withConsoleLog: <M, O>(self: Logger<M, O>) => Logger<M, void>

Takes a Logger<M, O> and returns a logger that calls the respective Console method based on the log level.

Signature

declare const withLeveledConsole: <M, O>(self: Logger<M, O>) => Logger<M, void>

Example

import { Logger, Effect } from "effect"
const loggerLayer = Logger.replace(
Logger.defaultLogger,
Logger.withLeveledConsole(Logger.stringLogger),
)
Effect.gen(function* () {
yield* Effect.logError("an error")
yield* Effect.logInfo("an info")
}).pipe(Effect.provide(loggerLayer))

Constructors

Signature

declare const defaultLogger: Logger<unknown, void>

json

Added in v2.0.0 Source

The json logger formats log entries as JSON objects, making them easy to integrate with logging systems that consume JSON data.

Signature

declare const json: Layer.Layer<never>

Example

import { Effect, Logger } from "effect"
const program = Effect.log("message1", "message2").pipe(
Effect.annotateLogs({ key1: "value1", key2: "value2" }),
Effect.withLogSpan("myspan")
)
Effect.runFork(program.pipe(Effect.provide(Logger.json)))
// {"message":["message1","message2"],"logLevel":"INFO","timestamp":"...","annotations":{"key2":"value2","key1":"value1"},"spans":{"myspan":0},"fiberId":"#0"}

jsonLogger

Added in v2.0.0 Source

The jsonLogger logger formats log entries as JSON objects, making them easy to integrate with logging systems that consume JSON data.

Signature

declare const jsonLogger: Logger<unknown, string>

Example

import { Effect, Logger } from "effect"
const program = Effect.log("message1", "message2").pipe(
Effect.annotateLogs({ key1: "value1", key2: "value2" }),
Effect.withLogSpan("myspan")
)
Effect.runFork(program.pipe(Effect.provide(Logger.json)))
// {"message":["message1","message2"],"logLevel":"INFO","timestamp":"...","annotations":{"key2":"value2","key1":"value1"},"spans":{"myspan":0},"fiberId":"#0"}

logFmt

Added in v2.0.0 Source

This logger outputs logs in a human-readable format that is easy to read during development or in a production console.

Signature

declare const logFmt: Layer.Layer<never>

Example

import { Effect, Logger } from "effect"
const program = Effect.log("message1", "message2").pipe(
Effect.annotateLogs({ key1: "value1", key2: "value2" }),
Effect.withLogSpan("myspan")
)
Effect.runFork(program.pipe(Effect.provide(Logger.logFmt)))
// timestamp=... level=INFO fiber=#0 message=message1 message=message2 myspan=0ms key2=value2 key1=value1

logfmtLogger

Added in v2.0.0 Source

This logger outputs logs in a human-readable format that is easy to read during development or in a production console.

Signature

declare const logfmtLogger: Logger<unknown, string>

Example

import { Effect, Logger } from "effect"
const program = Effect.log("message1", "message2").pipe(
Effect.annotateLogs({ key1: "value1", key2: "value2" }),
Effect.withLogSpan("myspan")
)
Effect.runFork(program.pipe(Effect.provide(Logger.logFmt)))
// timestamp=... level=INFO fiber=#0 message=message1 message=message2 myspan=0ms key2=value2 key1=value1

make

Added in v2.0.0 Source

Creates a custom logger that formats log messages according to the provided function.

Signature

declare const make: <Message, Output>(log: (options: Logger.Options<Message>) => Output) => Logger<Message, Output>

Example

import { Effect, Logger, LogLevel } from "effect"
const logger = Logger.make(({ logLevel, message }) => {
globalThis.console.log(`[${logLevel.label}] ${message}`)
})
const task1 = Effect.logDebug("task1 done")
const task2 = Effect.logDebug("task2 done")
const program = Effect.gen(function*() {
yield* Effect.log("start")
yield* task1
yield* task2
yield* Effect.log("done")
}).pipe(
Logger.withMinimumLogLevel(LogLevel.Debug),
Effect.provide(Logger.replace(Logger.defaultLogger, logger))
)
Effect.runFork(program)
// [INFO] start
// [DEBUG] task1 done
// [DEBUG] task2 done
// [INFO] done

none

Added in v2.0.0 Source

A logger that does nothing in response to logging events.

Signature

declare const none: Logger<unknown, void>

pretty

Added in v3.5.0 Source

The pretty logger utilizes the capabilities of the console API to generate visually engaging and color-enhanced log outputs. This feature is particularly useful for improving the readability of log messages during development and debugging processes.

Signature

declare const pretty: Layer.Layer<never>

Example

import { Effect, Logger } from "effect"
const program = Effect.log("message1", "message2").pipe(
Effect.annotateLogs({ key1: "value1", key2: "value2" }),
Effect.withLogSpan("myspan")
)
Effect.runFork(program.pipe(Effect.provide(Logger.pretty)))
// green --v v-- bold and cyan
// [07:51:54.434] INFO (#0) myspan=1ms: message1
// message2
// v-- bold
// key2: value2
// key1: value1

prettyLogger

Added in v3.5.0 Source

The pretty logger utilizes the capabilities of the console API to generate visually engaging and color-enhanced log outputs. This feature is particularly useful for improving the readability of log messages during development and debugging processes.

Signature

declare const prettyLogger: (options?: {
readonly colors?: "auto" | boolean;
readonly formatDate?: (date: Date) => string;
readonly mode?: "browser" | "tty" | "auto";
readonly stderr?: boolean;
}) => Logger<unknown, void>

Example

import { Effect, Logger } from "effect"
const program = Effect.log("message1", "message2").pipe(
Effect.annotateLogs({ key1: "value1", key2: "value2" }),
Effect.withLogSpan("myspan")
)
Effect.runFork(program.pipe(Effect.provide(Logger.pretty)))
// green --v v-- bold and cyan
// [07:51:54.434] INFO (#0) myspan=1ms: message1
// message2
// v-- bold
// key2: value2
// key1: value1

A default version of the pretty logger.

Signature

declare const prettyLoggerDefault: Logger<unknown, void>

simple

Added in v2.0.0 Source

Signature

declare const simple: <A, B>(log: (a: A) => B) => Logger<A, B>

stringLogger

Added in v2.0.0 Source

Signature

declare const stringLogger: Logger<unknown, string>

structured

Added in v2.0.0 Source

The structured logger provides detailed log outputs, structured in a way that retains comprehensive traceability of the events, suitable for deeper analysis and troubleshooting.

Signature

declare const structured: Layer.Layer<never>

Example

import { Effect, Logger } from "effect"
const program = Effect.log("message1", "message2").pipe(
Effect.annotateLogs({ key1: "value1", key2: "value2" }),
Effect.withLogSpan("myspan")
)
Effect.runFork(program.pipe(Effect.provide(Logger.structured)))
// {
// message: [ 'message1', 'message2' ],
// logLevel: 'INFO',
// timestamp: '2024-07-09T14:05:41.623Z',
// cause: undefined,
// annotations: { key2: 'value2', key1: 'value1' },
// spans: { myspan: 0 },
// fiberId: '#0'
// }

The structured logger provides detailed log outputs, structured in a way that retains comprehensive traceability of the events, suitable for deeper analysis and troubleshooting.

Signature

declare const structuredLogger: Logger<unknown, {
readonly annotations: Record<string, unknown>;
readonly cause: string | undefined;
readonly fiberId: string;
readonly logLevel: string;
readonly message: unknown;
readonly spans: Record<string, number>;
readonly timestamp: string;
}>

Example

import { Effect, Logger } from "effect"
const program = Effect.log("message1", "message2").pipe(
Effect.annotateLogs({ key1: "value1", key2: "value2" }),
Effect.withLogSpan("myspan")
)
Effect.runFork(program.pipe(Effect.provide(Logger.structured)))
// {
// message: [ 'message1', 'message2' ],
// logLevel: 'INFO',
// timestamp: '2024-07-09T14:05:41.623Z',
// cause: undefined,
// annotations: { key2: 'value2', key1: 'value1' },
// spans: { myspan: 0 },
// fiberId: '#0'
// }

succeed

Added in v2.0.0 Source

Signature

declare const succeed: <A>(value: A) => Logger<unknown, A>

sync

Added in v2.0.0 Source

Signature

declare const sync: <A>(evaluate: LazyArg<A>) => Logger<unknown, A>

test

Added in v2.0.0 Source

Signature

declare const test: {
<Message>(input: Message): <Output>(self: Logger<Message, Output>) => Output;
<Message, Output>(self: Logger<Message, Output>, input: Message): Output;
}

tracerLogger

Added in v2.0.0 Source

Signature

declare const tracerLogger: Logger<unknown, void>

Context

add

Added in v2.0.0 Source

Signature

declare const add: <B>(logger: Logger<unknown, B>) => Layer.Layer<never>

addEffect

Added in v2.0.0 Source

Signature

declare const addEffect: <A, E, R>(effect: Effect<Logger<unknown, A>, E, R>) => Layer.Layer<never, E, R>

addScoped

Added in v2.0.0 Source

Signature

declare const addScoped: <A, E, R>(effect: Effect<Logger<unknown, A>, E, R>) => Layer.Layer<never, E, Exclude<R, Scope>>

Sets the minimum log level for logging operations, allowing control over which log messages are displayed based on their severity.

Signature

declare const minimumLogLevel: (level: LogLevel.LogLevel) => Layer.Layer<never>

Example

import { Effect, Logger, LogLevel } from "effect"
const program = Effect.gen(function*() {
yield* Effect.log("Executing task...")
yield* Effect.sleep("100 millis")
console.log("task done")
})
// Logging disabled using a layer
Effect.runFork(program.pipe(Effect.provide(Logger.minimumLogLevel(LogLevel.None))))
// task done

remove

Added in v2.0.0 Source

Signature

declare const remove: <A>(logger: Logger<unknown, A>) => Layer.Layer<never>

replace

Added in v2.0.0 Source

Signature

declare const replace: {
<B>(that: Logger<unknown, B>): <A>(self: Logger<unknown, A>) => Layer<never>;
<A, B>(self: Logger<unknown, A>, that: Logger<unknown, B>): Layer<never>;
}

Signature

declare const replaceEffect: {
<B, E, R>(that: Effect<Logger<unknown, B>, E, R>): <A>(self: Logger<unknown, A>) => Layer<never, E, R>;
<A, B, E, R>(self: Logger<unknown, A>, that: Effect<Logger<unknown, B>, E, R>): Layer<never, E, R>;
}

Signature

declare const replaceScoped: {
<B, E, R>(that: Effect<Logger<unknown, B>, E, R>): <A>(self: Logger<unknown, A>) => Layer<never, E, Exclude<R, Scope>>;
<A, B, E, R>(self: Logger<unknown, A>, that: Effect<Logger<unknown, B>, E, R>): Layer<never, E, Exclude<R, Scope>>;
}

Sets the minimum log level for subsequent logging operations, allowing control over which log messages are displayed based on their severity.

Signature

declare const withMinimumLogLevel: {
(level: LogLevel): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
<A, E, R>(self: Effect<A, E, R>, level: LogLevel): Effect<A, E, R>;
}

Example

import { Effect, Logger, LogLevel } from "effect"
const program = Effect.logDebug("message1").pipe(Logger.withMinimumLogLevel(LogLevel.Debug))
Effect.runFork(program)
// timestamp=... level=DEBUG fiber=#0 message=message1

Filtering

Returns a version of this logger that only logs messages when the log level satisfies the specified predicate.

Signature

declare const filterLogLevel: {
(f: (logLevel: LogLevel) => boolean): <Message, Output>(self: Logger<Message, Output>) => Logger<Message, Option<Output>>;
<Message, Output>(self: Logger<Message, Output>, f: (logLevel: LogLevel) => boolean): Logger<Message, Option<Output>>;
}

Guards

isLogger

Added in v1.0.0 Source

Returns true if the specified value is a Logger, otherwise returns false.

Signature

declare const isLogger: (u: unknown) => u is Logger<unknown, unknown>

Mapping

batched

Added in v2.0.0 Source

Creates a batched logger that groups log messages together and processes them in intervals.

Signature

declare const batched: {
<Output, R>(window: DurationInput, f: (messages: Array<NoInfer<Output>>) => Effect<void, never, R>): <Message>(self: Logger<Message, Output>) => Effect<Logger<Message, void>, never, Scope | R>;
<Message, Output, R>(self: Logger<Message, Output>, window: DurationInput, f: (messages: Array<NoInfer<Output>>) => Effect<void, never, R>): Effect<Logger<Message, void>, never, Scope | R>;
}

Example

import { Console, Effect, Logger } from "effect"
const LoggerLive = Logger.replaceScoped(
Logger.defaultLogger,
Logger.logfmtLogger.pipe(
Logger.batched("500 millis", (messages) => Console.log("BATCH", `[\n${messages.join("\n")}\n]`))
)
)
const program = Effect.gen(function*() {
yield* Effect.log("one")
yield* Effect.log("two")
yield* Effect.log("three")
}).pipe(Effect.provide(LoggerLive))
Effect.runFork(program)
// BATCH [
// timestamp=... level=INFO fiber=#0 message=one
// timestamp=... level=INFO fiber=#0 message=two
// timestamp=... level=INFO fiber=#0 message=three
// ]

map

Added in v2.0.0 Source

Signature

declare const map: {
<Output, Output2>(f: (output: Output) => Output2): <Message>(self: Logger<Message, Output>) => Logger<Message, Output2>;
<Message, Output, Output2>(self: Logger<Message, Output>, f: (output: Output) => Output2): Logger<Message, Output2>;
}

mapInput

Added in v2.0.0 Source

Signature

declare const mapInput: {
<Message, Message2>(f: (message: Message2) => Message): <Output>(self: Logger<Message, Output>) => Logger<Message2, Output>;
<Output, Message, Message2>(self: Logger<Message, Output>, f: (message: Message2) => Message): Logger<Message2, Output>;
}

Signature

declare const mapInputOptions: {
<Message, Message2>(f: (options: Options<Message2>) => Options<Message>): <Output>(self: Logger<Message, Output>) => Logger<Message2, Output>;
<Output, Message, Message2>(self: Logger<Message, Output>, f: (options: Options<Message2>) => Options<Message>): Logger<Message2, Output>;
}

Models

Logger interface

Added in v2.0.0 Source

Signature

interface Logger<in Message, out Output> extends Variance<Message, Output>, Pipeable {
log(options: Options<Message>): Output;
}

Other

Logger

Added in v2.0.0 Source

Symbols

LoggerTypeId

Added in v2.0.0 Source

Signature

declare const LoggerTypeId: unique symbol

LoggerTypeId type

Added in v2.0.0 Source

Signature

type LoggerTypeId = typeof LoggerTypeId

Tracing

Signature

declare const withSpanAnnotations: <Message, Output>(self: Logger<Message, Output>) => Logger<Message, Output>

Zipping

zip

Added in v2.0.0 Source

Combines this logger with the specified logger to produce a new logger that logs to both this logger and that logger.

Signature

declare const zip: {
<Message2, Output2>(that: Logger<Message2, Output2>): <Message, Output>(self: Logger<Message, Output>) => Logger<Message & Message2, [Output, Output2]>;
<Message, Output, Message2, Output2>(self: Logger<Message, Output>, that: Logger<Message2, Output2>): Logger<Message & Message2, [Output, Output2]>;
}

zipLeft

Added in v2.0.0 Source

Signature

declare const zipLeft: {
<Message2, Output2>(that: Logger<Message2, Output2>): <Message, Output>(self: Logger<Message, Output>) => Logger<Message & Message2, Output>;
<Message, Output, Message2, Output2>(self: Logger<Message, Output>, that: Logger<Message2, Output2>): Logger<Message & Message2, Output>;
}

zipRight

Added in v2.0.0 Source

Signature

declare const zipRight: {
<Message2, Output2>(that: Logger<Message2, Output2>): <Message, Output>(self: Logger<Message, Output>) => Logger<Message & Message2, Output2>;
<Message, Output, Message2, Output2>(self: Logger<Message, Output>, that: Logger<Message2, Output2>): Logger<Message & Message2, Output2>;
}