Logger<unknown, void>A Logger which outputs logs using a structured format and writes them to
the console.
Details
For example, console structured output can contain
message: [ "info", "message" ], level: "INFO",
timestamp: "2025-01-03T14:25:39.666Z",
annotations: { key: "value" }, spans: { label: 0 }, and
fiberId: "#1".
Example (Logging structured output to the console)
import { Effect, Logger } from "effect"
// Use the console structured logger
const structuredProgram = Effect.log("Hello Structured Console").pipe(
Effect.provide(Logger.layer([Logger.consoleStructured]))
)
// Perfect for development debugging
const debugProgram = Effect.gen(function*() {
yield* Effect.log("User event", {
userId: 123,
action: "login",
ip: "192.168.1.1"
})
yield* Effect.logInfo("API call", {
endpoint: "/users",
method: "GET",
duration: 120
})
}).pipe(
Effect.annotateLogs("requestId", "req-123"),
Effect.withLogSpan("authentication"),
Effect.provide(Logger.layer([Logger.consoleStructured]))
)
// Easy to parse and inspect object structure
const inspectionProgram = Effect.gen(function*() {
yield* Effect.log("Complex data", {
user: { id: 1, name: "John" },
metadata: { source: "api", version: 2 }
})
}).pipe(
Effect.provide(Logger.layer([Logger.consoleStructured]))
)export const const consoleStructured: Logger<
unknown,
void
>
const consoleStructured: {
log: (options: Options<unknown>) => void;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
A Logger which outputs logs using a structured format and writes them to
the console.
Details
For example, console structured output can contain
message: [ "info", "message" ], level: "INFO",
timestamp: "2025-01-03T14:25:39.666Z",
annotations: { key: "value" }, spans: { label: 0 }, and
fiberId: "#1".
Example (Logging structured output to the console)
import { Effect, Logger } from "effect"
// Use the console structured logger
const structuredProgram = Effect.log("Hello Structured Console").pipe(
Effect.provide(Logger.layer([Logger.consoleStructured]))
)
// Perfect for development debugging
const debugProgram = Effect.gen(function*() {
yield* Effect.log("User event", {
userId: 123,
action: "login",
ip: "192.168.1.1"
})
yield* Effect.logInfo("API call", {
endpoint: "/users",
method: "GET",
duration: 120
})
}).pipe(
Effect.annotateLogs("requestId", "req-123"),
Effect.withLogSpan("authentication"),
Effect.provide(Logger.layer([Logger.consoleStructured]))
)
// Easy to parse and inspect object structure
const inspectionProgram = Effect.gen(function*() {
yield* Effect.log("Complex data", {
user: { id: 1, name: "John" },
metadata: { source: "api", version: 2 }
})
}).pipe(
Effect.provide(Logger.layer([Logger.consoleStructured]))
)
consoleStructured: interface Logger<in Message, out Output>A logger that transforms a runtime log event into an output value.
Details
The runtime calls log with the message, level, cause, fiber, and timestamp
for each log event. Use Logger.layer to install one or more loggers for an
effect.
Example (Creating custom loggers)
import { Effect, Logger } from "effect"
// Create a custom logger that accepts unknown messages and returns void
const stringLogger = Logger.make<unknown, void>((options) => {
console.log(`[${options.logLevel}] ${options.message}`)
})
// Create a logger that accepts any message type and returns a formatted string
const formattedLogger = Logger.make<unknown, string>((options) =>
`${options.date.toISOString()} [${options.logLevel}] ${options.message}`
)
// Use the logger in an Effect program
const program = Effect.log("Hello World").pipe(
Effect.provide(Logger.layer([stringLogger]))
)
Logger<unknown, void> = const withConsoleLog: <Message, Output>(
self: Logger<Message, Output>
) => Logger<Message, void>
Returns a new Logger that writes all output of the specified Logger to
the console using console.log.
When to use
Use when a logger's string or object output should be routed to console.log for
development or debugging.
Example (Writing logger output with console.log)
import { Effect, Logger } from "effect"
// Create a custom formatter
const customFormatter = Logger.make((options) =>
`[${options.date.toISOString()}] ${options.logLevel}: ${options.message}`
)
// Route to console
const consoleLogger = Logger.withConsoleLog(customFormatter)
const program = Effect.log("Hello World").pipe(
Effect.provide(Logger.layer([consoleLogger]))
)
withConsoleLog(const formatStructured: Logger<
unknown,
{
readonly level: string
readonly fiberId: string
readonly timestamp: string
readonly message: unknown
readonly cause: string | undefined
readonly annotations: Record<string, unknown>
readonly spans: Record<string, number>
}
>
const formatStructured: {
log: (options: Options<unknown>) => { readonly level: string; readonly fiberId: string; readonly timestamp: string; readonly message: unknown; readonly cause: string | undefined; readonly annotations: Record<string, unknown>; readonly spans: Re…;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
A Logger which outputs logs using a structured format.
Details
For example, a structured entry can contain message: [ "hello" ],
level: "INFO", timestamp: "2025-01-03T14:25:39.666Z",
annotations: { key: "value" }, spans: { label: 0 }, and
fiberId: "#1".
Example (Formatting logs as structured objects)
import { Effect, Logger } from "effect"
// Use the structured format logger
const structuredLoggerProgram = Effect.log("Hello Structured Format").pipe(
Effect.provide(Logger.layer([Logger.formatStructured]))
)
// Perfect for JSON processing and analytics
const analyticsProgram = Effect.gen(function*() {
yield* Effect.log("User action", { action: "click", element: "button" })
yield* Effect.logInfo("API call", { endpoint: "/users", duration: 150 })
}).pipe(
Effect.annotateLogs("sessionId", "abc123"),
Effect.withLogSpan("request"),
Effect.provide(Logger.layer([Logger.formatStructured]))
)
// Process structured output
const processingLogger = Logger.map(Logger.formatStructured, (output) => {
// Process the structured object
const enhanced = { ...output, processed: true }
return enhanced
})
formatStructured)