@jaquinones45/jaquilogs-sdk
v1.2.0
Published
SDK oficial de JaquiLogs - Cliente de logs, componentes React embebibles y dashboard analytics para monitoreo de aplicaciones
Maintainers
Readme
@jaquinones45/jaquilogs-sdk
SDK oficial de JaquiLogs - Plataforma de monitoreo y gestión de logs.
Incluye:
- Cliente SDK para enviar logs desde cualquier aplicación Node.js/Browser
- Componentes React embebibles con dashboard, tabla de logs y gráficos
- Hooks de React Query para consumo de datos
- Sistema de temas y labels completamente personalizable
- Soporte i18n (Español e Inglés)
Instalación
# Con pnpm
pnpm add @jaquinones45/jaquilogs-sdk
# Con npm
npm install @jaquinones45/jaquilogs-sdk
# Con yarn
yarn add @jaquinones45/jaquilogs-sdkPeer Dependencies (solo si usas componentes React)
pnpm add react react-dom @tanstack/react-query recharts1. Cliente SDK (Enviar Logs)
El cliente funciona en cualquier entorno JavaScript (Node.js, Browser, Edge Functions). No requiere React.
Configuración Básica
import { createClient } from "@jaquinones45/jaquilogs-sdk";
const logger = createClient({
apiKey: "tu-api-key",
baseUrl: "https://api.jaquilogs.com", // Opcional, este es el default
applicationId: "app-id-opcional", // Se aplica a todos los logs
debug: true, // Logs de debug en consola
});Enviar Logs
// Método genérico
logger.log({
level: "INFO",
message: "Usuario autenticado exitosamente",
request_url: "/api/auth/login",
request_method: "POST",
status_code: 200,
response_time_ms: 45,
custom_fields: { user_id: "abc123", region: "latam" },
});
// Shortcuts por nivel
logger.success("Pago procesado", {
request_url: "/api/payments",
request_method: "POST",
status_code: 201,
response_time_ms: 320,
});
logger.error("Fallo en la base de datos", {
request_url: "/api/users",
request_method: "GET",
status_code: 500,
response_time_ms: 5000,
});
logger.warn("Rate limit alcanzado", {
request_url: "/api/search",
request_method: "GET",
status_code: 429,
response_time_ms: 12,
});
logger.info("Health check OK", {
request_url: "/health",
request_method: "GET",
status_code: 200,
response_time_ms: 3,
});
logger.debug("Cache miss para key users:list", {
request_url: "/api/users",
request_method: "GET",
status_code: 200,
response_time_ms: 150,
});Middleware Express
Loguea automáticamente todas las peticiones HTTP:
import express from "express";
import { createClient } from "@jaquinones45/jaquilogs-sdk";
const app = express();
const logger = createClient({ apiKey: "tu-api-key" });
// Agrega el middleware - ¡y listo!
app.use(logger.middleware());
app.get("/api/users", (req, res) => {
res.json({ users: [] });
// Se logueará automáticamente: GET /api/users 200
});Fetch Wrapper
Loguea automáticamente llamadas fetch:
const logger = createClient({ apiKey: "tu-api-key" });
// En lugar de fetch(), usa logger.fetch()
const response = await logger.fetch("https://api.example.com/data", {
method: "POST",
body: JSON.stringify({ query: "test" }),
});
// Se logueará automáticamente con level, status, response_timeBatching y Flush
Los logs se acumulan en batch y se envían periódicamente:
const logger = createClient({
apiKey: "tu-api-key",
batchSize: 50, // Flush automático al llegar a 50 logs
flushInterval: 5000, // O cada 5 segundos
maxRetries: 3, // Reintentos con backoff exponencial
timeout: 10000, // Timeout por request
});
// Flush manual
await logger.flush();
// Ver cuántos logs están en cola
console.log(logger.pendingCount);
// Destruir (flush + limpiar timer)
await logger.destroy();Leer Datos
// Obtener logs
const logs = await logger.getLogs({
level: "ERROR",
application_id: "mi-app",
limit: 100,
});
// Obtener un log específico
const log = await logger.getLog("log-id-aqui");
// Obtener estadísticas
const stats = await logger.getStats({
period: "day",
level: ["ERROR", "WARNING"],
});
// Obtener aplicaciones
const apps = await logger.getApplications();2. Componentes React
Setup: JaquiLogsProvider
Envuelve tu aplicación (o sección) con el provider:
import { JaquiLogsProvider } from "@jaquinones45/jaquilogs-sdk";
// O import más específico:
// import { JaquiLogsProvider } from "@jaquinones45/jaquilogs-sdk/react";
function App() {
return (
<JaquiLogsProvider
config={{
baseUrl: "https://api.jaquilogs.com",
apiKey: "tu-api-key",
locale: "es", // "es" | "en"
refreshInterval: 10000, // Polling cada 10s
labels: {
dashboardTitle: "Mi Panel de Monitoreo",
totalLogs: "Registros Totales",
// ... cualquier label que quieras personalizar
},
theme: {
primaryColor: "#6366f1",
mode: "dark",
borderRadius: 12,
levelColors: {
ERROR: "#ff0000",
},
},
}}
>
<MyDashboard />
</JaquiLogsProvider>
);
}Si ya usas React Query
Pasa tu propio QueryClient para evitar conflictos:
import { QueryClient } from "@tanstack/react-query";
const queryClient = new QueryClient();
<JaquiLogsProvider config={config} queryClient={queryClient}>
{children}
</JaquiLogsProvider>Dashboard Completo
El componente todo-en-uno con stats, gráficos y tabla:
import { JaquiLogsDashboard } from "@jaquinones45/jaquilogs-sdk";
function MonitorPage() {
return (
<JaquiLogsDashboard
title="Sistema de Monitoreo"
sections={["stats", "logsByLevel", "logsByHour", "recentLogs"]}
onLogClick={(log) => console.log("Log seleccionado:", log)}
/>
);
}Props disponibles:
| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| title | string | labels.dashboardTitle | Título del dashboard |
| sections | string[] | Todas | Secciones visibles |
| filters | DashboardStatsFilters | - | Filtros iniciales |
| onLogClick | (log) => void | - | Callback al hacer clic en un log |
| className | string | - | Clase CSS personalizada |
Secciones disponibles: stats, logsByLevel, logsByHour, logsByMethod, topUrls, recentLogs
Cards de Estadísticas
import { JaquiLogsStatsCards } from "@jaquinones45/jaquilogs-sdk";
<JaquiLogsStatsCards
cards={["totalLogs", "totalErrors", "avgResponseTime", "successRate"]}
filters={{ period: "day" }}
/>Cards disponibles: totalLogs, totalErrors, totalWarnings, applications, avgResponseTime, successRate, errorRate
Tabla de Logs
import { JaquiLogsTable } from "@jaquinones45/jaquilogs-sdk";
<JaquiLogsTable
searchable
level="ERROR"
limit={100}
columns={["timestamp", "level", "message", "statusCode", "responseTime"]}
maxHeight="500px"
onRowClick={(log) => openModal(log)}
/>Props:
| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| applicationId | string | - | Filtrar por app |
| level | LogLevel | - | Filtrar por nivel |
| limit | number | - | Máximo de logs |
| columns | string[] | Todas | Columnas visibles |
| searchable | boolean | false | Habilitar buscador |
| maxHeight | string | 600px | Altura máxima con scroll |
| onRowClick | (log) => void | - | Click en fila |
Gráficos
import { JaquiLogsChart } from "@jaquinones45/jaquilogs-sdk";
// Gráfico de barras por nivel
<JaquiLogsChart chartType="bar" dataKey="logsByLevel" height={300} />
// Gráfico de líneas por hora (tráfico)
<JaquiLogsChart chartType="line" dataKey="logsByHour" title="Tráfico por Hora" />
// Gráfico de torta por método HTTP
<JaquiLogsChart chartType="pie" dataKey="logsByMethod" />
// Top URLs con errores
<JaquiLogsChart chartType="bar" dataKey="topUrls" height={400} />Props:
| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| chartType | "bar" \| "line" \| "pie" | "bar" | Tipo de gráfico |
| dataKey | string | "logsByLevel" | Fuente de datos |
| title | string | Auto (i18n) | Título del gráfico |
| height | number | 300 | Altura en pixeles |
| filters | DashboardStatsFilters | - | Filtros |
dataKeys disponibles: logsByLevel, logsByMethod, logsByHour, logsByStatus, logsByApplication, topUrls, topApplicationsByLogCount
3. Hooks de React
Usa los hooks directamente para construir tus propios componentes:
import { useLogs, useDashboardStats, useApplications, useLog } from "@jaquinones45/jaquilogs-sdk";
function MyComponent() {
// Lista de logs con auto-refresh
const { data: logs, isLoading } = useLogs({
level: "ERROR",
application_id: "mi-app",
});
// Estadísticas del dashboard
const { data: stats } = useDashboardStats({
period: "day",
level: ["ERROR", "WARNING"],
});
// Aplicaciones
const { data: apps } = useApplications();
// Un log específico
const { data: log } = useLog("log-id");
return (
<div>
<p>Errores hoy: {stats?.totalErrors}</p>
<ul>
{logs?.map((log) => (
<li key={log.id}>{log.message}</li>
))}
</ul>
</div>
);
}4. Personalización
Labels / Títulos
Cambia cualquier texto visible en los componentes:
<JaquiLogsProvider
config={{
baseUrl: "...",
apiKey: "...",
labels: {
// Cambia el título del dashboard
dashboardTitle: "Centro de Control ACME Corp",
// Cambia los KPIs
totalLogs: "Registros del Sistema",
totalErrors: "Incidentes",
avgResponseTime: "Latencia Promedio",
// Cambia la tabla
logViewerTitle: "Historial de Eventos",
searchPlaceholder: "Buscar eventos...",
noLogsFound: "Sin eventos registrados",
// Cambia encabezados
timestamp: "Fecha",
message: "Descripción",
statusCode: "Estado HTTP",
responseTime: "Duración",
// Cambia gráficos
logsByLevel: "Eventos por Severidad",
logsByHour: "Volumen por Hora",
// Labels completamente custom
myCustomLabel: "Mi label personalizado",
},
}}
>Temas
// Tema claro personalizado
const miTema = {
mode: "light" as const,
primaryColor: "#0066cc",
backgroundColor: "#fafafa",
surfaceColor: "#ffffff",
textColor: "#1a1a1a",
borderRadius: 12,
fontFamily: "'Inter', sans-serif",
levelColors: {
SUCCESS: "#10b981",
INFO: "#0ea5e9",
WARNING: "#f59e0b",
ERROR: "#dc2626",
DEBUG: "#a855f7",
},
chartColors: ["#0066cc", "#10b981", "#f59e0b", "#dc2626", "#a855f7"],
};
// Tema oscuro
const temaOscuro = {
mode: "dark" as const,
primaryColor: "#818cf8",
backgroundColor: "#0f172a",
surfaceColor: "#1e293b",
textColor: "#f1f5f9",
borderColor: "#334155",
};
<JaquiLogsProvider config={{ ...config, theme: miTema }}>Idioma
// Español (default)
<JaquiLogsProvider config={{ ...config, locale: "es" }}>
// Inglés
<JaquiLogsProvider config={{ ...config, locale: "en" }}>
// Inglés con overrides específicos
<JaquiLogsProvider
config={{
...config,
locale: "en",
labels: { dashboardTitle: "My Custom Title" },
}}
>5. Ejemplos Completos
Next.js App
// app/monitoring/page.tsx
"use client";
import {
JaquiLogsProvider,
JaquiLogsDashboard,
} from "@jaquinones45/jaquilogs-sdk";
export default function MonitoringPage() {
return (
<JaquiLogsProvider
config={{
baseUrl: process.env.NEXT_PUBLIC_JAQUILOGS_URL!,
apiKey: process.env.NEXT_PUBLIC_JAQUILOGS_KEY!,
locale: "es",
theme: { mode: "dark", primaryColor: "#6366f1" },
labels: { dashboardTitle: "Monitor de Producción" },
}}
>
<div style={{ maxWidth: 1200, margin: "0 auto", padding: 24 }}>
<JaquiLogsDashboard
sections={["stats", "logsByLevel", "logsByHour", "recentLogs"]}
/>
</div>
</JaquiLogsProvider>
);
}React + Vite (Componentes Individuales)
import {
JaquiLogsProvider,
JaquiLogsStatsCards,
JaquiLogsChart,
JaquiLogsTable,
} from "@jaquinones45/jaquilogs-sdk";
function App() {
return (
<JaquiLogsProvider config={{ baseUrl: "...", apiKey: "...", locale: "es" }}>
<div className="grid gap-6 p-6">
{/* Solo los KPIs */}
<JaquiLogsStatsCards cards={["totalLogs", "totalErrors"]} />
{/* Un gráfico específico */}
<JaquiLogsChart
chartType="line"
dataKey="logsByHour"
title="Tráfico en tiempo real"
height={300}
/>
{/* Tabla de errores recientes */}
<JaquiLogsTable
level="ERROR"
searchable
columns={["timestamp", "message", "statusCode"]}
limit={20}
/>
</div>
</JaquiLogsProvider>
);
}Node.js Backend (Solo Cliente)
import { createClient } from "@jaquinones45/jaquilogs-sdk/client";
const logger = createClient({
apiKey: process.env.JAQUILOGS_API_KEY!,
applicationId: "backend-api",
});
// Express middleware
app.use(logger.middleware());
// En un catch de error
app.use((err, req, res, next) => {
logger.error(`Unhandled error: ${err.message}`, {
request_url: req.originalUrl,
request_method: req.method,
status_code: 500,
response_time_ms: 0,
custom_fields: { stack: err.stack },
});
res.status(500).json({ error: "Internal Server Error" });
});
// Cleanup al cerrar
process.on("SIGTERM", async () => {
await logger.destroy();
process.exit(0);
});6. Referencia de Tipos
// Niveles de log
type LogLevel = "SUCCESS" | "INFO" | "WARNING" | "ERROR" | "DEBUG";
// Métodos HTTP
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD";
// Períodos de tiempo
type Period = "minute" | "hour" | "day" | "week" | "quarter" | "semester" | "annual";
// Filtros de dashboard
interface DashboardStatsFilters {
period?: Period;
application_id?: string[];
level?: LogLevel[];
method?: HttpMethod[];
status?: ("2xx" | "3xx" | "4xx" | "5xx")[];
date_from?: string; // ISO 8601
date_to?: string; // ISO 8601
}
// Payload para crear un log
interface CreateLogPayload {
timestamp?: string; // Auto-generado si no se envía
level: LogLevel;
request_url: string;
request_method: HttpMethod;
status_code: number;
response_time_ms: number;
message: string;
application_id?: string; // Override del default
custom_fields?: Record<string, unknown>;
}7. Utilidades Exportadas
import {
formatTimestamp, // "2024-02-15T10:30:00Z" → "15/2/2024, 10:30:00"
formatMs, // 1500 → "1.50s", 45 → "45ms"
formatNumber, // 15000 → "15.0K", 1500000 → "1.5M"
formatPercent, // 98.5 → "98.5%"
defaultTheme, // Tema claro por defecto
darkTheme, // Tema oscuro por defecto
labelsEs, // Labels en español
labelsEn, // Labels en inglés
} from "@jaquinones45/jaquilogs-sdk";Licencia
MIT - JaquiSoft
