---
title: "Configuration"
description: "Control log level, connectors, file rotation, ingestion paths, and config loading with code or blyp.config files."
canonical_url: "https://www.blyp.dev/docs/configuration"
markdown_url: "https://www.blyp.dev/docs/configuration.md"
last_updated: "2018-10-20"
x_farming_labs_generated_preamble: true
---

# Configuration
URL: /docs/configuration
LLM index: /llms.txt
Description: Control log level, connectors, file rotation, ingestion paths, and config loading with code or blyp.config files.

# Configuration

Blyp configuration comes from two places:

- `blyp.config.*` in your project root
- per-logger runtime overrides passed to `createStandaloneLogger()` or a framework adapter

Runtime overrides are merged on top of the loaded config.

## Supported config files

Blyp loads the first matching config file from:

- `blyp.config.ts`
- `blyp.config.mts`
- `blyp.config.cts`
- `blyp.config.js`
- `blyp.config.mjs`
- `blyp.config.cjs`
- `blyp.config.json`

Executable config files are loaded through `jiti`.

If Convex (or another isolate) will import the same `blyp.config.ts`, use the isolate-safe helper so that file does not pull the Node logger graph:

```ts
import { defineConfig } from "@blyp/core/config";

export default defineConfig({
  level: "info",
  connectors: {
    otlp: [
      {
        name: "axiom",
        endpoint: "https://api.axiom.co/v1/logs",
        auth: `Bearer ${process.env.AXIOM_TOKEN}`,
      },
    ],
  },
});
```

Node apps can keep `import { defineConfig } from "@blyp/core"`. Convex must import the config module and pass it to `configureConvexLogger()`; it does not walk the filesystem. See [Convex](/docs/integrations/convex).

## Example `blyp.config.ts`

```ts
export default {
  "pretty": true,
  "level": "info",
  "destination": "database",
  "redact": {
    "paths": ["user.ssn", "payment.**.raw"]
  },
  "file": {
    "enabled": true,
    "format": "ndjson",
    "rotation": {
      "enabled": true,
      "maxSizeBytes": 10485760,
      "maxArchives": 5,
      "compress": true
    }
  },
  "database": {
    "dialect": "postgres",
    "delivery": {
      "strategy": "immediate",
      "batchSize": 1,
      "flushIntervalMs": 250,
      "maxQueueSize": 1000,
      "overflowStrategy": "drop-oldest",
      "flushTimeoutMs": 5000,
      "retry": {
        "maxRetries": 1,
        "backoffMs": 100
      }
    }
  },
  "clientLogging": {
    "enabled": true,
    "path": "/inngest"
  },
  "connectors": {
    "delivery": {
      "enabled": true,
      "durableQueuePath": ".blyp/connectors.sqlite",
      "retry": {
        "maxAttempts": 8,
        "initialBackoffMs": 500,
        "maxBackoffMs": 30000,
        "multiplier": 2,
        "jitter": true
      }
    },
    "posthog": {
      "enabled": true,
      "mode": "auto",
      "projectKey": process.env.POSTHOG_PROJECT_KEY,
      "errorTracking": {
        "enabled": true,
        "mode": "auto"
      }
    },
    "sentry": {
      "enabled": true,
      "mode": "auto",
      "dsn": process.env.SENTRY_DSN
    },
    "otlp": [
      {
        "name": "grafana",
        "enabled": true,
        "mode": "auto",
        "endpoint": process.env.OTLP_HTTP_ENDPOINT
      }
    ]
  }
};
```

## Default behavior

- pretty console logging is enabled
- default level is `info`
- default destination is `file`
- file logging is enabled
- client logging is enabled
- default client ingestion path is `/inngest`
- built-in redaction runs across console, files, database writes, connectors, client ingestion, and framework request logs
- default rotation is `10 MB`, `5` archives, gzip compression enabled
- database delivery defaults are immediate writes, queue size `1000`, flush timeout `5000ms`, and one retry with `100ms` backoff
- connector delivery queueing is disabled unless `connectors.delivery.enabled` is set
- connectors are disabled unless configured

## Redaction config

Use `redact` to remove sensitive values before they reach Blyp sinks:

```ts
export default {
  redact: {
    keys: ["internal_token"],
    paths: ["user.ssn", "payment.**.raw"],
    patterns: [/MY_ORG_[A-Z0-9]{32}/],
    disablePatternScanning: false,
  },
};
```

The redaction config supports:

- `keys`: additional sensitive field names to redact
- `paths`: exact or wildcard field paths to redact
- `patterns`: regex patterns for secret scanning
- `disablePatternScanning`: disables Blyp's built-in token and card pattern detection

Notes:

- `redact.paths` supports exact paths, numeric indexes, `*`, and `**`
- `patterns` require executable config such as `blyp.config.ts`
- Blyp preserves keys and replaces values with `[REDACTED]` or a typed marker such as `[REDACTED:jwt]`

## Database logging config

Use `destination: "database"` when local file persistence is not a good fit, especially in serverless deployments.

Database mode requires an executable config file such as `blyp.config.ts`, `blyp.config.mts`, `blyp.config.js`, or `blyp.config.cjs` because Prisma and Drizzle adapters are runtime objects.
`blyp.config.json` cannot hold adapter instances by itself.

The config flag is only one part of the setup. The database must also match the required Blyp schema contract documented in [Schema Contract](/docs/database/schema).

```ts
import { PrismaClient } from "@prisma/client";
import { createPrismaDatabaseAdapter } from "@blyp/core/database";

const prisma = new PrismaClient();

export default {
  destination: "database",
  database: {
    dialect: "postgres",
    adapter: createPrismaDatabaseAdapter({
      client: prisma,
      model: "blypLog",
    }),
    delivery: {
      strategy: "batch",
      batchSize: 50,
      flushIntervalMs: 1000,
    },
  },
};
```

The database delivery config supports:

- `strategy`: `"immediate"` or `"batch"`
- `batchSize`
- `flushIntervalMs`
- `maxQueueSize`
- `overflowStrategy`: `"drop-oldest"` or `"drop-new"`
- `flushTimeoutMs`
- `retry.maxRetries`
- `retry.backoffMs`

Use [Database](/docs/database) for the full setup flow, [Schema Contract](/docs/database/schema) for the required table and indexes, and [Database Migrations](/docs/database/migrations) for the CLI migration workflow.

## Connector delivery queue config

Use `connectors.delivery` when retryable server-side connector failures should spill into Blyp's internal queue instead of being dropped immediately:

```ts
export default {
  connectors: {
    delivery: {
      enabled: true,
      durableQueuePath: ".blyp/connectors.sqlite",
      memoryBufferSize: 500,
      durableSpillStrategy: "after-first-failure",
      memoryBatchSize: 25,
      sqliteWriteBatchSize: 100,
      sqliteReadBatchSize: 50,
      dispatchConcurrency: 4,
      pollIntervalMs: 1000,
      overflowStrategy: "drop-oldest",
      retry: {
        maxAttempts: 8,
        initialBackoffMs: 500,
        maxBackoffMs: 30000,
        multiplier: 2,
        jitter: true,
      },
    },
    betterstack: {
      enabled: true,
      mode: "auto",
      sourceToken: process.env.BETTERSTACK_TOKEN,
      ingestingHost: "https://in.logs.betterstack.com",
    },
  },
};
```

The connector delivery config supports:

- `enabled`
- `memoryBufferSize`
- `durableQueuePath`
- `durableSpillStrategy`
- `memoryBatchSize`
- `sqliteWriteBatchSize`
- `sqliteReadBatchSize`
- `dispatchConcurrency`
- `pollIntervalMs`
- `overflowStrategy`
- `retry.maxAttempts`
- `retry.initialBackoffMs`
- `retry.maxBackoffMs`
- `retry.multiplier`
- `retry.jitter`

Notes:

- the default queue path is `.blyp/connectors.sqlite`
- `.blyp/` should be ignored in git
- this queue applies to server connector delivery, not the primary `destination`
- older runtimes without built-in SQLite support fall back to memory-only retries with a warning
- use the root exports `getConnectorQueuePath()`, `connectorQueueExists()`, `getConnectorDeliveryStatusSummary()`, `listConnectorDeadLetters()`, `retryConnectorDeadLetters()`, and `clearConnectorDeadLetters()` for queue inspection and recovery tooling

## Common server adapter options

```ts
createLogger({
  level: "debug",
  pretty: false,
  logDir: "logs/api",
  file: {
    rotation: {
      maxSizeBytes: 5 * 1024 * 1024,
      maxArchives: 3,
      compress: true,
    },
  },
  autoLogging: {
    ignore: (ctx) => false,
  },
  customProps: (ctx) => ({
    requestId: "req_123",
  }),
  logErrors: true,
  ignorePaths: ["/health", "/metrics/**"],
  clientLogging: {
    path: "/client-ingest",
    validate: async (_ctx, payload) => payload.id !== "blocked",
    enrich: async (_ctx, payload) => ({
      clientLevel: payload.level,
    }),
  },
});
```

## Connector config

Connectors live under `connectors`:

```ts
export default {
  connectors: {
    posthog: {
      enabled: true,
      mode: "auto",
      projectKey: process.env.POSTHOG_PROJECT_KEY,
      errorTracking: {
        enabled: true,
        mode: "auto",
        enableExceptionAutocapture: true,
      },
    },
    sentry: {
      enabled: true,
      mode: "auto",
      dsn: process.env.SENTRY_DSN,
      environment: process.env.NODE_ENV,
      release: process.env.RELEASE_SHA,
    },
    otlp: [
      {
        name: "grafana",
        enabled: true,
        mode: "auto",
        endpoint: process.env.OTLP_HTTP_ENDPOINT,
        auth: process.env.OTLP_AUTH_HEADER,
        serviceName: "api",
      },
    ],
  },
};
```

## Notes that matter in production

- `ignorePaths` applies to both automatic request logs and error logs.
- When client logging is enabled, the ingestion path is auto-added to the ignore list so Blyp does not emit duplicate `http_request` records for `POST /inngest`.
- `logErrors: false` disables HTTP error record emission for the adapter.
- `customProps()` is merged into emitted request records and is the right place for request IDs, user IDs, tenant IDs, and controller/action names.
- connector `auto` mode forwards from server runtimes directly
- browser and Expo connector requests still flow through Blyp ingestion first

## Config helpers from the root package

```ts
import {
  getConfig,
  loadConfig,
  mergeBlypConfig,
  resolveConfig,
  resetConfigCache,
  type ResolvedBlypConfig,
} from "@blyp/core";
```

`loadConfig()`, `resolveConfig()`, and `getConfig()` now return `ResolvedBlypConfig`, so the returned shape includes normalized defaults for `destination`, `file`, `clientLogging`, connector readiness, and database delivery.

Use these if you need to inspect or recompute configuration in tests or custom bootstrap code.

Use [Connectors](/docs/connectors) for provider-specific behavior and manual APIs.

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
Docs-scoped sitemap: [/docs/sitemap.md](/docs/sitemap.md).
Well-known sitemap: [/.well-known/sitemap.md](/.well-known/sitemap.md).
