log, regexp & text/template
El procesamiento de texto en producción Go abarca logs, coincidencia de patrones y salida renderizada.
Busca en todas las páginas de la documentación
El procesamiento de texto en producción Go abarca logs, coincidencia de patrones y salida renderizada.
log/slog estructura eventos para pipelines de observabilidad.
regexp extrae y valida texto con un rendimiento predecible.
text/template y html/template generan correos electrónicos, CLIs y HTML sin errores de concatenación de cadenas.
Migra nuevos servicios a slog con manejadores JSON y filtros de nivel.
Mantén el paquete log solo donde el costo de migración supere el beneficio.
Precompila expresiones regulares al inicializar el paquete o al inicio, no por solicitud.
Elige html/template siempre que la salida llegue a los navegadores para obtener auto-escapado contextual.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
import (
"log/slog"
"os"
"regexp"
"text/template"
)
// Establece el logger por defecto de slog para usar JSON y escribir en stdout.
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
// Compila una expresión regular para UUIDs una vez al inicio del paquete.
var reUUID = regexp.MustCompile(`[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`)
// Parsea una plantilla de correo electrónico una vez al inicio del paquete.
tmpl := template.Must(template.New("mail").Parse("Hello {{.Name}}\n"))Cuándo usar esto:
html/template.package main
import (
"bytes"
"errors"
"html/template"
"log/slog"
"os"
"regexp"
"text/template"
)
// User representa un usuario con nombre y correo electrónico.
type User struct {
Name string
Email string
}
// Compila una expresión regular para validar correos electrónicos.
var emailRe = regexp.MustCompile(`^[^@\s]+@[^@\s]+\.[^@\s]+$`)
// validateAndRender valida el correo electrónico de un usuario y renderiza un saludo.
func validateAndRender(u User) (string, error) {
// Valida el formato del correo electrónico.
if !emailRe.MatchString(u.Email) {
return "", ErrInvalidEmail
}
// Registra un evento informativo con atributos del usuario.
slog.Info("render welcome",
slog.String("user", u.Name),
slog.String("email", u.Email),
)
// Crea y ejecuta una plantilla de texto.
textT := template.Must(template.New("text").Parse("Welcome {{.Name}} <{{.Email}}>"))
var textBuf bytes.Buffer
if err := textT.Execute(&textBuf, u); err != nil {
return "", err
}
// Crea y ejecuta una plantilla HTML.
htmlT := template.Must(template.New("html").Parse(`<p>Welcome <b>{{.Name}}</b></p>`))
var htmlBuf bytes.Buffer
if err := htmlT.Execute(&htmlBuf, u); err != nil {
return "", err
}
// Devuelve el resultado de la plantilla HTML.
return htmlBuf.String(), nil
}
// ErrInvalidEmail es un error para correos electrónicos no válidos.
var ErrInvalidEmail = errors.New("invalid email")
func main() {
// Configura el manejador de texto de slog para registrar solo mensajes de nivel INFO o superior.
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})))
// Valida y renderiza un usuario.
out, err := validateAndRender(User{Name: "Ada", Email: "ada@example.com"})
if err != nil {
panic(err)
}
// Imprime la salida renderizada.
println(out)
}Lo que esto demuestra:
slog.Info con atributos tipados.text/template y html/template a partir de una misma estructura.template.Must para fallos en tiempo de análisis al inicio, cuando se mueve a init.slog enruta los registros a través de un Handler (JSONHandler, TextHandler o personalizado) con filtrado por nivel.regexp compila patrones en autómatas con sintaxis RE2 (sin retroreferencias).{{.Field}} y acciones como range y if.html/template aplica reglas de escapado contextual por cada contexto HTML, JS, URL y CSS.| API | Salida | Mejor para |
|---|---|---|
log | Líneas de stderr no estructuradas | Scripts, depuración rápida |
log/slog | Registros con niveles y atributos | Servicios y bibliotecas |
| zap/zerolog de terceros | Rendimiento específico del ecosistema | Pilas existentes ya estandarizadas |
// Adjunta el ID de solicitud a través de los manejadores:
logger := slog.With(slog.String("request_id", id))
logger.Info("handled", slog.Int("status", 200))
// Subcoincidencias de Regex:
parts := re.FindStringSubmatch(line)
// Mapa de funciones de plantilla:
tmpl.Funcs(template.FuncMap{"upper": strings.ToUpper})regexp.MustCompile al inicio o usar sync.Once.<script>. Solución: html/template para salida en el navegador.slog.SetDefault temprano en main; aceptar *slog.Logger en paquetes.encoding/json, el tokenizador html o analizadores adecuados.Execute entra en pánico en campos faltantes. Solución: usar {{if .Optional}} o comprobaciones de punteros en estructuras de datos.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| zap / zerolog | Logging de nanosegundos a QPS muy altos | slog nuevo es suficiente |
Funciones strings | Comprobaciones simples de prefijo/división | Las necesidades de patrones son pesadas en regex |
embed + archivos estáticos | Activos HTML fijos | Contenido de correo electrónico personalizado |
fmt.Fprintf de una línea | Salida solo de depuración | Logs estructurados de producción |
Usa log/slog para nuevos servicios.
Mantén log en código heredado hasta una pasada de migración enfocada; ambos pueden coexistir durante la transición.
slog.HandlerOptions{Level: slog.LevelDebug} en tu manejador.
Controla los logs de depuración en producción con variables de entorno o tags de compilación.
No.
Go regexp sigue RE2, que omite retroreferencias y lookahead para garantías de tiempo lineal.
Reestructura patrones o usa un motor diferente si realmente necesitas esas características.
Regex compilado en literales simples es más pesado que Contains o HasPrefix.
Usa funciones de cadena para comprobaciones de subcadenas fijas; regex cuando la estructura importa.
Analiza una plantilla base con bloques {{define "layout"}} y {{template "layout" .}} en los hijos.
ParseFiles y ParseGlob cargan conjuntos al inicio.
Envuelve os.File en un slog.Handler o usa io.MultiWriter con bibliotecas de rotación estilo lumberjack.
La elección del manejador permanece independiente del destino.
El escapado contextual depende del tipo de atributo.
Usa ayudantes tipados como template.URL para valores dinámicos de href.
Ejecuta en bytes.Buffer en pruebas de tabla y compara cadenas doradas.
Para HTML, verifica subcadenas en lugar de archivos completos sensibles a espacios en blanco.
Los flags del paquete log (LstdFlags, Lshortfile) solo se aplican a la salida heredada de log.
slog usa atributos explícitos en su lugar.
Pasa el flag (?m) para el comportamiento ^ y $ multilínea.
O habilita la constante regexp.Multiline al compilar con Compile.
Es posible que ya se haya escrito una salida parcial en el escritor.
Usa buffers para respuestas atómicas o descarta el error antes de enviar encabezados HTTP.
Reemplaza las cadenas de formato con pares clave-valor de atributos: slog.Info("msg", "key", value).
Envuelve los sitios de llamada heredados incrementalmente detrás de una pequeña interfaz de logging.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (default de GC Green Tea, go fix modernizers - verifica el parche al compilar), chi (última - verifica al compilar), gin (última - verifica al compilar), echo (última - verifica al compilar), google.golang.org/grpc (última - verifica al compilar), sigs.k8s.io/controller-runtime (última - verifica al compilar), kubebuilder (última - verifica al compilar), tinygo (última - verifica objetivos de placa al compilar), wazero (última - verifica al compilar) y golangci-lint (última - verifica el conjunto de linters al compilar).
Revisado por Chris St. John·Última actualización: 16 jul 2026