npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@webdevarif/logs

v1.0.3

Published

A comprehensive logging package for tracking activities across websites with customizable log levels, storage adapters, and real-time monitoring

Readme

@webdevarif/logs

A comprehensive, dynamic logging package for tracking activities across websites with customizable log levels, storage adapters, and real-time monitoring.

Features

  • 🎯 Dynamic & Customizable: Pass any data with logs, use across any website
  • 📊 Multiple Log Levels: Debug, Info, Warn, Error, Critical
  • 🗂️ Categorized Logging: Auth, User, API, Database, Payment, Notification, System, Security, Performance, Custom
  • 💾 Flexible Storage: In-memory, File system, Database adapters
  • Real-time Monitoring: Live log updates via event system
  • 🔍 Advanced Filtering: Search by level, category, user, date range, tags
  • 📈 Statistics & Analytics: Comprehensive log statistics and insights
  • 🎨 React Integration: Hooks for easy React integration
  • 🔄 Batch Processing: Efficient batch logging with configurable intervals
  • 🛡️ Error Handling: Robust error handling with retry logic
  • 📤 Export Support: Export logs in JSON or CSV format

Installation

npm install @webdevarif/logs
# or
pnpm add @webdevarif/logs
# or
yarn add @webdevarif/logs

Quick Start

Basic Usage

import { createLogsService, InMemoryLogStorage } from '@webdevarif/logs';

// Create logs service
const logsService = createLogsService({
  storage: new InMemoryLogStorage(),
  enableConsole: true,
  enableStorage: true
});

// Log different levels
await logsService.info('user', 'login', 'User logged in successfully', {
  userId: '123',
  ipAddress: '192.168.1.1',
  metadata: { browser: 'Chrome', version: '91.0' }
});

await logsService.error('api', 'create', 'Failed to create user', {
  userId: '123',
  error: new Error('Database connection failed'),
  metadata: { endpoint: '/api/users', method: 'POST' }
});

await logsService.warn('payment', 'update', 'Payment method expired', {
  userId: '123',
  tags: ['payment', 'expired']
});

React Integration

import { useLogs, useLogInfo, useLogError } from '@webdevarif/logs';

function MyComponent() {
  const { logs, loading, createLog } = useLogs({
    service: logsService,
    autoRefresh: true
  });

  const logInfo = useLogInfo(logsService);
  const logError = useLogError(logsService);

  const handleUserAction = async () => {
    try {
      // Your business logic
      await someApiCall();
      
      // Log success
      await logInfo('user', 'update', 'User profile updated successfully', {
        userId: '123',
        metadata: { fields: ['name', 'email'] }
      });
    } catch (error) {
      // Log error
      await logError('user', 'update', 'Failed to update user profile', {
        userId: '123',
        error: error as Error,
        metadata: { fields: ['name', 'email'] }
      });
    }
  };

  return (
    <div>
      {loading ? 'Loading...' : (
        <div>
          <h2>Recent Logs</h2>
          {logs.map(log => (
            <div key={log.id}>
              [{log.level}] {log.message} - {log.timestamp.toISOString()}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

Database Integration (Prisma)

import { PrismaClient } from '@prisma/client';
import { DatabaseLogStorage } from '@webdevarif/logs';

class PrismaLogStorage extends DatabaseLogStorage {
  constructor(private prisma: PrismaClient) {
    super();
  }

  async save(log: LogEntry): Promise<void> {
    await this.prisma.log.create({
      data: {
        id: log.id,
        timestamp: log.timestamp,
        level: log.level,
        category: log.category,
        action: log.action,
        message: log.message,
        userId: log.userId,
        sessionId: log.sessionId,
        ipAddress: log.ipAddress,
        userAgent: log.userAgent,
        metadata: log.metadata,
        tags: log.tags,
        source: log.source,
        duration: log.duration,
        status: log.status,
        error: log.error
      }
    });
  }

  // Implement other methods...
}

// Usage
const prisma = new PrismaClient();
const logsService = createLogsService({
  storage: new PrismaLogStorage(prisma)
});

API Middleware Integration

import { createLogFromApiRequest } from '@webdevarif/logs';

// Express middleware
app.use((req, res, next) => {
  const startTime = Date.now();
  
  res.on('finish', async () => {
    const duration = Date.now() - startTime;
    
    const logData = createLogFromApiRequest(
      req.method,
      req.url,
      res.statusCode,
      duration,
      req.user?.id,
      {
        userAgent: req.get('User-Agent'),
        ip: req.ip,
        headers: req.headers
      }
    );
    
    await logsService.createLog(
      logData.level,
      logData.category,
      logData.action,
      logData.message,
      {
        userId: logData.userId,
        duration: logData.duration,
        metadata: logData.metadata,
        status: logData.status
      }
    );
  });
  
  next();
});

Next.js API Route Integration

// pages/api/users/route.ts
import { logsService } from '@/lib/logs';

export async function POST(request: Request) {
  try {
    const data = await request.json();
    
    // Your business logic
    const user = await createUser(data);
    
    // Log success
    await logsService.info('user', 'create', 'User created successfully', {
      userId: user.id,
      metadata: { email: user.email, role: user.role }
    });
    
    return Response.json(user);
  } catch (error) {
    // Log error
    await logsService.error('user', 'create', 'Failed to create user', {
      error: error as Error,
      metadata: { requestData: data }
    });
    
    return Response.json({ error: 'Failed to create user' }, { status: 500 });
  }
}

Configuration Options

interface LogConfig {
  storage: LogStorageAdapter;           // Storage adapter
  defaultLevel?: LogLevel;              // Default log level
  enableConsole?: boolean;              // Enable console logging
  enableStorage?: boolean;              // Enable storage logging
  enableRealTime?: boolean;             // Enable real-time events
  maxRetries?: number;                  // Max retry attempts
  retryDelay?: number;                  // Retry delay in ms
  batchSize?: number;                   // Batch size for bulk operations
  flushInterval?: number;               // Flush interval in ms
  enableCompression?: boolean;          // Enable log compression
  enableEncryption?: boolean;          // Enable log encryption
  encryptionKey?: string;              // Encryption key
  customFields?: Record<string, any>;   // Custom fields to add to all logs
}

Log Levels

  • debug: Detailed information for debugging
  • info: General information about application flow
  • warn: Warning messages for potential issues
  • error: Error messages for handled exceptions
  • critical: Critical errors that require immediate attention

Log Categories

  • auth: Authentication and authorization
  • user: User-related activities
  • api: API requests and responses
  • database: Database operations
  • payment: Payment processing
  • notification: Notification sending
  • system: System-level operations
  • security: Security-related events
  • performance: Performance monitoring
  • custom: Custom application events

Log Actions

  • create, read, update, delete: CRUD operations
  • login, logout, register, verify, reset: Auth actions
  • upload, download, export, import: File operations
  • send, receive, connect, disconnect: Communication
  • start, stop, pause, resume: Process control
  • custom: Custom actions

Storage Adapters

InMemoryLogStorage

  • Fast, temporary storage
  • Perfect for development and testing
  • Data lost on restart

FileSystemLogStorage

  • Persistent file-based storage
  • Good for single-instance applications
  • Configurable file path

DatabaseLogStorage (Abstract)

  • Extend for your database
  • Supports Prisma, MongoDB, etc.
  • Persistent and scalable

Utility Functions

import {
  getLogLevelColor,
  getLogLevelIcon,
  formatLogEntry,
  formatDuration,
  filterLogsByQuery,
  groupLogsByDate,
  getLogSummary,
  createLogFromError,
  createLogFromApiRequest
} from '@webdevarif/logs';

// Get UI colors and icons
const color = getLogLevelColor('error'); // '#EF4444'
const icon = getLogLevelIcon('warn');    // '⚠️'

// Format logs for display
const formatted = formatLogEntry(log);
const duration = formatDuration(1500); // '1.50s'

// Filter and group logs
const filtered = filterLogsByQuery(logs, 'user');
const grouped = groupLogsByDate(logs);
const summary = getLogSummary(logs);

// Create logs from common scenarios
const errorLog = createLogFromError(error, 'api', 'create');
const apiLog = createLogFromApiRequest('POST', '/api/users', 201, 150);

Real-time Events

// Subscribe to real-time log events
const unsubscribe = logsService.subscribe((event) => {
  switch (event.type) {
    case 'log_created':
      console.log('New log:', event.data);
      break;
    case 'log_batch':
      console.log('Batch of logs:', event.data);
      break;
    case 'log_deleted':
      console.log('Log deleted:', event.data);
      break;
  }
});

// Unsubscribe when done
unsubscribe();

Statistics and Analytics

const stats = await logsService.getStats({
  startDate: new Date('2024-01-01'),
  endDate: new Date('2024-01-31')
});

console.log(stats);
// {
//   totalLogs: 1500,
//   logsByLevel: { debug: 100, info: 800, warn: 200, error: 50, critical: 5 },
//   logsByCategory: { auth: 200, user: 300, api: 800, ... },
//   averageDuration: 150.5,
//   errorRate: 3.67,
//   topUsers: [{ userId: '123', count: 50 }, ...],
//   topTags: [{ tag: 'payment', count: 25 }, ...]
// }

Export and Search

// Export logs
const jsonExport = await logsService.exportLogs({ userId: '123' }, 'json');
const csvExport = await logsService.exportLogs({ level: 'error' }, 'csv');

// Search logs
const searchResults = await logsService.searchLogs('payment failed', {
  category: 'payment',
  startDate: new Date('2024-01-01')
});

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For support, email [email protected] or create an issue on GitHub.