Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der Treiber go-mssqldb bietet konfigurierbares Logging zur Fehlerbehebung von Verbindungsproblemen, Abfrageproblemen und Leistungsanalysen. Dieser Artikel beschreibt die verfügbaren Log-Flags und wie man benutzerdefinierte Logger verwendet.
Log-Kennzeichnungen
Verwenden Sie den Verbindungsparameter log , um die Diagnoseausgabe zu aktivieren. Log-Flags sind Bitmaskenwerte, das heißt, man kann sie kombinieren, indem man ihre ganzzahligen Werte addiert:
| Flagwert | Kategorie | Description |
|---|---|---|
1 |
Errors | Fehlermeldungen protokollieren. |
2 |
Messages | Informationsmeldungen des Servers protokollieren. |
4 |
Rows | Daten einer Zeile protokollieren. |
8 |
SQL | Protokolliere SQL-Anweisungen, die an den Server gesendet werden. |
16 |
Parameter | Protokolliere Parameternamen und -werte. |
32 |
Transaktionen | Protokolliere Transaktionsstart-, Commit- und Rollback-Ereignisse. |
64 |
Debug | Protokolliere Low-Level-Protokoll- und TDS-Details. |
128 |
Erneute Versuche | Protokolliere Verbindungsversuche. |
Flags 4 (Zeilen) und 16 (Parameter) können Anwendungsdaten, Geheimnisse oder personenbezogene Daten offenlegen. Behandle sie als kurzlebige Diagnosesignale, nicht als routinemäßige Produktionsumgebungen.
Beispiele
Nur Protokollfehler:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=1
Logfehler, SQL-Anweisungen und Parameter:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=25
Note
Der Wert 25 wird berechnet wie folgt 1 + 8 + 16 (Fehler + SQL + Parameter).
Protokolliere alles:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=255
Warning
Hohe logaritmische Flag-Werte (64, 128, ) 255erzeugen umfangreiche Ausgaben und können die Leistung beeinträchtigen. Verwende sie nur zum Debuggen.
Standardprotokollierer
Standardmäßig loggt sich der Treiber in das Standardpaket log von Go ein, das dann in schreibt os.Stderr. Die Ausgabe enthält Zeitstempel und die Log-Kategorie:
2026/03/28 10:15:30 mssql: login successful
2026/03/28 10:15:30 mssql: SQL: SELECT 1
Benutzerdefinierter Logger mit SetLogger
Nutze es mssql.SetLogger , um die Loggausgabe des Treibers an einen benutzerdefinierten Logger umzuleiten. Der Logger muss die mssql.Logger-Schnittstelle implementieren:
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
}
Kontextbewusster Logger mit SetContextLogger
Verwende mssql.SetContextLogger, um einen kontextbezogenen Logger bereitzustellen. Der Logger muss die Schnittstelle mssql.ContextLogger implementieren, die eine einzige Log Methode besitzt, die den Kontext empfängt, eine Log-Kategorie und eine Nachrichtenzeichenkette. Dieser Ansatz ermöglicht es Ihnen, Treiberprotokolle mit anfragebezogenen Tracingdaten (zum Beispiel Trace-IDs) zu korrelieren:
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
}
Diagnoseprüfliste
Beim Troubleshooting eines Verbindungs- oder Abfrageproblems:
- Beginne mit
log=1bei Fehlern oder mitlog=3, wenn du auch Servermeldungen benötigst. - Reproduzieren Sie das Problem und überprüfen Sie den Fehlertext, bevor Sie weitere Kategorien aktivieren.
- Fügen Sie hinzu,
8wenn Sie bestätigen müssen, welche SQL-Anweisung oder Prozeduraufruf gesendet wurde. - Fügen Sie nur
16oder4in einer sicheren Umgebung hinzu, in der Parameterwerte und zurückgegebene Zeilen protokolliert werden können, ohne sensible Daten offenzulegen. - Wenn das Problem auf Protokollebene zu liegen scheint oder mit Wiederholungsversuchen zusammenhängt, setzen Sie
log=64höher oder fügen Sie128für die Diagnose von Wiederholungsversuchen hinzu. - Entferne oder reduziere das Loggen, nachdem das Problem behoben ist.
Strukturiertes Logging mit log/slog
Go 1.21 führte log/slog für strukturiertes Logging ein. Verwenden Sie SetContextLogger, um die Treiberausgabe durch slog zu leiten:
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.
}
Integration mit zerolog
Zerolog ist ein strukturierter Logger mit Null-Allokation. Protokolle des Routentreibers über 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})
}
Integration mit Zap
ZAP ist ein hochleistungsfähiger strukturierter Logger. Fahrerprotokolle der Route über 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})
}
Weitergabe der Korrelations-ID
In verteilten Systemen wird eine Korrelations-ID durch den Kontext verbreitet, sodass Treiberprotokolle mit der Anfrage korreliert werden können, die sie ausgelöst hat:
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)),
)
}
Dann übergeben Sie die Korrelations-ID im Anforderungskontext:
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")
// ...
}
Wie man Korrelations-IDs in der Praxis verwendet
Verwenden Sie Korrelations-IDs als Nachverfolgungsschlüssel über Logs, Retries und Datenbankaufrufe:
- Erstelle oder akzeptiere eine Korrelations-ID an der Anfragegrenze.
- Speichere es im Anforderungskontext und füge es in die Anwendungs- und Treiberlogs ein.
- Für SQL-seitige Fehlersuche setze es in den Session-Kontext mit
sp_set_session_contextund lies es mitSESSION_CONTEXT.
Korrelations-IDs werden nicht automatisch in SQL Server-Tabellen gespeichert.
SESSION_CONTEXT ist session-scoped, sodass Werte nur auf die aktuelle Verbindung angewendet werden und nach Ablauf der Sitzung nicht bestehen bleiben.
Wenn Sie eine dauerhafte Historie benötigen, schreiben Sie die Korrelations-ID explizit in Ihre Audit- oder Geschäftstabellen (zum Beispiel eine AuditLog Tabelle mit correlation_id, Zeitstempel, Betrieb und Status).
Konfiguration der Produktionsprotokollierung
In der Produktion sollten Sie minimale Protokollierung aktivieren, um Leistungsüberkopf zu vermeiden und zu verhindern, dass sensible Daten in Logs erscheinen:
| Umgebung | Empfohlener Wert log |
Was er erfasst |
|---|---|---|
| Entwicklung |
63 (Fehler + Nachrichten + Zeilen + SQL + Params + Transaktionen) |
Volle Übersicht zum Debuggen. |
| Staging |
3 (Fehler + Nachrichten) |
Fehler und Servernachrichten ohne Abfragedetails. |
| Produktion |
1 (Fehler) oder 0 (aus) |
Nur Fehler oder die Treiberprotokollierung vollständig deaktivieren. |
Achtung
Das Flag Parameters (16) protokolliert tatsächliche Parameterwerte, die personenbezogene Daten (PII), Passwörter oder andere sensible Daten umfassen können. Aktiviere diese Flagge niemals in der Produktion. Für eine vollständige Risikobewertung jeder Flagge siehe Security Best Practices.
Protokollierung in der Produktion unterdrücken
Verwenden Sie Umweltvariablen, um die Log-Ebene pro Bereitstellungsstufe zu steuern:
if os.Getenv("APP_ENV") == "production" {
// Use only error-level logging in production.
connString += "&log=1"
} else {
// Full logging in development.
connString += "&log=63"
}