Documentation

Get started with EdgeLogs

The simplest, Next.js-native logging & error monitoring SDK — edge-safe, zero dependencies

Edge-Safe

Works in Vercel Edge, Cloudflare Workers, and all edge runtimes

Zero Dependencies

Tiny bundle size (<5KB minified) with no external dependencies

TypeScript First

Full type safety out of the box with comprehensive TypeScript support

Installation

Install EdgeLogs using your preferred package manager:

npm install edgelogs
# or
yarn add edgelogs
# or
pnpm add edgelogs

Quick Start

Method 1: Logger Instance

Recommended

Create a logger instance with your API key. Import and use it anywhere in your app.

Step 1: Create a logger file

// lib/logger.ts
import { init } from 'edgelogs';

export const logger = init({
  apiKey: process.env.EDGE_LOGS_API_KEY!,
});

Step 2: Use anywhere in your app

// anywhere in your app
import { logger } from '@/lib/logger';

logger.info('User signed up', { userId, plan: 'starter' });
logger.warn('Rate limit hit', { userId, endpoint });
logger.error(err, { route: '/api/checkout' });

Method 2: Instrumentation Hook

Auto-runs via Next.js instrumentation hook. Use the global log export.

Step 1: Create instrumentation.ts (Next.js 15+)

// instrumentation.ts
import { init } from "edgelogs";

export function register() {
  init({
    apiKey: process.env.EDGE_LOGS_API_KEY!,
  });
}

Step 2: Use the global log export

import { log } from "edgelogs";

log.info("User logged in", { userId: 123 });
log.warn("Rate limit approaching", { userId: 456 });
log.error(err, { orderId, userId });

Configuration

Customize EdgeLogs behavior with these configuration options:

OptionTypeDefaultDescription
apiKeystringRequiredYour EdgeLogs API key
endpointstringedgelogs.dev/api/ingestLog ingestion endpoint
enabledbooleantrueEnable/disable logging
batchSizenumber10Logs to batch before flush
flushIntervalnumber5000Auto-flush interval (ms)
debugbooleanfalseEnable debug console output

API Reference

log.info(message, context?)

Log an informational message.

log.info("Server started", { 
  port: 3000, 
  env: "production" 
});

log.warn(message, context?)

Log a warning message.

log.warn("Slow query detected", { 
  query: "SELECT *", 
  duration: 2500 
});

log.error(error, context?)

Log an error with automatic stack trace capture.

try {
  throw new Error("Payment failed");
} catch (err) {
  log.error(err, { 
    userId: 123, 
    orderId: "ord_abc" 
  });
}

log.debug(message, context?)

Log a debug message.

log.debug("Cache miss", { 
  key: "user:123" 
});

log.flush()

Manually flush all buffered logs immediately.

await log.flush();

Examples

Next.js App Router (API Route)

// app/api/checkout/route.ts
import { logger } from "@/lib/logger";

export async function POST(request: Request) {
  const body = await request.json();

  logger.info("Checkout started", { 
    userId: body.userId, 
    items: body.items.length 
  });

  try {
    const result = await processCheckout(body);
    logger.info("Checkout completed", { 
      orderId: result.orderId 
    });
    return Response.json(result);
  } catch (error) {
    logger.error(error, { 
      userId: body.userId 
    });
    return Response.json(
      { error: "Checkout failed" }, 
      { status: 500 }
    );
  }
}

Server Actions

// app/actions.ts
"use server";

import { logger } from "@/lib/logger";

export async function updateProfile(formData: FormData) {
  const userId = formData.get("userId");

  try {
    await db.users.update(userId, { 
      name: formData.get("name") 
    });
    logger.info("Profile updated", { userId });
  } catch (error) {
    logger.error(error, { userId, action: "updateProfile" });
    throw error;
  }
}

Edge Middleware

// middleware.ts
import { logger } from "@/lib/logger";
import { NextResponse } from "next/server";

export function middleware(request: Request) {
  const traceId = crypto.randomUUID();
  logger.setTraceId(traceId);

  logger.info("Request received", {
    path: request.url,
    method: request.method,
  });

  const response = NextResponse.next();
  response.headers.set("X-Trace-ID", traceId);

  return response;
}

Best Practices

1

Initialize once

Call init() in instrumentation.ts or at app startup

2

Use trace IDs

Set trace IDs in middleware for request correlation across your application

3

Add context

Include relevant metadata (userId, orderId, etc.) to make debugging easier

4

Handle errors

Always log errors with context for effective debugging and monitoring

5

Flush on exit

Call log.flush() before serverless function exits