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 🙏

© 2026 – Pkg Stats / Ryan Hefner

observoo-sdk

v3.0.0

Published

SDK oficial do Observoo para captura de erros e monitoramento em Node.js e browser

Readme

@observoo/sdk

SDK oficial do Observoo para captura de erros e monitoramento de aplicações — Node.js e browser.

Instalação

npm install @observoo/sdk
# ou
bun add @observoo/sdk

Início rápido

Modo global

Inicialize uma vez na entrada da aplicação e use as funções globais em qualquer lugar:

import * as Observoo from '@observoo/sdk';

Observoo.init({ sdkKey: process.env.OBSERVOO_SDK_KEY! });

// capturar exceção
try {
  await processarPagamento(pedido);
} catch (error) {
  Observoo.captureException(error);
}

// capturar mensagem
Observoo.captureMessage('Pagamento aprovado', { level: 'info' });

Modo instância (mais controle)

import { ObservooClient } from '@observoo/sdk';

const observoo = new ObservooClient({ sdkKey: process.env.OBSERVOO_SDK_KEY! });

observoo.captureException(new Error('algo deu errado'));

Configuração

// Mínimo necessário — só a SDK key do ambiente
Observoo.init({ sdkKey: process.env.OBSERVOO_SDK_KEY! });

// Opções avançadas
Observoo.init({
  sdkKey: process.env.OBSERVOO_SDK_KEY!,

  /** Versão da aplicação — aparece nos detalhes do evento */
  release: process.env.npm_package_version,

  /** Captura automaticamente uncaughtException / window.onerror. Padrão: true */
  autoCapture: true,

  /** Máximo de breadcrumbs mantidos. Padrão: 100 */
  maxBreadcrumbs: 100,

  /** Tentativas de reenvio em falha de rede. Padrão: 3 */
  retries: 3,

  /** Delay base entre tentativas em ms. Padrão: 500 */
  retryDelay: 500,
});

O ambiente é determinado pela SDK key. Cada SDK key é gerada para um ambiente específico (production, staging, dev) nas configurações do projeto — não é necessário informá-lo no init().

Request context

Quando estiver dentro de um servidor HTTP, você pode anexar headers e cookies da requisição ao contexto do SDK:

Observoo.setRequestHeaders(request.headers);
Observoo.setRequestCookies(request.headers.get('cookie') ?? '');

Esses valores passam a ser incluídos nos eventos subsequentes até o contexto ser substituído.


Captura de erros

captureException(error, context?)

Captura qualquer Error (ou valor desconhecido) com stack trace parseado automaticamente:

try {
  const dados = await buscarUsuario(id);
} catch (error) {
  Observoo.captureException(error, {
    requestUrl: '/api/users/' + id,
    requestMethod: 'GET',
    fingerprint: 'buscar-usuario-erro',
    tags: { modulo: 'usuarios' },
  });
}

captureMessage(message, context?)

Registra uma mensagem com nível definido:

Observoo.captureMessage('Limite de taxa atingido', {
  level: 'warning',
  tags: { endpoint: '/api/checkout' },
});

Scope — identificação e contexto

Defina uma vez, aplica a todos os eventos subsequentes:

// Identificar o usuário logado
Observoo.setUser({
  id: 'usr_123',
  email: '[email protected]',
  nome: 'João Silva',
});

// Tags de indexação
Observoo.setTag('plano', 'premium');
Observoo.setTag('regiao', 'br-south');

// Dados extras
Observoo.setExtra('configuracoes', { tema: 'escuro', idioma: 'pt-BR' });

Ou passando contexto direto no captureException / captureMessage:

Observoo.captureException(error, {
  level: 'error',
  fingerprint: 'checkout-pagamento-nulo',
  tags: { modulo: 'checkout' },
  extra: { pedidoId: 'ord_8421', valorTotal: 149.9 },
});

logger — interface compatível com Sentry

O SDK exporta um objeto logger com a mesma assinatura do Sentry.logger, facilitando a migração:

import * as Observoo from '@observoo/sdk';

Observoo.init({ sdkKey: process.env.OBSERVOO_SDK_KEY! });

// Drop-in replacement para Sentry.logger
Observoo.logger.info('Usuário autenticado', { userId: 'usr_123' });
Observoo.logger.warn('Tentativa de acesso negada', { ip: '1.2.3.4', rota: '/admin' });
Observoo.logger.error('Falha ao processar pagamento', { pedidoId: 'ord_8421' });
Observoo.logger.debug('Cache miss', { chave: 'produto:456' });
Observoo.logger.fatal('Banco de dados inacessível', { host: 'db.interno' });

Substituição direta do Sentry

// Antes (Sentry)
import * as Sentry from '@sentry/bun';

logger.info = (message, context) => {
  console.info('[INFO]', message, context ?? '');
  if (isSentryEnabled()) Sentry.logger.info(message, context);
};

// Depois (Observoo — mesma assinatura)
import * as Observoo from '@observoo/sdk';

logger.info = (message, context) => {
  console.info('[INFO]', message, context ?? '');
  Observoo.logger.info(message, context);
};

Wrapper de log com Observoo (padrão recomendado)

// lib/logger.ts
import * as Observoo from '@observoo/sdk';

function isObservooEnabled() {
  return !!process.env.OBSERVOO_SDK_KEY;
}

export const logger = {
  info(message: string, context?: Record<string, unknown>) {
    console.info('[INFO]', message, context ?? '');
    if (isObservooEnabled()) Observoo.logger.info(message, context);
  },
  warn(message: string, context?: Record<string, unknown>) {
    console.warn('[WARN]', message, context ?? '');
    if (isObservooEnabled()) Observoo.logger.warn(message, context);
  },
  error(message: string, context?: Record<string, unknown>) {
    console.error('[ERROR]', message, context ?? '');
    if (isObservooEnabled()) Observoo.logger.error(message, context);
  },
  debug(message: string, context?: Record<string, unknown>) {
    if (process.env.NODE_ENV !== 'production') {
      console.debug('[DEBUG]', message, context ?? '');
    }
    if (isObservooEnabled()) Observoo.logger.debug(message, context);
  },
  fatal(message: string, context?: Record<string, unknown>) {
    console.error('[FATAL]', message, context ?? '');
    if (isObservooEnabled()) Observoo.logger.fatal(message, context);
  },
};

Inicialização no Bun / Node

// lib/observoo.ts
import * as Observoo from '@observoo/sdk';

export function initObservoo() {
  const sdkKey = process.env.OBSERVOO_SDK_KEY;
  if (!sdkKey) return;

  Observoo.init({ sdkKey });
}

export { Observoo };
// index.ts (entrada da aplicação)
import { initObservoo } from './lib/observoo';

initObservoo();

Breadcrumbs

Registre eventos que antecederam o erro para facilitar a depuração:

Observoo.addBreadcrumb({
  type: 'navigation',
  message: '→ /checkout/finalizar',
  level: 'info',
});

Observoo.addBreadcrumb({
  type: 'http',
  message: 'GET /api/carrinho · 200 · 84ms',
  level: 'info',
});

Observoo.addBreadcrumb({
  type: 'http',
  message: 'POST /api/pagamento · 500 · 320ms',
  level: 'error',
  data: { statusCode: 500, endpoint: '/api/pagamento' },
});

// o erro capturado a seguir incluirá todos os breadcrumbs acima
Observoo.captureException(new Error('Pagamento falhou'));

Exemplos práticos

Express — middleware de erros

import express from 'express';
import * as Observoo from '@observoo/sdk';

Observoo.init({ sdkKey: process.env.OBSERVOO_SDK_KEY! });

const app = express();

app.use((req, _res, next) => {
  Observoo.addBreadcrumb({
    type: 'http.request',
    message: `${req.method} ${req.path}`,
    level: 'info',
  });
  next();
});

// Middleware de erro no final
app.use((error: Error, req: express.Request, res: express.Response, _next: express.NextFunction) => {
  Observoo.captureException(error, {
    requestUrl: req.originalUrl,
    requestMethod: req.method,
    extra: { body: req.body, params: req.params },
  });
  res.status(500).json({ error: 'Erro interno do servidor' });
});

Next.js — instrumentation.ts

// instrumentation.ts (na raiz do projeto)
import * as Observoo from '@observoo/sdk';

export function register() {
  Observoo.init({
    sdkKey: process.env.OBSERVOO_SDK_KEY!,
    release: process.env.npm_package_version, // opcional
  });
}

Next.js — captura em Server Actions

'use server';
import * as Observoo from '@observoo/sdk';

export async function finalizarPedido(pedidoId: string) {
  try {
    const resultado = await processarPagamento(pedidoId);
    return resultado;
  } catch (error) {
    Observoo.captureException(error, {
      tags: { acao: 'finalizar-pedido' },
      extra: { pedidoId },
    });
    throw error;
  }
}

React — Error Boundary

import { Component, type ReactNode } from 'react';
import * as Observoo from '@observoo/sdk';

export class ErrorBoundary extends Component<
  { children: ReactNode; fallback: ReactNode },
  { hasError: boolean }
> {
  state = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error: Error) {
    Observoo.captureException(error, {
      requestUrl: window.location.href,
      tags: { componente: 'ErrorBoundary' },
    });
  }

  render() {
    if (this.state.hasError) return this.props.fallback;
    return this.props.children;
  }
}

Variáveis de ambiente

# .env
OBSERVOO_SDK_KEY=sua-sdk-key-do-ambiente
OBSERVOO_ENDPOINT=https://api.observoo.com   # opcional se usar o padrão

Onde encontrar a SDK key? Acesse Projeto → Configurações → SDK Keys no painel do Observoo e gere uma chave para o ambiente desejado (production, staging, dev).


Compatibilidade

| Ambiente | Versão mínima | |---|---| | Node.js | 18+ (necessário fetch nativo) | | Bun | 1.0+ | | Browsers modernos | Chrome 99+, Firefox 99+, Safari 15.4+ |

Em Node.js < 18, instale um polyfill de fetch como node-fetch e atribua a globalThis.fetch antes de init().

Licença

MIT