Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il go-mssqldb driver fornisce logging configurabile per risolvere problemi di connessione, query e analisi delle prestazioni. Questo articolo descrive i flag di log disponibili e come utilizzare logger personalizzati.
Flag di registro
Usa il parametro di connessione log per abilitare l'output diagnostico. I flag di log sono valori di maschera di bit, ossia puoi combinarli sommando i rispettivi valori interi:
| Valore flag | Categoria | Description |
|---|---|---|
1 |
Errors | Registra i messaggi di errore. |
2 |
Messages | Registra i messaggi informativi dal server. |
4 |
Righe | Registra i dati della riga. |
8 |
SQL | Registra le istruzioni SQL inviate al server. |
16 |
Parametri | Nomi e valori dei parametri log. |
32 |
Transactions | Registra gli eventi di avvio, commit e rollback delle transazioni. |
64 |
Debug | Registra i dettagli del protocollo di basso livello e di TDS. |
128 |
Nuovi tentativi | Registra i tentativi di riconnessione. |
Flag 4 (righe) e 16 (parametri) possono esporre dati dell'applicazione, segreti o informazioni personali identificabili. Trattali come segnali diagnostici di breve durata, non come impostazioni di produzione di routine.
Examples
Solo errori di log:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=1
Errori di log, istruzioni SQL e parametri:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=25
Note
Il valore 25 si calcola come 1 + 8 + 16 (errori + SQL + parametri).
Registra tutto:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=255
Warning
Valori logaritici elevati (64, 128, 255) producono output verbosi e possono influire sulle prestazioni. Usali solo per il debug.
Logger predefinito
Di default, il driver si loga nel pacchetto standard log di Go, che scrive in os.Stderr. L'output include le marche temporali e la categoria di log:
2026/03/28 10:15:30 mssql: login successful
2026/03/28 10:15:30 mssql: SQL: SELECT 1
Logger personalizzato con SetLogger
Usa mssql.SetLogger per reindirizzare l'output del log del driver a un logger personalizzato. Il logger deve implementare l'mssql.Loggerinterfaccia:
import "github.com/microsoft/go-mssqldb"
type myLogger struct{}
func (l *myLogger) Printf(format string, v ...interface{}) {
// Write to your preferred logging system
fmt.Printf("[MSSQL] "+format+"\n", v...)
}
func (l *myLogger) Println(v ...interface{}) {
fmt.Println(append([]interface{}{"[MSSQL]"}, v...)...)
}
func main() {
mssql.SetLogger(&myLogger{})
// ... open connection
}
Logger sensibile al contesto con SetContextLogger
Usare mssql.SetContextLogger per fornire un logger sensibile al contesto. Il logger deve implementare l'interfaccia mssql.ContextLogger , che ha un unico Log metodo che riceve il contesto, una categoria di log e una stringa di messaggi. Questo approccio consente di correlare i log dei driver con i dati di tracciamento relativi alla singola richiesta (ad esempio, gli ID di tracciamento):
import (
"context"
"log/slog"
"github.com/microsoft/go-mssqldb"
"github.com/microsoft/go-mssqldb/msdsn"
)
type contextLogger struct{}
func (l *contextLogger) Log(ctx context.Context, category msdsn.Log, msg string) {
slog.InfoContext(ctx, msg, "category", category)
}
func main() {
mssql.SetContextLogger(&contextLogger{})
// ... open connection
}
Elenco di controllo diagnostico
Quando si risolve un problema di connessione o di domanda:
- Inizia con
log=1per gli errori, olog=3se ti occorrono anche i messaggi del server. - Riproduci il problema e rivedi il testo dell'errore prima di abilitare altre categorie.
- Aggiungi
8se devi confermare quale istruzione SQL o chiamata procedura è stata inviata. - Aggiungi
16o4solo in un ambiente sicuro dove i valori dei parametri e le righe restituite possono essere registrati senza esporre dati sensibili. - Se il problema sembra a livello del protocollo o relativo ai tentativi di ritrasmissione, aumenta a
log=64o aggiungi128per la diagnostica dei tentativi di ritrasmissione. - Rimuovi o riduci la registrazione dopo che il problema è risolto.
Logging strutturato con log/slog
Go 1.21 ha introdotto log/slog per il logging strutturato. Usa SetContextLogger per instradare l'uscita del driver attraverso slog:
import (
"context"
"log/slog"
"os"
"github.com/microsoft/go-mssqldb"
"github.com/microsoft/go-mssqldb/msdsn"
)
type slogLogger struct {
logger *slog.Logger
}
func (l *slogLogger) Log(ctx context.Context, category msdsn.Log, msg string) {
level := slog.LevelInfo
if category == msdsn.LogErrors {
level = slog.LevelError
}
if category == msdsn.LogDebug {
level = slog.LevelDebug
}
l.logger.LogAttrs(ctx, level, msg,
slog.Int("category", int(category)),
)
}
func main() {
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))
mssql.SetContextLogger(&slogLogger{logger: logger})
// Connection logging now produces structured JSON.
}
Integrazione con zerolog
Zerolog è un logger strutturato a allocazione zero. Instrada i log del driver tramite zerolog:
import (
"context"
"os"
"github.com/microsoft/go-mssqldb"
"github.com/microsoft/go-mssqldb/msdsn"
"github.com/rs/zerolog"
)
type zerologAdapter struct {
logger zerolog.Logger
}
func (l *zerologAdapter) Log(ctx context.Context, category msdsn.Log, msg string) {
event := l.logger.Info()
if category == msdsn.LogErrors {
event = l.logger.Error()
}
event.Int("category", int(category)).Msg(msg)
}
func main() {
logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
mssql.SetContextLogger(&zerologAdapter{logger: logger})
}
Integrazione con zap
ZAP è un logger strutturato ad alte prestazioni. Instrada i log del driver tramite ZAP:
import (
"context"
"github.com/microsoft/go-mssqldb"
"github.com/microsoft/go-mssqldb/msdsn"
"go.uber.org/zap"
)
type zapAdapter struct {
logger *zap.Logger
}
func (l *zapAdapter) Log(ctx context.Context, category msdsn.Log, msg string) {
if category == msdsn.LogErrors {
l.logger.Error(msg, zap.Int("category", int(category)))
} else {
l.logger.Info(msg, zap.Int("category", int(category)))
}
}
func main() {
logger, _ := zap.NewProduction()
defer logger.Sync()
mssql.SetContextLogger(&zapAdapter{logger: logger})
}
Propagazione dell'ID di correlazione
Nei sistemi distribuiti, propagare un ID di correlazione attraverso il contesto in modo che i log dei driver possano essere correlati con la richiesta che li ha attivati:
type correlationKey struct{}
func WithCorrelationID(ctx context.Context, id string) context.Context {
return context.WithValue(ctx, correlationKey{}, id)
}
func CorrelationID(ctx context.Context) string {
if id, ok := ctx.Value(correlationKey{}).(string); ok {
return id
}
return "unknown"
}
type correlatedLogger struct {
logger *slog.Logger
}
func (l *correlatedLogger) Log(ctx context.Context, category msdsn.Log, msg string) {
l.logger.LogAttrs(ctx, slog.LevelInfo, msg,
slog.String("correlation_id", CorrelationID(ctx)),
slog.Int("category", int(category)),
)
}
Poi passa l'ID di correlazione attraverso il contesto della richiesta:
func handleRequest(w http.ResponseWriter, r *http.Request) {
correlationID := r.Header.Get("X-Correlation-ID")
if correlationID == "" {
correlationID = uuid.NewString()
}
ctx := WithCorrelationID(r.Context(), correlationID)
// All database operations using this context will include the correlation ID.
rows, err := db.QueryContext(ctx, "SELECT TOP (10) ProductID, Name FROM Production.Product")
// ...
}
Come usare gli ID di correlazione nella pratica
Usa gli ID di correlazione come chiave per il tracciamento in tutti i log, i ritentativi e le chiamate al database:
- Generare o accettare un ID di correlazione al confine della richiesta.
- Memorizzalo nel contesto della richiesta e includerlo nei log delle applicazioni e dei driver.
- Per la risoluzione dei problemi lato SQL, impostalo nel contesto della sessione con
sp_set_session_contexte leggilo conSESSION_CONTEXT.
Gli ID di correlazione non vengono automaticamente memorizzati nelle tabelle di SQL Server.
SESSION_CONTEXT è a ambito sessione, quindi i valori si applicano solo alla connessione corrente e non persistono dopo la fine della sessione.
Se hai bisogno di una storia duratura, scrivi esplicitamente l'ID di correlazione nelle tue tabelle di audit o aziendale (ad esempio, una AuditLog tabella con correlation_id, timestamp, operazione e stato).
Configurazione della registrazione della produzione
In produzione, abilita la registrazione minima per evitare sovraccarichi di prestazioni e prevenire la comparsa di dati sensibili nei log:
| Ambiente | Valore consigliato log |
Cosa acquisisce |
|---|---|---|
| Development |
63 (errori + messaggi + righe + SQL + parametri + transazioni) |
Visibilità totale per il debug. |
| Staging |
3 (errori + messaggi) |
Errori e messaggi del server senza dettagli della query. |
| Produzione |
1 (errori) o 0 (disattivato) |
Solo errori, oppure disabilita completamente il log dei driver. |
Attenzione
Il Parameters flag (16) registra i valori effettivi dei parametri, che possono includere informazioni personali identificabili (PII), password o altri dati sensibili. Non abilitare mai questo flag in produzione. Per una valutazione completa del rischio di ciascuna bandiera, consulta le migliori pratiche di sicurezza.
Sopprimere la registrazione in produzione
Usa variabili ambientali per controllare il livello di log per ogni fase di deployment:
if os.Getenv("APP_ENV") == "production" {
// Use only error-level logging in production.
connString += "&log=1"
} else {
// Full logging in development.
connString += "&log=63"
}