# How LoggerService Interfaces with the Cordis Context: Deep Implementation Guide

> Discover how LoggerService interfaces with the Cordis context via constructor injection and fiber-aware emission. Achieve scoped logging that auto-cleans up with Cordis contexts.

- Repository: [Cordiverse/cordis](https://github.com/cordiverse/cordis)
- Tags: deep-dive
- Published: 2026-08-22

---

**The `LoggerService` binds to the Cordis execution context through constructor injection, effect-based lifecycle management, and fiber-aware message emission, enabling scoped logging that automatically cleans up when contexts dispose.**

The `LoggerService` in the **cordiverse/cordis** repository provides a sophisticated logging layer that leverages the framework's context system for dependency injection, configuration resolution, and execution tracking. Understanding how this service interfaces with the Cordis context reveals the architectural patterns that make the framework modular and reactive.

## Constructor Injection and Context Storage

The `LoggerService` establishes its relationship with the Cordis context immediately upon instantiation. In [`packages/core/src/logger.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/logger.ts) at lines 79–84, the service receives a `Context` instance through its constructor and stores it in the `ctx` property (lines 73–87). This **context binding** makes the service aware of its execution scope from the moment it is created.

Storing the context reference allows the logger to access framework-level services, configuration intercepts, and the current execution fiber throughout its lifecycle. This pattern ensures that every logger instance operates within a specific contextual boundary rather than existing as a global singleton.

## Effect-Based Lifecycle Management

After securing the context reference, the service registers its cleanup logic through the context's effect system. At lines 89–102 in [`packages/core/src/logger.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/logger.ts), the constructor invokes `ctx.effect` to register default exporters. This **effect registration** ties the logger's resource lifecycle directly to the context's disposal mechanism.

When the Cordis context is torn down, the effect system automatically triggers cleanup for all registered logger exporters. This prevents memory leaks and ensures that file handles, network connections, or other resources held by transport layers are released precisely when their parent context terminates.

## Dynamic Configuration via Context Intercepts

The `LoggerService` resolves configuration dynamically through the context's intercept system. When invoked via the `[symbols.invoke]` method at lines 126–138, the service reads configuration overrides from `ctx[symbols.intercept]` (lines 140–144). This mechanism enables **per-context configuration** such as default log levels, logger names, and formatter options.

Framework users can inject configuration at any point in the context hierarchy:

```typescript
import { LoggerLevel } from 'cordis'

// Override defaults for this context and its children
ctx.intercept({
  logger: { 
    level: LoggerLevel.WARN, 
    name: 'custom-logger' 
  },
})

// Subsequent logger instances respect the intercept
const logger = ctx.logger()
logger.debug('Filtered out')  // Ignored due to WARN level
logger.warn('Visible log')    // Emitted successfully

```

The service merges these intercepted values with instance-specific parameters, allowing granular control over logging behavior across different application layers.

## Fiber-Aware Message Emission

Every log message generated through the `LoggerService` maintains a reference to its execution context via the **Cordis fiber system**. When creating a logger instance, the service accesses the current fiber through `(caller ?? this.ctx).fiber` at lines 145–146. If no explicit name is provided, it falls back to the fiber's hyphenated representation (lines 149–150).

During message emission (lines 162–166), the service iterates over registered exporters and determines the effective log level by evaluating the exporter's level map, the logger's configured level, and the default level (lines 163–165). Each constructed `Message` object includes a `WeakRef` to the current fiber at lines 168–169, enabling downstream consumers to correlate log entries with specific execution paths without preventing garbage collection.

This fiber association allows debugging tools to trace logs back to their originating contextual fibers, even in complex asynchronous scenarios involving multiple nested contexts.

## Summary

- **Constructor binding**: `LoggerService` stores the Cordis `Context` instance in its `ctx` property during instantiation (lines 73–87).
- **Automated cleanup**: The service registers exporters through `ctx.effect`, ensuring resources release when contexts dispose (lines 89–102).
- **Configurable intercepts**: Configuration overrides are read from `ctx[symbols.intercept]`, enabling per-context log levels and names (lines 140–144).
- **Execution tracking**: Log messages capture the current fiber via `(caller ?? this.ctx).fiber`, binding entries to their execution context (lines 145–150, 168–169).

## Frequently Asked Questions

### How does LoggerService access the current execution fiber?

The service retrieves the active fiber through the expression `(caller ?? this.ctx).fiber` at lines 145–146 in [`packages/core/src/logger.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/logger.ts). If an explicit caller context is provided during logger creation, it uses that context's fiber; otherwise, it falls back to the service's own context fiber. This ensures every logger instance remains associated with its correct execution scope.

### Can I override logger configuration for specific contexts?

Yes. The framework supports **context intercepts** that allow you to override logger configuration at any level of the context tree. By calling `ctx.intercept({ logger: { level, name } })`, you modify the default behavior for all subsequent `ctx.logger()` calls within that scope. The service reads these values via `ctx[symbols.intercept]` at lines 140–144.

### What happens to logger exporters when a context is disposed?

The exporters are automatically cleaned up. During construction at lines 89–102, `LoggerService` registers its exporter initialization logic through `ctx.effect()`. When the Cordis context triggers its disposal sequence, the effect system invokes the cleanup functions, releasing all associated transport resources without manual intervention.

### Where is the LoggerService defined in the source code?

The primary implementation resides in [`packages/core/src/logger.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/logger.ts). Supporting infrastructure exists in [`packages/core/src/context.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/context.ts) (effect system and intercept handling), [`packages/core/src/fiber.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/fiber.ts) (execution fiber tracking), and [`packages/core/src/utils.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/utils.ts) (symbols and helper utilities like `createCallable` that enable the service's callable interface).