@slackgram/logger
v1.0.17
Published
TypeScript-first logger for Node.js with file rotation and webhook support for Discord/Slack/Telegram
Maintainers
Readme
@slackgram/logger
@slackgram/logger is a modern, dependency‑free, TypeScript‑first logging system that works in Node.js and can be bundled into browser/front‑end apps. It provides colorful, human‑friendly logs in development and structured JSON logs in production, with optional file logging and real‑time tracking via Slack / Telegram (and Discord) webhooks/bots.
Features
- Dependency‑free: Uses only built‑in Node APIs when available.
- Log levels:
debug,info,warn,error. - Optional emojis and colored console output.
- Timestamps by default (ISO 8601 with milliseconds).
- File logging (Node.js):
- Configurable path.
- Rotation:
"1H","1D","1W". - Retention by max number of files.
- Buffered, async, non‑blocking writes.
- Optional pretty JSON lines.
- Hooks system:
- Discord / Slack / Telegram integrations.
- Hook thresholds via
hooks.minLevel. - Fire asynchronously; failures are swallowed (best‑effort).
- Pretty formatting:
- Objects / arrays via safe
JSON.stringify. Error→ stack.BigInt→"123n".- Node
Buffer→"<Buffer length=...>".
- Objects / arrays via safe
- Convenience utilities:
log.time(label, asyncFn)→ times async code.log.group()/log.groupEnd()for indentation‑based grouping.log.tag("HTTP")to create tagged child loggers.
- Environment aware:
development→ colorful text logs.production→ one JSON object per console line.
Installation
Add the files to your project (or publish to npm and install from there):
pnpm add @slackgram/logger
# or
npm install @slackgram/logger
# or
yarn add @slackgram/loggerIf using this repo directly, just reference the entry file in your imports (e.g. ./src/index).
Basic usage
import log, { config } from '@slackgram/logger';
config({
env: 'development',
minLevel: 'info',
debug: true,
});
log.info('Server started on port', 3000);
log.warn('Cache miss for key', 'user:123');
log.error('Unexpected error', new Error('boom'));
log.debug('Raw payload', { foo: 'bar' });Tagging
import log, { tag } from '@slackgram/logger';
const httpLog = tag('HTTP');
httpLog.info('GET /users', { userId: 42 });
httpLog.error('Request failed', new Error('timeout'));Timing async work
await log.time('user.fetch', async () => {
// some async work
});This will emit debug‑level logs like:
⏱️ user.fetch - start⏱️ user.fetch - done in 37ms
Grouping logs
log.group('Processing batch #1');
log.info('Step 1');
log.info('Step 2');
log.groupEnd();In development this adds indentation to grouped logs to make them visually distinct.
File logging (Node.js)
import log, { config } from '@slackgram/logger';
config({
file: {
enabled: true,
filePath: 'logs/app.log',
rotation: {
strategy: '1D', // rotate daily
maxFiles: 7, // keep last 7
},
flushIntervalMs: 2000,
prettyJson: true,
},
});File logging is no‑op in browser environments; it only activates when a Node‑like process.cwd() is available.
You can force a flush (for example, before process exit):
await log.flush();Webhook hooks (Discord, Slack, Telegram)
import { config } from '@slackgram/logger';
config({
hooks: {
minLevel: 'error', // only trigger on error and above
discord: {
enabled: true,
webhookUrl: 'https://discord.com/api/webhooks/...',
},
slack: {
enabled: true,
webhookUrl: 'https://hooks.slack.com/services/...',
},
telegram: {
enabled: true,
botToken: 'BOT_TOKEN',
chatId: 'CHAT_ID',
},
},
});Hooks are fired asynchronously and are best‑effort; network/HTTP errors are ignored so logging never blocks your application.
Setting hooks via environment variables
Keep webhook URLs and tokens out of code by using environment variables. In Node.js, read process.env when calling config():
import { config } from '@slackgram/logger';
config({
hooks: {
minLevel: process.env.MB_LOG_HOOK_LEVEL || 'warn',
discord: {
enabled: !!process.env.DISCORD_WEBHOOK_URL,
webhookUrl: process.env.DISCORD_WEBHOOK_URL || '',
},
slack: {
enabled: !!process.env.SLACK_WEBHOOK_URL,
webhookUrl: process.env.SLACK_WEBHOOK_URL || '',
},
telegram: {
enabled: !!(process.env.TELEGRAM_BOT_TOKEN && process.env.TELEGRAM_CHAT_ID),
botToken: process.env.TELEGRAM_BOT_TOKEN || '',
chatId: process.env.TELEGRAM_CHAT_ID || '',
},
},
});Suggested env vars
| Variable | Used by | Description |
|----------|---------|-------------|
| DISCORD_WEBHOOK_URL | Discord | Incoming webhook URL from Discord server settings |
| SLACK_WEBHOOK_URL | Slack | Incoming webhook URL from Slack app (e.g. https://hooks.slack.com/services/...) |
| TELEGRAM_BOT_TOKEN | Telegram | Bot token from @BotFather |
| TELEGRAM_CHAT_ID | Telegram | Chat or group ID (e.g. from getUpdates after messaging the bot) |
| MB_LOG_HOOK_LEVEL | All | Minimum level to send to hooks: debug, info, warn, error (optional) |
| MB_LOGGER_TELEGRAM_API | Telegram | Override Telegram API base URL (optional, default https://api.telegram.org) |
Setting env vars when running
Windows (cmd):
set DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
set SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
set TELEGRAM_BOT_TOKEN=123456789:ABC...
set TELEGRAM_CHAT_ID=-1001234567890
set MB_LOG_HOOK_LEVEL=warn
node index.mjsWindows (PowerShell):
$env:DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
$env:SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
$env:TELEGRAM_BOT_TOKEN="123456789:ABC..."
$env:TELEGRAM_CHAT_ID="-1001234567890"
$env:MB_LOG_HOOK_LEVEL="warn"
node index.mjsLinux / macOS:
export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export TELEGRAM_BOT_TOKEN="123456789:ABC..."
export TELEGRAM_CHAT_ID="-1001234567890"
export MB_LOG_HOOK_LEVEL="warn"
node index.mjsOr use a .env file with a loader (e.g. dotenv) and load it before calling config(); never commit .env to version control.
Configuration reference
import type { LoggerConfig } from '@slackgram/logger';
const cfg: LoggerConfig = {
env: 'development', // 'development' | 'production' | 'test'
minLevel: 'info', // 'debug' | 'info' | 'warn' | 'error'
silent: false,
debug: false,
colors: true,
levels: {
debug: { enabled: true, emoji: '🐛' },
info: { enabled: true, emoji: 'ℹ️' },
warn: { enabled: true, emoji: '⚠️' },
error: { enabled: true, emoji: '⛔' },
},
file: {
enabled: true,
filePath: 'logs/app.log',
rotation: {
strategy: '1D', // '1H' | '1D' | '1W'
maxFiles: 7,
},
flushIntervalMs: 2000,
prettyJson: true,
},
hooks: {
minLevel: 'error',
discord: { enabled: true, webhookUrl: '' },
slack: { enabled: true, webhookUrl: '' },
telegram: { enabled: false, botToken: '', chatId: '' },
},
timestampFn: () => new Date().toISOString(),
};TypeScript & JavaScript
- In TypeScript, import from the package name or file path; types are defined in
types.tsand surfaced via the bundled declaration file. - In JavaScript, you can still import the default logger and call the same methods; you just won’t get static type checking unless your tooling reads
.d.tsfiles.
