---
name: logger_new
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func LoggerNew(level LogLevel, output io.Writer, format string) (*Logger, error)"
description: "Crea un Logger estructurado sobre log/slog con nivel, destino y formato configurables. Formato soportado: json o text. Si output es nil cae en os.Stderr."
tags: [logging, log, slog, logger, infra, pendiente-usar]
uses_functions: []
uses_types: [Logger_go_infra, LogLevel_go_infra]
returns: [Logger_go_infra]
returns_optional: true
error_type: "error_go_core"
imports: [fmt, io, log/slog, os]
params:
  - name: level
    desc: "nivel minimo de log (LogLevelDebug, LogLevelInfo, LogLevelWarn o LogLevelError)"
  - name: output
    desc: "destino de los logs (os.Stdout, os.Stderr, un archivo, bytes.Buffer). Si es nil se usa os.Stderr"
  - name: format
    desc: "formato de los logs: \"json\" para maquina o \"text\" para desarrollo local"
output: "Logger listo para usar con LogInfo/LogWarn/... o error si el formato no es valido"
tested: true
tests: ["crea logger JSON valido", "crea logger text valido", "rechaza formato invalido", "output nil cae en os.Stderr sin panic", "emite JSON valido al escribir", "filtra mensajes debajo del nivel configurado"]
test_file_path: "functions/infra/logger_test.go"
file_path: "functions/infra/logger_new.go"
---

## Ejemplo

```go
logger, err := LoggerNew(LogLevelInfo, os.Stdout, "json")
if err != nil {
    log.Fatal(err)
}
LogInfo(logger, "server starting", "port", 8484)
// {"time":"...","level":"INFO","msg":"server starting","port":8484}
```

## Notas

Funcion impura — internamente construye `slog.NewJSONHandler` o `slog.NewTextHandler` segun el formato y lo envuelve en `slog.New()`. El campo privado `inner` del Logger es el `*slog.Logger` real. Cada Logger es inmutable una vez creado: para anadir campos usar `LoggerWith`, que retorna una copia.
