observoo-sdk
v3.0.0
Published
SDK oficial do Observoo para captura de erros e monitoramento em Node.js e browser
Maintainers
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/sdkIní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ãoOnde 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
fetchcomonode-fetche atribua aglobalThis.fetchantes deinit().
Licença
MIT
