Logging in Envio HyperIndex
Effective logging is essential for monitoring your indexer's performance, diagnosing issues, and gathering insights. The Envio indexer uses pino, a high-performance logging library for JavaScript. These logs can be integrated with analytics tools such as Kibana to generate metrics and visualizations.
Table of Contents
- User Logging - How to implement logging in your event handlers
- Configuration & Output Formats - Configuring log output and formats
- Log Levels - Understanding available log levels
- Troubleshooting - Common issues and solutions
Users
When implementing handlers for your indexer, use the logging functions provided in the context object. These functions allow you to record events and errors at different severity levels.
Available Logging Methods
<context>.log.debug
- For detailed debugging information<context>.log.info
- For general information about application flow<context>.log.warn
- For potentially problematic situations<context>.log.error
- For error events that might still allow the application to continue<context>.log.errorWithExn
- Same aserror
, but takes an exception as the first argument to include stacktraces and error messages in the log
Examples by Language
- JavaScript
- TypeScript
- ReScript
// Inside your handler
context.log.debug(
`Processing event with block hash: ${event.blockHash} (debug)`
);
context.log.info(`Processing event with block hash: ${event.blockHash} (info)`);
context.log.warn(`Potential issue with event: ${event.blockHash} (warn)`);
context.log.error(`Failed to process event: ${event.blockHash} (error)`);
context.log.errorWithExn(
new Error("Error processing event"),
`Failed to process event: ${event.blockHash}`
);
// You can also pass objects to logs for structured logging:
context.log.info({
msg: "Processing blockchain event",
type: "info",
extra: "Additional debugging context",
data: { blockHash: event.blockHash },
});
// Inside your handler
context.log.debug(
`Processing event with block hash: ${event.blockHash} (debug)`
);
context.log.info(`Processing event with block hash: ${event.blockHash} (info)`);
context.log.warn(`Potential issue with event: ${event.blockHash} (warn)`);
context.log.error(`Failed to process event: ${event.blockHash} (error)`);
context.log.errorWithExn(
new Error("Error processing event"),
`Failed to process event: ${event.blockHash}`
);
For structured logging with TypeScript, use the following pattern:
import Logs from "generated/src/Logs.bs.js";
// Inside your handler
Logs.debug(context.log, {
msg: "Processing blockchain event",
type: "debug",
data: { blockHash: event.blockHash },
});
Logs.info(context.log, {
msg: "Processing blockchain event",
type: "info",
data: { blockHash: event.blockHash },
});
Logs.warn(context.log, {
msg: "Potential issue with event",
type: "warn",
data: { blockHash: event.blockHash },
});
Logs.error(context.log, {
msg: "Failed to process event",
type: "error",
data: { blockHash: event.blockHash },
});
Logs.errorWithExn(context.log, new Error("Error in processing"), {
msg: "Failed to process event",
type: "error",
data: { blockHash: event.blockHash },
});
// Inside your handler
exception ExampleException(string) // Example of an exception
// Basic string logging
context.log.debug(`Processing event with block hash: ${event.blockHash} (debug)`)
context.log.info(`Processing event with block hash: ${event.blockHash} (info)`)
context.log.warn(`Potential issue with event: ${event.blockHash} (warn)`)
context.log.error(`Failed to process event: ${event.blockHash} (error)`)
context.log.errorWithExn(
ExampleException("Error processing event"),
`Failed to process event: ${event.blockHash}`,
)
For structured logging in ReScript (since records are strictly typed and not polymorphic):
// Structured logging with objects
context.log->Logs.debug({
"msg": "Processing blockchain event",
"type": "debug",
"data": {"blockHash": event.blockHash},
})
context.log->Logs.info({
"msg": "Processing blockchain event",
"type": "info",
"data": {"blockHash": event.blockHash},
})
context.log->Logs.warn({
"msg": "Potential issue with event",
"type": "warn",
"data": {"blockHash": event.blockHash},
})
context.log->Logs.error({
"msg": "Failed to process event",
"type": "error",
"data": {"blockHash": event.blockHash},
})
context.log->Logs.errorWithExn(
ExampleException("Error processing event"),
{
"msg": "Failed to process event",
"type": "error",
"data": {"blockHash": event.blockHash},
},
)
Metrics, Debugging, and Troubleshooting
The Envio indexer provides flexible logging configurations to suit different environments and use cases.
Output Formats
The default output format is human-readable with color-coded log levels (console-pretty
). You can modify the output format using environment variables:
# Available log strategies
LOG_STRATEGY="console-pretty" # Default: Human-readable logs with colors in terminal
LOG_STRATEGY="ecs-file" # ECS format logs to file (standard for Elastic Stack)
LOG_STRATEGY="ecs-console" # ECS format logs to console
LOG_STRATEGY="file-only" # Logs to file in Pino format (most efficient)
LOG_STRATEGY="console-raw" # Raw Pino format logs to console
LOG_STRATEGY="both-prettyconsole" # Pretty logs to console, Pino format to file
# Specify log file location when using file output
LOG_FILE="<path-to-log-file>"
For production environments or detailed analytics, consider integrating logs with Kibana or similar tools. We're developing Kibana dashboards for self-hosting and UI dashboards for our hosting solution. If you have specific dashboard requirements, please contact us on Discord.
Developer Logging
Log Levels
The indexer supports the following log levels in ascending order of severity:
- trace # Most verbose level, detailed tracing information
- debug # Debugging information for developers
- info # General information about system operation
- udebug # User-level debug logs
- uinfo # User-level info logs
- uwarn # User-level warning logs
- uerror # User-level error logs
- warn # System warning logs
- error # System error logs
- fatal # Critical errors causing system shutdown
Note: Log levels prefixed with
u
(likeudebug
) are user-level logs emitted from the context for handlers or loaders.
Configuring Log Levels
Set log levels using these environment variables:
LOG_LEVEL="info" # Controls log level for console output (default: "info")
FILE_LOG_LEVEL="trace" # Controls log level for file output (default: "trace")
Example:
export LOG_LEVEL="trace" # Set console log level to the most verbose option
Troubleshooting
When debugging issues in development:
-
Terminal UI Issues: The Terminal UI may sometimes hide errors. To disable it:
export TUI_OFF="true" # Or use --tui-off flag when starting
-
Log Visibility: To maintain the Terminal UI while capturing detailed logs:
export LOG_STRATEGY="both-prettyconsole"
export LOG_FILE="./debug.log"
This approach allows you to view essential information in the UI while capturing comprehensive logs for troubleshooting.