Hoy vamos a implementar Bugsink un sistema autoalojado que nos permitirá registrar errores de nuestras aplicaciones y servidores de forma remota y con avisos. Para ello utilizaremos un docker compose.
Lo primero es entender qué es Bugsink.
BugSink es una herramienta o plataforma diseñada para gestionar errores o bugs en aplicaciones de software de manera centralizada. Su propósito es identificar, rastrear, priorizar y resolver problemas de software con mayor eficacia. Aunque no es un término ampliamente conocido como marca o software específico, en general, un sistema como BugSink podría funcionar como:
- Un sistema de gestión de errores: Recopila y centraliza reportes de errores provenientes de aplicaciones en producción, pruebas o desarrollo.
- Monitorización de excepciones: Detecta errores en tiempo real mientras los usuarios interactúan con la aplicación, registrando detalles técnicos como trazas de pila (stack trace), entornos de ejecución, o el estado del sistema cuando ocurrió el problema.
- Integración con flujos de trabajo: Muchas herramientas similares ofrecen integraciones con sistemas de gestión de proyectos como Jira, Trello, o Asana, lo que permite asignar y priorizar la resolución de errores directamente.
- Análisis y priorización: Proporciona métricas y visualizaciones para identificar cuáles errores son más críticos según su frecuencia, impacto en los usuarios, o gravedad.
- Facilidad para desarrolladores: Ofrece una interfaz amigable para rastrear los errores hasta su causa raíz, facilitando la depuración.
Ahora vamos a crear el entorno:
- Creamos un docker-compose con esta estructura.
services: bugsink: image: bugsink/bugsink:latest container_name: bugsink restart: always ports: - '8000:8000' environment: - PORT=8000 - CREATE_SUPERUSER=${CREATE_SUPERUSER} - SECRET_KEY=${SECRET_KEY} - BEHIND_HTTPS_PROXY=${USAR_PROXY_INVERSO} - SINGLE_USER=False - EMAIL_HOST=${EMAIL_HOST} - EMAIL_HOST_USER=${EMAIL_HOST_USER} - EMAIL_HOST_PASSWORD=${EMAIL_HOST_PASSWORD} - EMAIL_PORT=${EMAIL_PORT} - EMAIL_USE_TLS=${EMAIL_USE_TLS} - DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL} - DATABASE_URL=${DATABASE_URL} - SITE_TITLE=${SITE_TITLE} - BASE_URL=${BASE_URL} links: - mysql_bugsink:db depends_on: - mysql_bugsink mysql_bugsink: image: mariadb container_name: mysql_bugsink restart: always environment: MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} volumes: - ./config/mariadb:/var/lib/mysql phpmyadmin_mysql_bugsink: image: phpmyadmin restart: unless-stopped container_name: phpmyadmin_mysql_bugsink ports: - 8080:80 environment: - PMA_ARBITRARY=1 - MAX_EXECUTION_TIME=99999 - PHP_UPLOAD_MAX_FILESIZE=10000M - PHP_POST_MAX_SIZE=10000M - PHP_MEMORY_LIMIT=10000M links: - mysql_bugsink:db
He creado el servicio de bugsink configurando las variables para:
- Crear un super usuario
- El secret key (debemos generarlo aleatoriamente)
- Indicar si tiene o no un proxy por delante
- Indicar si va a utilizar un unico usuario (en este caso permito múltiples usuarios)
- Los datos del email SMTP. Esto se necesita para crear nuevos usuarios, ya que envía invitación utilizando el email.
- Database URL, necesario para utilizar MYSQL en vez de SQLite.
- Y podemos indicar el título del sitio.
Por otro lado, he desplegado un contenedor mariadb y phpmyadmin para poder utilizarlo como base de datos.
Ahora hay que configurar el .env de la siguiente forma:
SECRET_KEY=X534wALv1bEsJDmDnagsm19pPkYohZu5x3rORQenntylm3oxm5 USAR_PROXY_INVERSO=True CREATE_SUPERUSER=admin:admin SITE_TITLE=Bugsink - Control de errores BASE_URL=https://dominio.com #SMTP Email EMAIL_HOST=ssl.dominio.com EMAIL_HOST_USER=user@dominio.com EMAIL_HOST_PASSWORD=pass_email EMAIL_PORT=587 EMAIL_USE_TLS=True DEFAULT_FROM_EMAIL=Test <user@dominio.com> #Base de datos DATABASE_URL="mysql://user:password@db:3306/database_name" MYSQL_DATABASE="database_name" MYSQL_USER="user" MYSQL_PASSWORD="password" MYSQL_ROOT_PASSWORD="root_password"
Aquí tenemos que indicar las variables de entorno, primero indicaremos el SECRET_KEY, este debemos generarlo de forma aleatoría, he incluido el de defecto.
CREATE_SUPERUSER, debemos indicar el usuario:password del usuario administrador.
El resto de datos es para configurar el SMTP y la conexión a la base de datos.
Ahora podremos entrar al panel de control desde: http://localhost:8000/
E introducir los datos de usuario.
Para añadir un usuario tenemos que crear un nuevo equipo, vamos a Teams y pulsamos en New Team.
Ahora podremos invitar a un nuevo usuario pulsando en Invite Member:
Ahora crearemos un nuevo projecto, pulsamos en Projects > New Project
Elegiremos el nombre y el Team al que pertenece.
Ahora nos aparecerá la información de conexión con Python, JavaScript o PHP.
Instalar el cliente con JavaScript en React:
Utiliza el SDK de Sentry por lo que primero instalaremos Sentry:
npm install @sentry/react @sentry/tracing
Si utilizamos Next.js pondremos:
npm install @sentry/nextjs @sentry/tracing
Esto incluye:
- Sentry para React: Maneja errores y eventos en tus componentes React.
- Sentry para Next.js: Captura errores y excepciones en el servidor y cliente, e incluye soporte para API Routes y páginas dinámicas.
Configurar Sentry en JavaScript (React o Next.js)
Next.js tiene soporte para configurar Sentry fácilmente con un archivo de configuración dedicado.
Creamos un archivo dentro de utils por ejemplo, lo llamamos Bugsink.tsx o js según nuestro entorno
import * as Sentry from '@sentry/nextjs'; export function iniciarlizarBugsink() { Sentry.init({ dsn: 'https://<YOUR_DSN>@sentry.io/<PROJECT_ID>', tracesSampleRate: 1.0, // Captura el 100% de las solicitudes para debugging. Reduce en producción. }); }
*DSN es la URL que viene directamente en el proyecto creado.
Y ahora debemos importar el archivo en un context o nuestra web principal por ejemplo index.tsx
useEffect(() => { iniciarlizarBugsink(); }, []);
Puedes añadir otro tipo de configuración, por ejemplo los IDs de usuario:
import * as Sentry from '@sentry/nextjs'; Sentry.configureScope((scope) => { scope.setUser({ id: '123', email: 'user@example.com' }); scope.setTag('environment', 'production'); });
Y puedes capturar errores manualmente:
try { // Código que puede fallar throw new Error('Test error'); } catch (err) { Sentry.captureException(err); }
Ahora para probarlo generaremos un error:
throw new Error("Error Thrown on purpose to send it to Bugsink");
Y si todo va bien, aparecerá el error capturado en la web:
En el caso de Next.js
Ahora tenemos que generar los archivos .map para mostrar el source code en Bugsink.
Para ello vamos a next.config.js y añadimos esta línea dentro de nextConfig
const nextConfig = { productionBrowserSourceMaps: true,
Y en la configuración de webpack añadimos lo siguiente:
webpack(config, options) { config.devtool = options.dev ? 'eval-source-map' : 'source-map';
Configuración en React Native:
Instalamos las dependencias:
npm install @sentry/react-native
O si utilizas expo (https://docs.expo.dev/guides/using-sentry/)
npx expo install @sentry/react-native
Y ahora creamos el inicializador en un archivo llamado Bugsink qué podemos añadir en utils:
import * as Sentry from '@sentry/react'; export function iniciarlizarBugsink() { Sentry.init({ dsn: '<url proyecto>', tracesSampleRate: 1.0, // Captura el 100% de las solicitudes para debugging. Reduce en producción. }); }
Enviamos un mensaje de prueba de error:
Sentry.captureMessage('Mensaje de prueba desde Expo');
O generando una excepcion:
throw new Error('Hello, again, Sentry!');
Añadir en Python:
Para añadirlo en python tendremos que instalar la libreria:
pip install sentry-sdk
Y ahora debemos inicializarla en el main de nuestra aplicación:
import sentry_sdk sentry_sdk.init( '<url proyecto>', send_default_pii=True, max_request_body_size="always", # Setting up the release is highly recommended. The SDK will try to # infer it, but explicitly setting it is more reliable: # release=..., traces_sample_rate=1.0, )
*Indica la URL del proyecto que viene en el panel de control.
Extra: Utilizarlo debajo de Nginx Proxy Manager
Para configurar Bugsink con HTTPS detrás de un Nginx Proxy Manager, puedes usar los pasos a continuación. Esto asegura que Bugsink reconozca que está detrás de un proxy y maneja correctamente las solicitudes HTTPS.
1. Configuración del Proxy en Nginx Proxy Manager
Configura un host en tu Nginx Proxy Manager que redirija el tráfico al contenedor de Bugsink.
- Añadir un Proxy Host:
- En Nginx Proxy Manager, crea un nuevo Proxy Host.
- Domain Name: Introduce el dominio (por ejemplo,
bugsink.example.com
). - Forward Hostname/IP: La dirección interna del contenedor de Bugsink, como
bugsink
(nombre del servicio en Docker Compose). - Forward Port: El puerto que usa Bugsink (por defecto, suele ser
8000
para Gunicorn). - Enable Websockets: Marca esta opción.
- Configurar HTTPS:
- En la pestaña SSL, selecciona “Request a new SSL certificate”.
- Habilita las opciones:
- “Force SSL” para que todas las solicitudes sean redirigidas a HTTPS.
- “HTTP/2 Support” para mejorar el rendimiento.
- Guarda los cambios.
2. Configurar Bugsink para HTTPS y Proxy
En tu configuración de Bugsink, debes asegurarte de que la aplicación reconozca que está detrás de un proxy y que el proxy maneja HTTPS.
Opción 1: Usar la variable de entorno BEHIND_HTTPS_PROXY
En tu archivo docker-compose.yml
, añade esta variable de entorno al servicio de Bugsink:
services: bugsink: image: bugsink:latest environment: - BEHIND_HTTPS_PROXY=True ports: - "8000:8000" depends_on: - db
Esto configura automáticamente las siguientes opciones en Bugsink:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
USE_X_REAL_IP = True
Opción 2: Configurar manualmente en bugsink_conf.py
Si prefieres personalizar los ajustes, edita el archivo bugsink_conf.py
(o el archivo equivalente de configuración):
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True USE_X_REAL_IP = True
En Nginx Proxy Manager, asegúrate de que las cabeceras necesarias estén configuradas:
X-Forwarded-Proto
: Debe serhttps
.X-Real-IP
: Debe ser la dirección IP real del cliente.
3. Verificar las Cabeceras en Nginx Proxy Manager
Nginx Proxy Manager ya maneja correctamente las cabeceras como X-Forwarded-Proto
y X-Real-IP
, pero puedes personalizar las reglas si es necesario:
- Ve al Advanced Tab del Proxy Host.
- Asegúrate de añadir las siguientes cabeceras personalizadas si no están presentes:
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Esto asegurará que Bugsink reciba las cabeceras necesarias.
4. Reiniciar los Servicios
Después de hacer los cambios, reinicia tanto el contenedor de Bugsink como el Nginx Proxy Manager:
docker-compose restart
Ingeniero en Informática, Investigador, me encanta crear cosas o arreglarlas y darles una nueva vida. Escritor y poeta. Más de 20 APPs publicadas y un libro en Amazon.