Skip to content

Client

Pinorama Client is an isomorphic HTTP client for interacting with Pinorama Server. It provides methods for inserting logs, searching, querying stats, and managing MCP. It works in both Node.js and the browser.

Installation

sh
npm i pinorama-client
sh
pnpm i pinorama-client
sh
yarn add pinorama-client

Usage

js
import { PinoramaClient } from "pinorama-client"

const client = new PinoramaClient({
  url: "http://localhost:3000/pinorama",
  adminSecret: "my-secret"
})

// Insert logs
await client.insert([
  { level: 30, msg: "hello", time: Date.now() }
])

// Search logs
const results = await client.search({
  term: "hello",
  limit: 10
})

Constructor Options

Options are validated with Zod at construction time.

OptionTypeDefaultDescription
urlstringrequiredPinorama Server URL
adminSecretstringSecret for the x-pinorama-admin-secret header
maxRetriesnumber5Max retry attempts for insert()
backoffnumber1000Initial backoff time in ms
backoffFactornumber2Backoff multiplier (min: 2)
backoffMaxnumber30000Maximum backoff time in ms

API Methods

insert(docs)

Insert an array of log documents into the server.

  • Endpoint: POST /bulk
  • Retries: Yes (exponential backoff)
  • Returns: Promise<void>
js
await client.insert([
  { level: 30, msg: "request started", time: Date.now() },
  { level: 30, msg: "request completed", time: Date.now() }
])

search(params)

Search the log database using Orama search params.

  • Endpoint: POST /search
  • Retries: No
  • Returns: Promise<Results>
js
const results = await client.search({
  term: "error",
  where: { level: { eq: 50 } },
  limit: 25
})

console.log(results.hits)

introspection()

Retrieve the server's introspection configuration (facets, columns, labels, formatters, styles).

  • Endpoint: GET /introspection
  • Retries: No
  • Returns: Promise<PinoramaIntrospection>
js
const config = await client.introspection()
console.log(config.columns)

styles()

Retrieve the server's generated CSS stylesheet.

  • Endpoint: GET /styles.css
  • Retries: No
  • Returns: Promise<string>
js
const css = await client.styles()

clear()

Clear all documents from the database.

  • Endpoint: POST /clear
  • Retries: No
  • Returns: Promise<void>
js
await client.clear()

stats()

Get database statistics: total documents, memory usage, and time range.

  • Endpoint: GET /stats
  • Retries: No
  • Returns: Promise<PinoramaStats>
js
const stats = await client.stats()
console.log(stats.totalDocs, stats.memoryUsage)

The returned object includes:

FieldTypeDescription
totalDocsnumberTotal number of documents
memoryUsagenumberHeap memory used in bytes
oldestTimestampnumber | nullOldest log timestamp
newestTimestampnumber | nullNewest log timestamp

context(params)

Get logs surrounding a specific timestamp.

  • Endpoint: POST /context
  • Retries: No
  • Returns: Promise<PinoramaContextResult>
js
const ctx = await client.context({
  timestamp: 1700000000000,
  before: 10,
  after: 10
})

console.log(ctx.before, ctx.after)
ParamTypeDefaultDescription
timestampnumberrequiredCenter point timestamp
beforenumber10Number of logs before the timestamp
afternumber10Number of logs after the timestamp
whereobjectAdditional Orama where clause

aggregateByField(params)

Group logs by a field and compute optional metrics.

  • Endpoint: POST /aggregate/field
  • Retries: No
  • Returns: Promise<PinoramaAggregateResult>
js
const result = await client.aggregateByField({
  field: "req.url",
  metric: { field: "responseTime", fn: "avg" },
  limit: 10
})

console.log(result.values)
ParamTypeDefaultDescription
fieldstringrequiredField to group by
metricobject{ field: string, fn: "count" | "avg" | "min" | "max" }
whereobjectOrama where clause for filtering
limitnumber10Max number of groups

mcpStatus()

Check whether the embedded MCP server is enabled.

  • Endpoint: GET /mcp/status
  • Retries: No
  • Returns: Promise<{ enabled: boolean }>
js
const { enabled } = await client.mcpStatus()

setMcpStatus(enabled)

Enable or disable the embedded MCP server.

  • Endpoint: POST /mcp/status
  • Retries: No
  • Returns: Promise<{ enabled: boolean }>
js
await client.setMcpStatus(true)

Error Handling

All methods throw a PinoramaError on failure. This error extends Error with additional properties:

PropertyTypeDescription
statusnumberHTTP status code
errorDetailsunknownFull response body from the server
js
import { PinoramaError } from "pinorama-client"

try {
  await client.search({ term: "test" })
} catch (error) {
  if (error instanceof PinoramaError) {
    console.log(error.status, error.errorDetails)
  }
}

Retry Behavior

Only insert() uses automatic retry with exponential backoff. After maxRetries attempts, a PinoramaError is thrown.

Retry sequence with default options
AttemptWait Time
1st (initial)immediate
2nd (retry 1)1,000 ms
3rd (retry 2)2,000 ms
4th (retry 3)4,000 ms
5th (retry 4)8,000 ms

The wait time is always capped at backoffMax.

Platform Support

Pinorama Client works in both Node.js and the browser with the same API.

Node.js

js
import { PinoramaClient } from "pinorama-client"
// or explicitly:
import { PinoramaClient } from "pinorama-client/node"

Browser

js
import { PinoramaClient } from "pinorama-client/browser"

The browser build is an ESM module that uses window.setTimeout instead of Node.js timers/promises.