Skip to main content

Real-Time Log

The Blong framework ships with a real-time log viewer. When the framework is running locally, a log server is available at http://127.0.0.1:9998. All queries use a REST API.

Quick Reference

# 20 most recent entries
curl -s 'http://127.0.0.1:9998/api/entries?limit=20' | jq '.entries[]'

# Errors only
curl -s 'http://127.0.0.1:9998/api/entries?level=error&limit=10' | jq '.entries[]'

# Full-text search
curl -s 'http://127.0.0.1:9998/api/search?search=connection+refused' | jq '.entries[]'

# Filter by service name
curl -s 'http://127.0.0.1:9998/api/entries?name=gateway&limit=20' | jq '.entries[]'

# Trace a request across services
curl -s 'http://127.0.0.1:9998/api/entries?traceId=abc-123' | jq '.entries[]'

REST API

GET /api/entries

Returns the most recent log entries. Supports filtering.

ParameterTypeDescription
levelstringMinimum log level: trace, debug, info, warn, error, fatal
namestringService name (substring match, case-insensitive)
traceIdstringExact trace ID match
searchstringFree-text search across all properties
afterstringReturn only entries after this ULID (pagination)
limitnumberMax entries to return (default: 200)

GET /api/search

Same as /api/entries but searches the full buffer instead of just recent entries.

GET /api/config

Returns server configuration including recognised property names. Useful for discovering available filter fields.

Common Workflows

Check for errors after a code change

curl -s 'http://127.0.0.1:9998/api/entries?level=error&limit=5' \
| jq '.entries[] | {msg, name, err: .err.message}'

Monitor a specific service

curl -s 'http://127.0.0.1:9998/api/entries?name=orchestrator&limit=30' \
| jq '.entries[] | {levelName, msg}'

Verify an API call

# By method name
curl -s 'http://127.0.0.1:9998/api/search?search=userUserAdd' \
| jq '.entries[] | {levelName, msg, name}'

Trace a request through services

# Find the trace ID
TRACE=$(curl -s 'http://127.0.0.1:9998/api/entries?search=transfer&limit=1' \
| jq -r '.entries[0].traceId')

# All logs for that trace
curl -s "http://127.0.0.1:9998/api/entries?traceId=$TRACE" \
| jq '.entries[] | {name, levelName, msg}'

Poll for new entries

LAST_ID=$(curl -s 'http://127.0.0.1:9998/api/entries?limit=1' \
| jq -r '.entries[-1].id')

# Later, get only new entries
curl -s "http://127.0.0.1:9998/api/entries?after=$LAST_ID" \
| jq '.entries[] | {levelName, msg}'

Log Entry Properties

PropertyTypeDescription
idstringULID — monotonically increasing, sortable
timenumberUnix timestamp in milliseconds
levelnumberPino level: 10=trace 20=debug 30=info 40=warn 50=error 60=fatal
levelNamestringHuman-readable level name
msgstringLog message
namestringService/module name
traceIdstringDistributed trace ID
errobjectError details: {message, stack, type}
reqobjectHTTP request: {method, url, headers, body}
resobjectHTTP response: {statusCode, headers, responseTime}
$metaobjectBlong framework metadata: {mtid, method, …}

Runtime Introspection Endpoints

For inspecting the framework's internal state (registered ports, handlers, config), enable the systemDebug endpoints in the suite's server.ts (dev only — never in production):

config: {
dev: {
gateway: {debug: true}, // include stack traces in error responses
systemDebug: {enabled: true}, // expose /api/sys/* endpoints
},
}
EndpointReturns
GET /api/sys/configEffective merged runtime configuration
GET /api/sys/portsAll registered adapter/orchestrator port names
GET /api/sys/methodsAll handler method groups with handler counts
GET /api/sys/modulesAll registered realm module names
GET /api/sys/rpcInternal RPC server address

Typical troubleshooting workflow

# Is the expected port registered?
curl -s http://localhost:8080/api/sys/ports | jq '.ports[]'

# Are the expected handlers present?
curl -s http://localhost:8080/api/sys/methods \
| jq '.methods[] | select(.name | contains("myRealm"))'

# What is the effective config?
curl -s http://localhost:8080/api/sys/config | jq '.myRealm.myAdapter'

# Correlate with logs
curl -s 'http://127.0.0.1:9998/api/entries?level=error&limit=10' \
| jq '.entries[] | {msg, name}'

Implementation

The log viewer lives in core/blong-log/. It exposes a React LogViewer component (used in the browser) and a server that stores log entries forwarded from Pino.

For more on the design rationale see rationale/real-time-log.