Skip to content

Slogger Examples

GitHub Actions edited this page Aug 15, 2026 · 3 revisions

Slogger Examples

Common usage patterns and real-world examples.

Deno Bun Node.js

Table of Contents

Basic Examples

Simple Console Logging

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'SimpleApp',
  level: SyslogSeverities.INFO,
  handlers: [{
    name: 'console',
    type: 'ConsoleHandler',
    level: SyslogSeverities.INFO,
    formatter: 'standard',
  }],
});

logger.info('Application started');
logger.debug('Debug message'); // Won't be logged (below INFO)
logger.error('Something went wrong', { error: 'connection timeout' });

File Logging

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'FileApp',
  level: SyslogSeverities.INFO,
  handlers: [{
    name: 'file',
    type: 'FileHandler',
    level: SyslogSeverities.INFO,
    directory: './logs',
    filenameTemplate: 'app.log',
    maxFileSizeBytes: 50 * 1024 * 1024,
    formatter: 'json',
  }],
});

logger.info('User logged in', { userId: '12345', ip: '192.168.1.1' });

Multiple Handlers

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'MultiApp',
  level: SyslogSeverities.DEBUG,
  handlers: [
    {
      name: 'console',
      type: 'ConsoleHandler',
      level: SyslogSeverities.DEBUG,
      formatter: 'detailed',
    },
    {
      name: 'file',
      type: 'FileHandler',
      level: SyslogSeverities.INFO,
      directory: './logs',
      filenameTemplate: 'app.log',
      formatter: 'json',
    },
    {
      name: 'errors',
      type: 'FileHandler',
      level: SyslogSeverities.ERROR,
      directory: './logs',
      filenameTemplate: 'errors.log',
      formatter: 'detailed',
    },
  ],
});

Web Application

HTTP Server with Request Logging

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
import { serve } from 'https://deno.land/std/http/server.ts';

const logger = new Slogger({
  appName: 'WebApp',
  level: SyslogSeverities.INFO,
  handlers: [
    {
      name: 'console',
      type: 'ConsoleHandler',
      level: SyslogSeverities.INFO,
      formatter: 'standard',
    },
    {
      name: 'requests',
      type: 'FileHandler',
      level: SyslogSeverities.INFO,
      directory: './logs',
      filenameTemplate: 'requests-${date}.log',
      formatter: 'json',
    },
  ],
});

serve(async (request) => {
  const start = performance.now();
  const url = new URL(request.url);

  try {
    // Log incoming request
    logger.info('Request received', {
      method: request.method,
      path: url.pathname,
      userAgent: request.headers.get('user-agent'),
    });

    // Handle request (example)
    const response = new Response('Hello World');

    // Log response
    const duration = performance.now() - start;
    logger.info('Request completed', {
      method: request.method,
      path: url.pathname,
      status: response.status,
      duration: Math.round(duration),
    });

    return response;
  } catch (error) {
    // Log error
    logger.error('Request failed', {
      method: request.method,
      path: url.pathname,
      error: (error as Error).message,
      stack: (error as Error).stack,
    });

    return new Response('Internal Server Error', { status: 500 });
  }
}, { port: 8000 });

logger.info('Server started', { port: 8000 });

Middleware Logging

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'API',
  level: SyslogSeverities.INFO,
  handlers: [{
    name: 'file',
    type: 'FileHandler',
    level: SyslogSeverities.INFO,
    directory: './logs',
    filenameTemplate: 'api-${date}.log',
    formatter: 'json',
  }],
});

type Handler = (request: Request) => Promise<Response>;

function loggingMiddleware(handler: Handler): Handler {
  return async (request: Request) => {
    const requestId = crypto.randomUUID();
    const start = performance.now();

    logger.info('Request started', {
      requestId,
      method: request.method,
      url: request.url,
    });

    try {
      const response = await handler(request);
      const duration = performance.now() - start;

      logger.info('Request completed', {
        requestId,
        status: response.status,
        duration: Math.round(duration),
      });

      return response;
    } catch (error) {
      const duration = performance.now() - start;

      logger.error('Request failed', {
        requestId,
        error: (error as Error).message,
        duration: Math.round(duration),
      });

      throw error;
    }
  };
}

API Server

REST API with Structured Logging

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'RestAPI',
  level: SyslogSeverities.INFO,
  handlers: [
    {
      name: 'console',
      type: 'ConsoleHandler',
      level: SyslogSeverities.DEBUG,
      formatter: 'detailed',
    },
    {
      name: 'requests',
      type: 'FileHandler',
      level: SyslogSeverities.INFO,
      directory: './logs',
      filenameTemplate: 'requests.log',
      formatter: 'json',
    },
    {
      name: 'errors',
      type: 'HTTPHandler',
      level: SyslogSeverities.ERROR,
      url: 'https://logs.example.com/api/errors',
      batchSize: 10,
      headers: {
        'Authorization': `Bearer ${Deno.env.get('LOG_API_KEY')}`,
      },
      formatter: 'json',
    },
  ],
});

declare function fetchUserFromDatabase(
  userId: string,
): Promise<{ username: string } | undefined>;

// API endpoint example
async function handleUser(userId: string) {
  logger.debug('Fetching user', { userId });

  try {
    const user = await fetchUserFromDatabase(userId);

    if (!user) {
      logger.warning('User not found', { userId });
      return new Response('Not Found', { status: 404 });
    }

    logger.info('User fetched successfully', {
      userId,
      username: user.username,
    });

    return new Response(JSON.stringify(user), {
      headers: { 'Content-Type': 'application/json' },
    });
  } catch (error) {
    logger.error('Failed to fetch user', {
      userId,
      error: (error as Error).message,
      stack: (error as Error).stack,
    });

    return new Response('Internal Server Error', { status: 500 });
  }
}

Database Query Logging

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'Database',
  level: SyslogSeverities.DEBUG,
  handlers: [{
    name: 'queries',
    type: 'FileHandler',
    level: SyslogSeverities.INFO,
    directory: './logs',
    filenameTemplate: 'queries-${date}.log',
    formatter: 'json',
    sampling: {
      sampleRate: 0.1, // Sample 10% of queries
      bypassSamplingForLevel: SyslogSeverities.WARNING,
    },
  }],
});

declare const db: {
  query(sql: string, params?: unknown[]): Promise<unknown[]>;
};

async function executeQuery(sql: string, params?: unknown[]) {
  const queryId = crypto.randomUUID();
  const start = performance.now();

  logger.debug('Query started', () => ({
    queryId,
    sql,
    params,
  }));

  try {
    const result = await db.query(sql, params);
    const duration = performance.now() - start;

    logger.debug('Query completed', {
      queryId,
      duration: Math.round(duration),
      rowCount: result.length,
    });

    // Log slow queries
    if (duration > 1000) {
      logger.warning('Slow query detected', () => ({
        queryId,
        sql,
        params,
        duration: Math.round(duration),
      }));
    }

    return result;
  } catch (error) {
    const duration = performance.now() - start;

    logger.error('Query failed', {
      queryId,
      sql,
      error: (error as Error).message,
      duration: Math.round(duration),
    });

    throw error;
  }
}

Microservice

Microservice with Distributed Tracing

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'PaymentService',
  level: SyslogSeverities.INFO,
  handlers: [
    {
      name: 'console',
      type: 'ConsoleHandler',
      level: SyslogSeverities.INFO,
      formatter: 'standard',
    },
    {
      name: 'distributed',
      type: 'HTTPHandler',
      level: SyslogSeverities.INFO,
      url: 'https://jaeger.example.com/api/logs',
      batchSize: 50,
      formatter: 'json',
    },
  ],
});

declare function validatePayment(paymentId: string): Promise<void>;
declare function callPaymentGateway(
  paymentId: string,
): Promise<{ id: string; status: string }>;

async function processPayment(
  paymentId: string,
  traceId: string,
  spanId: string,
) {
  logger.info('Payment processing started', {
    paymentId,
    traceId,
    spanId,
    service: 'PaymentService',
  });

  try {
    // Validate payment
    logger.debug('Validating payment', { paymentId, traceId, spanId });
    await validatePayment(paymentId);

    // Process with external gateway
    logger.info('Calling payment gateway', {
      paymentId,
      traceId,
      spanId,
      gateway: 'Stripe',
    });
    const result = await callPaymentGateway(paymentId);

    // Log success
    logger.info('Payment processed successfully', {
      paymentId,
      traceId,
      spanId,
      result: result.status,
      transactionId: result.id,
    });

    return result;
  } catch (error) {
    logger.error('Payment processing failed', {
      paymentId,
      traceId,
      spanId,
      error: (error as Error).message,
      errorCode: (error as { code?: string }).code,
    });

    throw error;
  }
}

CLI Application

Interactive CLI with Progress Logging

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'CLI-Tool',
  level: SyslogSeverities.INFO,
  handlers: [
    {
      name: 'console',
      type: 'ConsoleHandler',
      level: SyslogSeverities.INFO,
      formatter: 'minimalist', // Clean output for CLI
    },
    {
      name: 'debug-file',
      type: 'FileHandler',
      level: SyslogSeverities.DEBUG,
      directory: './logs',
      filenameTemplate: 'cli-debug.log',
      formatter: 'detailed',
    },
  ],
});

declare function processFile(file: string): Promise<void>;

async function processFiles(files: string[]) {
  logger.info(`Processing ${files.length} files...`);

  for (let i = 0; i < files.length; i++) {
    const file = files[i];

    logger.debug(`Processing file ${i + 1}/${files.length}`, { file });

    try {
      await processFile(file);
      logger.info(`✓ Processed ${file}`);
    } catch (error) {
      logger.error(`✗ Failed to process ${file}`, {
        file,
        error: (error as Error).message,
      });
    }
  }

  logger.info('Processing complete');
}

Testing

Test Environment Logger

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

// Create logger that doesn't output during tests
export function createTestLogger(appName: string = 'TestApp') {
  return new Slogger({
    appName,
    level: SyslogSeverities.ERROR, // Only errors
    handlers: [{
      name: 'blackhole',
      type: 'BlackholeHandler',
      level: SyslogSeverities.INFO,
    }],
  });
}

// Or capture logs for assertions
export function createCapturingLogger(appName: string = 'TestApp') {
  const logs: string[] = [];

  const logger = new Slogger({
    appName,
    level: SyslogSeverities.DEBUG,
    handlers: [{
      name: 'capture',
      type: 'ConsoleHandler',
      level: SyslogSeverities.INFO,
      formatter: (log) => {
        const formatted = JSON.stringify(log);
        logs.push(formatted);
        return formatted;
      },
    }],
  });

  return { logger, logs };
}

// Use in tests
Deno.test('should log errors', () => {
  const { logger, logs } = createCapturingLogger();

  logger.error('Test error', { code: 500 });

  if (logs.length !== 1) throw new Error('expected exactly one log line');
  if (!logs[0].includes('Test error')) throw new Error('message missing');
  if (!logs[0].includes('500')) throw new Error('context missing');
});

Monitoring Integration

Datadog Integration

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'MonitoredApp',
  level: SyslogSeverities.INFO,
  handlers: [
    {
      name: 'console',
      type: 'ConsoleHandler',
      level: SyslogSeverities.INFO,
      formatter: 'standard',
    },
    {
      name: 'datadog',
      type: 'HTTPHandler',
      level: SyslogSeverities.INFO,
      url: `https://http-intake.logs.datadoghq.com/v1/input/${
        Deno.env.get('DD_API_KEY')
      }`,
      batchSize: 100,
      headers: {
        'Content-Type': 'application/json',
        'DD-API-KEY': Deno.env.get('DD_API_KEY')!,
      },
      formatter: 'json',
    },
  ],
});

// Log with Datadog-specific tags
logger.info('Application started', {
  env: Deno.env.get('ENV'),
  version: Deno.env.get('APP_VERSION'),
  host: Deno.hostname(),
});

Grafana Loki Integration

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';
import type { SlogObject } from '@tundralibs/slogger';

// Custom Loki formatter
function lokiFormatter(log: SlogObject): string {
  return JSON.stringify({
    streams: [{
      stream: {
        app: log.appName,
        level: log.levelName,
        hostname: log.hostname,
      },
      values: [[
        `${log.timestamp}000000`, // Nanosecond timestamp
        log.message,
      ]],
    }],
  });
}

const logger = new Slogger({
  appName: 'LokiApp',
  level: SyslogSeverities.INFO,
  handlers: [{
    name: 'loki',
    type: 'HTTPHandler',
    level: SyslogSeverities.INFO,
    url: 'https://loki.example.com/loki/api/v1/push',
    batchSize: 50,
    headers: {
      'Content-Type': 'application/json',
    },
    formatter: lokiFormatter,
  }],
});

Prometheus Metrics from Logs

import { Slogger, SyslogSeverities } from '@tundralibs/slogger';

const logger = new Slogger({
  appName: 'MetricsApp',
  level: SyslogSeverities.INFO,
  handlers: [{
    name: 'console',
    type: 'ConsoleHandler',
    level: SyslogSeverities.INFO,
    formatter: 'json',
  }],
});

// Log metrics that can be scraped by Prometheus
function recordMetric(
  name: string,
  value: number,
  labels?: Record<string, string>,
) {
  logger.info('metric', {
    metric_name: name,
    metric_value: value,
    metric_type: 'gauge',
    ...labels,
  });
}

// Usage
recordMetric('http_requests_total', 1, { method: 'GET', status: '200' });
recordMetric('response_time_ms', 45, { endpoint: '/api/users' });

Related Documentation


← Back to Slogger

Clone this wiki locally