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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@useflytrap/logs

v0.0.18

Published

Instant Stripe-level observability for your Next.js project

Downloads

43

Readme

Flytrap Logs

npm version npm downloads Github Actions

Open-source full-stack error monitoring for Next.js apps

Flytrap Logs is a full-stack error monitoring tool, that monitors your Server Actions, Route Handlers & React components, alerts you when your system health is degraded, and provides you context from tools and libraries you use such as Prisma, Drizzle, Supabase, Auth.js to help you fix bugs & outages faster. Read more →

Flytrap Logs is under active development. Flytrap Logs is an ongoing effort to build a much more developer friendly error monitoring and debugging experience. Some features are not yet built. Open an issue or join our Discord to suggest features and follow our progress. Check out our Roadmap →

Features

  • Monitors Server-rendered pages, API Routes, Server Actions & React components. Learn more →
  • Saves context from libraries you use (eg. Prisma, Drizzle, Supabase, Stripe, Auth.js) to make debugging easier. Learn more →
  • Type-safe structured canonical logging Learn more →
  • Encryption for log data Learn more →

⚡️ Quickstart

  1. Install the Flytrap Logs SDK
$ npm install @useflytrap/logs
  1. Install the Next.js plugin
$ npm install -D @useflytrap/logs-transform
  1. Add the plugin to next.config.js
const { nextjs } = require('@useflytrap/logs-transform')

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: nextjs({
    // 👈 plugin options here
  })
}

module.exports = nextConfig
  1. Create a logging file (logging.ts)

In your logging file, you can codify your logs with TypeScript, enable encryption, configure the log API endpoints and more.

🚨 Remember to export all the functions as shown below

import { PermissionedApiKey } from "@/types"
import { createFlytrapLogger } from "@useflytrap/logs"

export type AdditionalLogContext = {
  team_id: string
  project_id: string
  auth_type: "api_key" | "dashboard"
  permissions_used: PermissionedApiKey["permissions"]
  build_id: string
  key_id: string
}

export const {
  addContext,
  flushAsync,
  flush,
  catchUncaughtAction,
  catchUncaughtRoute,
  response,
  nextResponse,
  json,
  nextJson,
  redirect,
  nextRedirect,
  parseJson,
  parseText,
} = createFlytrapLogger<AdditionalLogContext>({
  publicKey:
    "pk_MIIBI...",
  encryption: {
    enabled: true,
  },
})

Your code-base will now automatically emit log data from Server-rendered pages, API routes, Server Actions & React components.

Try making a request, and you should see requests & server actions get logged in the console. If you want to send them to an API, you can change the flushMethod to 'api' in your logging.ts, and define logsEndpoint with your API endpoint.

You can manually add context to your log data using the addContext function like this:

const apiKey = assertApiKey(headers())
addContext({
  auth_type: "api_key",
  key_id: apiKey.id,
})

📈 Monitoring Server-rendered pages, API Routes, Server Actions & React components

The Flytrap Logs code-transform automatically wraps your SSR pages, API routes, Server Actions & React components to capture errors that happen in them. It also automatically gathers useful context that can be used when fixing bugs.

What context is automatically captured

  • SSR pages: request headers, params, duration, path, status code, uncaught errors
  • API routes: request & response payload, request & response headers, duration, path, status code, uncaught errors
  • Server Actions: input data, response object, headers, duration, path, status code, uncaught errors
+ import { catchUncaughtPage } from "./lib/logging"

- export default function Home() {}
+ export default catchUncaughtPage(function Home() {}, {
+  path: "/"
+})

Notes

  • The catchUncaughtPage doesn't affect the runtime nature of your code at all, if bubbles any caught errors up, so error boundaries work perfectly.
  • Only React Server Component pages are transformed.
+ import { catchUncaughtRoute } from "@/lib/logging"

- export function GET() {}
+ export const GET = catchUncaughtRoute(function GET() {}, {
+  path: "/"
+})

Notes

  • The catchUncaughtRoute doesn't affect the runtime nature of your code at all, it bubbles any caught errors up
  • Only React Server Component pages are transformed.

🛠️ Automatic context from your tools

The worst thing that can happen when trying to fix a bug is not having enough context. Because of this, Flytrap logs automatically adds context from your libraries such as Prisma, Drizzle, Supabase, Auth.js, Stripe & more, so when you have enough context when fixing bugs.

Here's an example to illustrate how context gets added to an Auth.js call on the server side:

import { auth } from "@/lib/auth"
+ import { addContext } from "@/lib/logging"

export async function getCurrentUser() {
  const session = await auth()

+  if (session) {
+    addContext({
+      'auth.js': {
+        user_id: session.user.id,
+        user_email: session.user.email
+      }
+    })
+  }

  return session?.user
}

Boom! Now your bug reports will automatically contain the authenticated user.

Here's another example with Supabase:

import { auth } from "@/lib/auth"
+ import { addContext } from "@/lib/logging"

export async function findUserById(userId: string) {
  const session = await auth()

  const { data: { users }, error } = await supabase.auth.admin.listUsers()

+ if (error) {
+   addContext({
+     'supabase': { error } // 👈 error context saved automatically
+   })
+ }
+ addContext({
+   'supabase': {
+     'supabase.auth.admin.listUsers()': users // 👈 fetched users saved to make bug-fixing easier
+   }
+ })

  return users.find(({ id }) => id === userId)
}

🪵 Type-safe canonical logging

Canonical logging is a way of doing structured logging at scale, popularized by Stripe, where each action produces one log line, which contains all the necessary context to fix bugs, associate log lines with users, API keys or organizations, monitor latencies and more.

It's a really good way to handle logs and easy to work with and extend. You can use TypeScript to make your canonical logs fully type-safe.

Here's an example:

import { PermissionedApiKey } from "@/types"
import { createFlytrapLogger } from "@useflytrap/logs"

export type AdditionalLogContext = {
  team_id: string
  project_id: string
  auth_type: "api_key" | "dashboard"
  permissions_used: PermissionedApiKey["permissions"]
  build_id: string
  key_id: string
}

export const {
  getContext,
  addContext,
  flush,
  flushAsync,
  catchUncaughtAction,
  catchUncaughtRoute,
  response,
  nextResponse,
  json,
  nextJson,
  redirect,
  nextRedirect,
  parseJson,
  parseText,
} = createFlytrapLogger<AdditionalLogContext>({
  publicKey:
    "pk_MIIBI...",
  vercel: {
    enabled: true,
  },
  encryption: {
    enabled: true,
  },
})

Here we're adding keys such as team_id, key_id, build_id, permissions_used so we can easily find logs filtered by team, API key and more.

To manually add this context to our canonical log lines during execution of Server Actions or API Routes, we can use the addContext function.

import { addContext, json } from "@/lib/logging"
import { db } from "@/lib/db"
import { Err, Ok } from "ts-results"

async function assertUserInTeam(teamId: string, userId: string) {
  const team = await db.teamMember.count({
    where: {
      teamId,
      userId,
    },
  })

  if (team === 0) {
    return Err(
      json(
        {
          message: `You're trying to access resources for team with ID "${teamId}" without having access to it.`,
        },
        { status: 401 }
      )
    )
  }
  addContext({
    team_id: teamId,
  })
  return Ok(true)
}

🔐 Encryption for log data

To enable encryption for log data, simply add encryption.enabled to true in your logging.ts file, and your public key as the publicKey key. This uses the public key to encrypt the log data.

By default, keys req, req_headers, res, res_headers & error are encrypted. If you want to add other keys to encrypt, simply add them to the encryption.encryptKeys key as an array:

export const {
  // ... omitted for brevity
} = createFlytrapLogger<AdditionalLogContext>({
  publicKey:
    "pk_MIIBI...",
  vercel: {
    enabled: true,
  },
  encryption: {
    enabled: true,
    encryptKeys: ['api_key', 'user_id', 'user_email']
  },
})

🐛 Sending data to Flytrap Logs Dashboard

If you want automatically set-up dashboards for your Route Handlers, Server Actions that look like this 👇, you can integrate our Logs SDK with the Flytrap Logs Dashboard.

| | | | |:-------------------------:|:-------------------------:|:-------------------------:| | | || | | || ||||

  1. Sign up on Flytrap
  2. Create a project, select the "Logs" product during the onboarding
  3. Create your logging.ts file, and add the publicKey from your onboarding there.
  4. Set the flushMethod in your logging.ts file to 'api'

🚧 Roadmap

TODO!

💻 Development

  • Clone this repository
  • Enable Corepack using corepack enable (use npm i -g corepack for Node.js < 16.10)
  • Install dependencies using pnpm install
  • Run the tests using pnpm dev

License

Made with ❤️ in Helsinki, Finland.

Published under MIT License.