> ## Documentation Index
> Fetch the complete documentation index at: https://docs.faremeter.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Logging

> Configuring structured logging with @faremeter/logs.

`@faremeter/logs` provides a lightweight logging abstraction used across all faremeter packages. It supports pluggable backends, log levels, and structured context objects.

```bash theme={null}
pnpm add @faremeter/logs
```

## Basic usage

Get a logger without any explicit configuration. The library auto-resolves a backend (`LogtapeBackend` if `@logtape/logtape` is installed, otherwise `ConsoleBackend`).

```typescript theme={null}
import { getLogger } from "@faremeter/logs"

const logger = await getLogger(["my-app"])

logger.info("Server started", { port: 3000 })
logger.error("Request failed", { status: 500, path: "/api/resource" })
```

The `subsystem` array passed to `getLogger` identifies the component producing the log entry. Backends use this for filtering and categorization.

## Configuring the app

Call `configureApp` once at startup to set the log level and optionally choose a backend:

```typescript theme={null}
import { configureApp, getLogger } from "@faremeter/logs"

await configureApp({ level: "debug" })

const logger = await getLogger(["my-app"])
logger.debug("This will now appear")
```

### `ConfigureAppArgs`

| Option    | Type             | Default       | Description                |
| --------- | ---------------- | ------------- | -------------------------- |
| `level`   | `LogLevel`       | `"info"`      | Minimum log level to emit. |
| `backend` | `LoggingBackend` | Auto-resolved | Logging backend to use.    |

## Log levels

The `LogLevels` constant defines all available levels in order of increasing severity:

```typescript theme={null}
import { LogLevels } from "@faremeter/logs"

// ["trace", "debug", "info", "warning", "error", "fatal"]
```

| Level     | Use case                                            |
| --------- | --------------------------------------------------- |
| `trace`   | Fine-grained debugging (RPC calls, serialization).  |
| `debug`   | Development diagnostics.                            |
| `info`    | Normal operational events.                          |
| `warning` | Recoverable issues that may need attention.         |
| `error`   | Failures that prevent an operation from completing. |
| `fatal`   | Unrecoverable errors requiring shutdown.            |

Messages below the configured level are suppressed.

## Context objects

Every log method accepts an optional context object as the second argument:

```typescript theme={null}
logger.info("Payment settled", {
  txHash: "5xK9...",
  network: "devnet",
  amount: 0.01,
})
```

Context values can be any serializable type (`Record<string, unknown>`). Backends determine how context is rendered.

## Custom backend

Implement the `LoggingBackend` interface to route logs to any destination:

```typescript theme={null}
import type { LoggingBackend, LogLevel, LogArgs } from "@faremeter/logs"

const myBackend: LoggingBackend = {
  async configureApp({ level }: { level: LogLevel }) {
    // Store the configured level, initialize your transport, etc.
  },

  getLogger(subsystem: readonly string[]) {
    const prefix = subsystem.join(":")
    return {
      debug: (msg, ctx?) => console.debug(`[${prefix}]`, msg, ctx),
      info: (msg, ctx?) => console.info(`[${prefix}]`, msg, ctx),
      warning: (msg, ctx?) => console.warn(`[${prefix}]`, msg, ctx),
      error: (msg, ctx?) => console.error(`[${prefix}]`, msg, ctx),
      fatal: (msg, ctx?) => console.error(`[FATAL][${prefix}]`, msg, ctx),
    }
  },
}
```

Pass it to `configureApp`:

```typescript theme={null}
import { configureApp } from "@faremeter/logs"

await configureApp({ level: "debug", backend: myBackend })
```

## LogtapeBackend

For structured logging in production, use the `LogtapeBackend` from `@faremeter/logs/logtape`. This is the default backend when `@logtape/logtape` is installed.

```bash theme={null}
pnpm add @logtape/logtape
```

```typescript theme={null}
import { configureApp } from "@faremeter/logs"
import { LogtapeBackend } from "@faremeter/logs/logtape"

await configureApp({ level: "info", backend: LogtapeBackend })
```

`LogtapeBackend` integrates with the logtape ecosystem, enabling file sinks, JSON formatting, and other logtape transports.

## Further reading

* [Fetch Wrapper](/client/fetch-wrapper) -- The fetch wrapper uses `@faremeter/logs` internally.
* [@faremeter/logs API Reference](/api/logs.src) -- Full API reference.
