Usage
Initialize
Kino.init() is called once, at startup. A second call throws an error, and log methods throw until it has been called.
import Kino from '@fca.gg/kino';
Kino.init({
locale: 'en-GB',
defaultIntanceTitle: 'BOT',
});
locale(default:'en-US'): language of the date format on each line.defaultIntanceTitle(default:'GLOBAL'): name of the global logger. The option really is spelled this way, without an "s".sentry,packages,ANR,autoCaptureUnhandledRejections: see Sentry.
Levels
Each level writes to the matching console output, with its own color:
log(cyan) andsuccess(green):console.log;info(white):console.info;warn(yellow):console.warn;error(red):console.error;debug(blue):console.debug.
Each line is prefixed with the date, the module and the level:
[24/09/2026, 18:02:11 - Commands - WARN] Unknown command: /pnig
Methods accept several values: each one is written on its own line, and objects are printed in detail (three levels deep).
Kino.warn('Unexpected response', {status: 429, retryAfter: 2});
Global logger and per-module loggers
Static methods use the global logger:
Kino.info('Connected to the gateway');
Kino.error(new Error('Connection failed'));
To know where a line comes from, create one logger per module. Its name replaces the global logger's in the prefix, and is used as the module tag in Sentry:
const logger = new Kino('Database');
logger.debug('Query ran in 12 ms');
KinoLoggedClass
A class that extends KinoLoggedClass gets a protected logger property, named after the class, available in static and instance methods alike:
import {KinoLoggedClass} from '@fca.gg/kino';
class TicketManager extends KinoLoggedClass {
public open(userId: string) {
this.logger.info(`Ticket opened for ${userId}`); // module "TicketManager"
}
public static cleanup() {
this.logger.warn('Cleaning up expired tickets');
}
}
The logger is created on first access, then shared by the whole class.
Errors
error() writes the error and, when Sentry is configured, sends it with the module as a tag. A second argument adds context:
logger.error(error, {
tags: {command: 'ban'},
extras: {guildId: interaction.guildId},
user: {id: interaction.user.id, username: interaction.user.username},
});
Trace an operation
trace(uid) returns a function to use as an error handler. It sends the error with a trace_uid tag, so you can find every error of the same operation in Sentry:
const onError = logger.trace(interaction.id, {tags: {command: 'ban'}});
await member.ban().catch(onError);
The static version, Kino.trace(uid), takes no context.