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

@spidey52/api-logs-sdk

v1.0.3

Published

TypeScript/JavaScript SDK for API logging service with Express and Hono middleware support

Readme

API Logs SDK - TypeScript/JavaScript

TypeScript SDK for the API logging service with Express and Hono middleware support, automatic batching, and user auto-creation.

Features

Framework Support - Express and Hono middleware included
Automatic Batching - Efficiently queues and sends logs in batches
User Auto-Creation - Automatically creates users if they don't exist
Type Safety - Full TypeScript support with type definitions
Retry Logic - Exponential backoff for failed requests
Configurable - Highly customizable batch size, intervals, etc.
Graceful Shutdown - Ensures no logs are lost on exit

Installation

npm install @spidey52/api-logs-sdk
# or
yarn add @spidey52/api-logs-sdk
# or
pnpm add @spidey52/api-logs-sdk

Quick Start

import { APILogsExporter } from "@spidey52/api-logs-sdk";

const exporter = new APILogsExporter({
 apiKey: "your-api-key-here",
 environment: "production",
 baseURL: "https://api-logs.example.com/api/v1",
 batchSize: 10,
 flushInterval: 5000,
 createUsers: true, // Auto-create users
});

// Log an API call with user info
await exporter.log({
 method: "GET",
 path: "/api/users",
 status_code: 200,
 response_time_ms: 45,
 user_identifier: "[email protected]",
 user_name: "John Doe",
});

Configuration Options

interface ExporterConfig {
 apiKey: string; // Required: Your API key
 environment?: "dev" | "production"; // Default: 'dev'
 baseURL?: string; // API logs service URL
 batchSize?: number; // Batch size (default: 10)
 flushInterval?: number; // Auto-flush interval in ms (default: 5000)
 enabled?: boolean; // Enable/disable logging (default: true)
 maxRetries?: number; // Max retry attempts (default: 3)
 retryDelay?: number; // Initial retry delay in ms (default: 1000)
 createUsers?: boolean; // Auto-create users (default: true)
}

User Auto-Creation

When createUsers: true (default), the SDK will automatically create users in your database when logging with user_identifier:

// User will be auto-created if doesn't exist
await exporter.log({
 method: "POST",
 path: "/api/orders",
 status_code: 201,
 response_time_ms: 156,
 user_identifier: "[email protected]", // Used to find/create user
 user_name: "Alice Smith", // Stored with user
});

Benefits:

  • No need to manually create users before logging
  • Seamless tracking across API calls
  • Automatic user discovery from API usage

How it works:

  1. SDK sends user_identifier and user_name in log
  2. Backend checks if user exists by identifier
  3. If not found, creates new user automatically
  4. Associates log with user ID

Manual Logging

// Simple log
await exporter.log({
 method: "GET",
 path: "/api/items",
 status_code: 200,
 response_time_ms: 45,
});

// With user info (auto-creates user)
await exporter.log({
 method: "POST",
 path: "/api/orders",
 status_code: 201,
 response_time_ms: 156,
 user_identifier: "[email protected]",
 user_name: "Bob Johnson",
});

// With full details
await exporter.log({
 method: "POST",
 path: "/api/products",
 status_code: 201,
 response_time_ms: 234,
 user_identifier: "[email protected]",
 user_name: "Admin User",
 request_headers: {
  "content-type": "application/json",
 },
 request_body: {
  name: "Product",
 },
 response_body: {
  id: "prod-123",
 },
});

Express Middleware

import express from "express";
import { APILogsExporter, createExpressMiddleware } from "@spidey52/api-logs-sdk";

const app = express();
const exporter = new APILogsExporter({
 apiKey: "your-api-key",
 createUsers: true,
});

// Add middleware
app.use(
 createExpressMiddleware(exporter, {
  captureRequestBody: true,
  captureResponseBody: true,
  captureHeaders: true,
  excludePaths: ["/health", "/metrics"],
  getUserInfo: (req) => ({
   user_identifier: req.user?.email,
   user_name: req.user?.name,
  }),
 }),
);

// Your routes automatically logged
app.get("/api/users", (req, res) => {
 res.json({ users: [] });
});

Hono Middleware

import { Hono } from "hono";
import { APILogsExporter, createHonoMiddleware } from "@spidey52/api-logs-sdk";

const app = new Hono();
const exporter = new APILogsExporter({
 apiKey: "your-api-key",
 createUsers: true,
});

// Add middleware
app.use(
 "*",
 createHonoMiddleware({
  exporter,
  captureRequestBody: true,
  captureResponseBody: true,
  captureHeaders: true,
  getUserInfo: (c) => ({
   user_identifier: c.req.header("x-user-email"),
   user_name: c.req.header("x-user-name"),
  }),
 }),
);

app.get("/api/users", (c) => c.json({ users: [] }));

Testing with Headers

You can pass user info via headers for testing:

curl http://localhost:3000/api/users \
  -H "X-User-Email: [email protected]" \
  -H "X-User-Name: Alice Smith"

Batching Behavior

Logs are sent in batches automatically:

  1. Batch Size Trigger: Queue reaches batchSize (default: 10)
  2. Time Trigger: Every flushInterval ms (default: 5000ms)
  3. Manual Trigger: Call flush() explicitly
  4. Shutdown Trigger: Call shutdown() before exit

Example:

const exporter = new APILogsExporter({
 apiKey: "key",
 batchSize: 5,
 flushInterval: 3000,
});

// These 5 logs sent together
for (let i = 0; i < 5; i++) {
 await exporter.log({
  /* log */
 });
} // Batch sent here!

// These sent after 3 seconds
await exporter.log({
 /* log 6 */
});
await exporter.log({
 /* log 7 */
});
// Auto-flushed after 3s

API Methods

log(entry: APILogEntry): Promise<void>

Add a log entry to the queue. Automatically batches and sends.

flush(): Promise<BatchResponse | null>

Immediately send all queued logs. Returns batch result with success/failure counts.

shutdown(): Promise<void>

Flush remaining logs and stop auto-flush timer. Always call before exiting!

getQueueSize(): number

Get current number of logs in the queue.

clearQueue(): void

Clear all queued logs (use with caution).

isEnabled(): boolean

Check if exporter is enabled.

setEnabled(enabled: boolean): void

Enable or disable the exporter dynamically.

getConfig(): object

Get current configuration (safe - masks API key).

Batch Response

When flushing, you get a response with results:

const result = await exporter.flush();
console.log(result);
// {
//   success_count: 8,
//   failed_count: 2,
//   total: 10,
//   errors: ['error msg 1', 'error msg 2']
// }

Best Practices

1. Graceful Shutdown

Always flush logs before exiting:

process.on("SIGINT", async () => {
 await exporter.shutdown();
 process.exit(0);
});

2. Error Handling

The SDK retries automatically, but you can monitor:

const result = await exporter.flush();
if (result && result.failed_count > 0) {
 console.warn("Some logs failed:", result.errors);
}

3. Performance Tuning

For high-traffic APIs:

const exporter = new APILogsExporter({
 batchSize: 50, // Larger batches
 flushInterval: 10000, // Less frequent flushes
 maxRetries: 5, // More retries
});

4. Privacy

Be careful with sensitive data:

createExpressMiddleware(exporter, {
 captureHeaders: false, // Don't capture auth headers
 captureRequestBody: false, // Don't capture passwords
 captureResponseBody: true,
});

5. User Tracking

For authenticated APIs:

app.use(
 createExpressMiddleware(exporter, {
  getUserInfo: (req) => {
   const token = req.headers.authorization;
   const user = decodeJWT(token); // Your auth logic

   return {
    user_identifier: user.email,
    user_name: user.displayName,
    user_id: user.id, // Optional: if you manage users separately
   };
  },
 }),
);

Development

# Install dependencies
npm install

# Build
npm run build

# Run examples
npm run example
npm run example:express

# Watch mode
npm run dev

# Test
npm test

Examples

See examples/ directory:

  • basic.ts - Manual logging with user auto-creation
  • express-app.ts - Express middleware with batching

Testing the Batch Endpoint

# Start your Go backend
cd ../../
make dev

# In another terminal, run the example
cd sdk/typescript
npm run example:express

# Test with curl
curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -H "X-User-Email: [email protected]" \
  -H "X-User-Name: Test User" \
  -d '{"name": "Test", "email": "[email protected]"}'

# Check exporter status
curl http://localhost:3000/api/exporter/status

# Manual flush
curl -X POST http://localhost:3000/api/exporter/flush

API Log Entry Fields

interface APILogEntry {
 // Required
 method: HTTPMethod;
 path: string;
 status_code: number;
 response_time_ms: number;

 // Optional - Connection info
 ip_address?: string;
 user_agent?: string;

 // Optional - User info (for auto-creation)
 user_id?: string; // If you manage users
 user_name?: string; // Display name
 user_identifier?: string; // Email or username (unique)

 // Optional - Headers & Bodies
 request_headers?: Record<string, any>;
 response_headers?: Record<string, any>;
 request_body?: Record<string, any>;
 response_body?: Record<string, any>;

 // Optional - Error info
 error_message?: string;
}

Troubleshooting

Logs not being sent

  1. Check API key is valid
  2. Verify backend URL is accessible
  3. Check queue size: exporter.getQueueSize()
  4. Manually flush: await exporter.flush()

Users not being created

  1. Ensure createUsers: true in config
  2. Provide both user_identifier and user_name
  3. Check backend logs for errors
  4. Verify user service is initialized

High memory usage

  1. Reduce batchSize or increase flushInterval
  2. Call flush() more frequently
  3. Check for long-running processes not shutting down

License

MIT

Support

For issues or questions, please open an issue on GitHub.