Skip to main content

Overview

The logger module provides configured logger instances using consola for consistent logging throughout the application. It includes package name tagging and log level control.

Exports

logger

Application logger instance with package name tag.
export const logger: ConsolaInstance
The logger provides methods for different log levels:
logger.silent()
function
Silent logging (level 0)
logger.warn()
function
Warning messages (level 1)
logger.log()
function
General log messages (level 2)
logger.info()
function
Informational messages (level 3)
logger.debug()
function
Debug messages (level 4)
logger.trace()
function
Trace messages (level 5)
import { logger } from 'ccusage/logger';

logger.info('Loading usage data...');
logger.debug('Processing file:', filePath);
logger.warn('Missing cost data, using fallback');
logger.error('Failed to load file:', error);

log

Direct console.log function for cases where logger formatting is not desired.
export const log: typeof console.log
Use log when you need plain output without logger formatting, such as for JSON output or raw data display.
import { log } from 'ccusage/logger';
import { loadDailyUsageData } from 'ccusage/data-loader';

const data = await loadDailyUsageData();

// Output raw JSON without logger formatting
log(JSON.stringify(data, null, 2));

Log Levels

Control logging verbosity with the LOG_LEVEL environment variable:
LevelValueMethods Shown
Silent0None
Warn1warn, error, fatal
Log2log + above
Info3info + above (default)
Debug4debug + above
Trace5trace + all
# Silent mode (no logs)
LOG_LEVEL=0 ccusage daily

# Warnings only
LOG_LEVEL=1 ccusage daily

# Debug mode
LOG_LEVEL=4 ccusage daily

# Trace mode (maximum verbosity)
LOG_LEVEL=5 ccusage daily

Usage Patterns

Development vs Production

import { logger } from 'ccusage/logger';

// Verbose logging for development
logger.debug('Starting data load...');
logger.debug('Found files:', files.length);
logger.debug('Processing file:', file);
logger.info('Data loaded successfully');

Progress Tracking

import { logger } from 'ccusage/logger';

const files = await globUsageFiles(claudePaths);
logger.info(`Processing ${files.length} files...`);

for (let i = 0; i < files.length; i++) {
  logger.debug(`Processing file ${i + 1}/${files.length}:`, files[i].file);
  await processFile(files[i]);
}

logger.info('All files processed successfully');

Error Context

import { logger } from 'ccusage/logger';

try {
  const data = await loadSessionUsageById(sessionId);
  if (!data) {
    logger.warn('Session not found:', sessionId);
    return null;
  }
  return data;
} catch (error) {
  logger.error('Failed to load session:', {
    sessionId,
    error: error instanceof Error ? error.message : String(error)
  });
  throw error;
}

Integration Examples

CLI Commands

import { logger, log } from 'ccusage/logger';
import { loadDailyUsageData } from 'ccusage/data-loader';

export async function dailyCommand(options: Options) {
  logger.info('Loading daily usage data...');
  
  const data = await loadDailyUsageData({
    since: options.since,
    until: options.until,
    mode: options.mode
  });
  
  logger.debug(`Loaded ${data.length} days`);
  
  if (options.json) {
    // Use log for raw JSON output
    log(JSON.stringify(data, null, 2));
  } else {
    // Use logger for formatted output
    logger.info('Daily Usage Report');
    // ... render table ...
  }
}

Library Usage

import { logger } from 'ccusage/logger';
import { loadDailyUsageData } from 'ccusage/data-loader';
import { calculateTotals } from 'ccusage/calculate-cost';

export async function analyzeUsage(projectName: string) {
  logger.info('Starting usage analysis for:', projectName);
  
  const data = await loadDailyUsageData({
    project: projectName,
    groupByProject: true
  });
  
  if (data.length === 0) {
    logger.warn('No usage data found for project:', projectName);
    return null;
  }
  
  logger.debug('Data loaded:', {
    days: data.length,
    firstDate: data[0]?.date,
    lastDate: data[data.length - 1]?.date
  });
  
  const totals = calculateTotals(data);
  
  logger.info('Analysis complete:', {
    project: projectName,
    totalCost: totals.totalCost,
    avgCostPerDay: totals.totalCost / data.length
  });
  
  return { data, totals };
}

Best Practices

Never use console.log directly in ccusage code. Always use logger for formatted output or log for raw output.

When to Use Each Level

  • trace: Very detailed debugging, variable values
  • debug: Detailed flow information, file processing
  • info: General progress updates, completion messages
  • log: Standard output, user-facing messages
  • warn: Non-critical issues, fallback behaviors
  • error: Errors that prevent operation

Logger vs Log

  • Use logger: For application messages, progress updates, errors
  • Use log: For JSON output, tables, raw data that shouldn’t be formatted
import { logger } from 'ccusage/logger';

logger.info('Processing complete');
logger.debug('Found', items.length, 'items');
logger.warn('Missing optional field:', field);

Build docs developers (and LLMs) love