0Pricing
Go Academy · Lección

Handlers personalizados

Construya su propia salida de logs

Handlers personalizados es una lección gratuita de Go Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Go Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Go Academy incluye 4 lecciones en total.

Cuándo los handlers integrados no bastan

Los handlers de texto y JSON cubren la mayoría de las necesidades, pero a veces querrá una salida personalizada: terminales con color, envío a un sistema de métricas u ocultación de secretos. En ese caso, debe crear un handler personalizado.

La interfaz Handler

Un handler implementa cuatro métodos:

  • Enabled(ctx, level) bool
  • Handle(ctx, record) error
  • WithAttrs(attrs) Handler
  • WithGroup(name) Handler
type Handler interface {
    Enabled(context.Context, slog.Level) bool
    Handle(context.Context, slog.Record) error
    WithAttrs(attrs []slog.Attr) slog.Handler
    WithGroup(name string) slog.Handler
}

Enabled controla el filtrado

Enabled se llama antes de crear un registro. Devolver false permite que slog omita todo el trabajo, así que úselo para comprobar los niveles.

func (h *MyHandler) Enabled(_ context.Context, l slog.Level) bool {
    return l >= slog.LevelInfo
}

Handle realiza el trabajo

Handle recibe un slog.Record con la hora, el nivel, el mensaje y los atributos. Puede darle formato y escribirlo como prefiera.

func (h *MyHandler) Handle(_ context.Context, r slog.Record) error {
    fmt.Printf("[%s] %s\n", r.Level, r.Message)
    return nil
}

Iterar sobre los atributos

Un Record expone sus atributos mediante r.Attrs, que llama a su función para cada uno de ellos.

r.Attrs(func(a slog.Attr) bool {
    fmt.Printf("  %s=%v\n", a.Key, a.Value)
    return true // keep going
})

WithAttrs y WithGroup

Estos métodos devuelven una copia de su handler con atributos preestablecidos o un prefijo de grupo. Admiten logger.With y slog.Group. Un handler mínimo puede almacenarlos y reproducirlos o, para aprender, devolver el propio handler.

Envolver en lugar de construir

A menudo no necesita un handler completo: puede envolver uno existente y sobrescribir solo el comportamiento necesario, como añadir un atributo constante u ocultar determinadas claves.

type RedactHandler struct{ slog.Handler }

func (h RedactHandler) Handle(ctx context.Context, r slog.Record) error {
    // mutate r here, then delegate
    return h.Handler.Handle(ctx, r)
}

Caso de uso: ocultación

Un handler de ocultación puede buscar atributos con claves sensibles como password o token y sustituir el valor antes de delegar en un handler JSON.

Caso de uso: enrutamiento

Un handler personalizado puede enrutar por nivel: enviar los logs Error a stderr y a un webhook de alertas, mientras que Info va a stdout. Así, la lógica de enrutamiento no se repite en cada punto de llamada.

Consideraciones de rendimiento

Handle puede ejecutarse en rutas críticas. Evite las asignaciones de memoria, compruebe los niveles en Enabled y reutilice los búferes. Por este motivo, los handlers estándar usan internamente un búfer agrupado.

Ejecutable: un handler personalizado mínimo

Este programa independiente define un handler pequeño que imprime el nivel, el mensaje y los atributos, y después registra datos mediante él.

package main

import (
    "context"
    "fmt"
    "log/slog"
)

type Mini struct{}

func (Mini) Enabled(context.Context, slog.Level) bool { return true }
func (Mini) WithAttrs(a []slog.Attr) slog.Handler   { return Mini{} }
func (Mini) WithGroup(string) slog.Handler          { return Mini{} }
func (Mini) Handle(_ context.Context, r slog.Record) error {
    fmt.Printf("%s: %s", r.Level, r.Message)
    r.Attrs(func(a slog.Attr) bool {
        fmt.Printf(" %s=%v", a.Key, a.Value)
        return true
    })
    fmt.Println()
    return nil
}

func main() {
    l := slog.New(Mini{})
    l.Info("hello", "user", "ada", "id", 7)
}

Comprobación rápida

Compruebe lo que ha aprendido sobre los handlers personalizados.

Resumen

Ha aprendido a crear handlers personalizados:

  • Implemente Enabled, Handle, WithAttrs y WithGroup
  • Compruebe los niveles en Enabled para mejorar el rendimiento
  • Itere sobre los atributos con r.Attrs
  • A menudo es más sencillo envolver un handler existente que crearlo desde cero

Preguntas frecuentes

¿La lección «Handlers personalizados» es gratis?

Sí — el texto completo de «Handlers personalizados» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Go Academy, actualiza a CoddyKit PRO. El curso de Go Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Handlers personalizados»?

Construya su propia salida de logs Practicas Go Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Go Academy?

No se requiere experiencia previa. Go Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Handlers personalizados»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Go Academy?

Sí. Cada lección de Go Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Por qué usar logs estructurados
  2. Handlers de slog
  3. Niveles y atributos de logs
  4. Handlers personalizados
← Volver a Go Academy