Skip to content

Presets

Presets define the database schema and introspection configuration for Pinorama Server. They control how logs are indexed, displayed, filtered, and styled in Pinorama Studio.

How Presets Work

A preset is an object with two properties:

  • schema — An Orama schema that defines the indexed fields and their types
  • introspection — A PinoramaIntrospection config that controls how Pinorama Studio renders the data
ts
type PinoramaPreset<T> = {
  schema: T
  introspection: PinoramaIntrospection<T>
}

Presets are passed to the server at registration time via the dbSchema and introspection options.

Built-in Presets

Pinorama ships with two presets in the pinorama-presets package.

pino (default)

The default preset for standard Pino logs.

Schema fields:

FieldTypeDescription
timenumberLog timestamp
levelenumLog level (10–60)
msgstringLog message
pidenumProcess ID
hostnamestringHostname

Default columns:

ColumnVisibleSize
timeyes150px
levelyes70px
msgyes400px
pidno70px
hostnameno150px

Level labels: TRACE (10), DEBUG (20), INFO (30), WARN (40), ERROR (50), FATAL (60)

fastify

Extended preset for Fastify applications. Includes all pino fields plus HTTP request/response data.

Additional schema fields:

FieldTypeDescription
reqIdstringRequest ID
req.methodstringHTTP method
req.urlstringRequest URL
req.hostnamestringRequest hostname
req.remoteAddressstringClient IP address
req.remotePortenumClient port
res.statusCodeenumResponse status code
responseTimenumberResponse time in ms

Additional columns:

ColumnVisibleSize
reqIdyes80px
req.methodyes80px
req.urlyes100px
res.statusCodeyes70px
req.hostnameno150px
req.remoteAddressno100px
req.remotePortno80px
responseTimeno150px

Introspection Config

The PinoramaIntrospection object controls how Pinorama Studio renders each field:

facets

Defines which fields appear as filters in the sidebar. Three facet types are available:

TypeDescriptionUI Control
"enum"Select from known valuesCheckbox list
"string"Free text searchText input
"date"Date range filterDate range picker
ts
facets: {
  time: "date",
  level: "enum",
  msg: "string",
  "req.method": "string"
}

columns

Controls which fields appear as columns in the log viewer, their visibility, and width.

ts
columns: {
  time: { visible: true, size: 150 },
  level: { visible: true, size: 70 },
  msg: { visible: true, size: 400 },
  pid: { visible: false, size: 70 }
}

labels

Defines display labels for fields. Can be a simple string or a tuple with a value map for human-readable values.

ts
labels: {
  time: "Time",                    // simple label
  msg: "Message",
  level: ["Level", {               // label + value mapping
    10: "TRACE",
    20: "DEBUG",
    30: "INFO",
    40: "WARN",
    50: "ERROR",
    60: "FATAL"
  }]
}

formatters

Specifies how field values are formatted for display. Currently supports "timestamp" for converting Unix timestamps.

ts
formatters: {
  time: "timestamp"
}

styles

Defines CSS styles applied to field values. Can be a base style object or a tuple with per-value styles.

ts
styles: {
  time: { opacity: "0.5" },       // base style for all values
  level: [{}, {                    // base + per-value styles
    30: { color: "lime" },
    40: { color: "yellow" },
    50: { color: "red" }
  }]
}

The server generates CSS classes from these styles (e.g. .pinorama-level, .pinorama-level-30) served at GET /styles.css.

Custom Presets

Create a custom preset using the createPreset function from pinorama-presets, then pass it to the server:

ts
import pinoramaServer from "pinorama-server"

app.register(pinoramaServer, {
  dbSchema: myPreset.schema,
  introspection: myPreset.introspection
})
Full custom preset example
ts
import { createPreset } from "pinorama-presets"

const myPreset = createPreset(
  // Orama schema
  {
    timestamp: "number",
    severity: "enum",
    message: "string",
    service: "string"
  },
  // Introspection config
  {
    facets: {
      timestamp: "date",
      severity: "enum",
      message: "string",
      service: "enum"
    },
    columns: {
      timestamp: { visible: true, size: 150 },
      severity: { visible: true, size: 80 },
      message: { visible: true, size: 400 },
      service: { visible: true, size: 100 }
    },
    labels: {
      timestamp: "Time",
      severity: ["Severity", { 1: "LOW", 2: "MEDIUM", 3: "HIGH" }],
      message: "Message",
      service: "Service"
    },
    formatters: {
      timestamp: "timestamp"
    },
    styles: {
      severity: [{}, {
        1: { color: "gray" },
        2: { color: "yellow" },
        3: { color: "red" }
      }]
    }
  }
)