Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Driver go-mssqldb menyediakan pengelogan yang dapat dikonfigurasi untuk memecahkan masalah koneksi, masalah kueri, dan analisis performa. Artikel ini menjelaskan bendera log yang tersedia dan cara menggunakan logger kustom.
Bendera log
Gunakan log parameter koneksi untuk mengaktifkan output diagnostik. Bendera log adalah nilai bitmask, artinya Anda dapat menggabungkannya dengan menambahkan nilai bilangan bulatnya:
| Nilai penanda | Kategori | Description |
|---|---|---|
1 |
Errors | Mencatat pesan kesalahan. |
2 |
Messages | Catat pesan informasi dari server. |
4 |
Rows | Catat data baris. |
8 |
SQL | Log pernyataan SQL yang dikirim ke server. |
16 |
Parameter-parameternya | Catat nama dan nilai parameter. |
32 |
Transactions | Catat peristiwa mulai, penerapan dan pengembalian transaksi. |
64 |
Debug | Catat protokol tingkat rendah dan rincian TDS. |
128 |
Pengulangan | Catat upaya percobaan ulang koneksi. |
Bendera 4 (baris) dan 16 (parameter) dapat mengekspos data aplikasi, rahasia, atau informasi identitas pribadi. Perlakukan mereka sebagai bendera diagnostik berumur pendek, bukan sebagai pengaturan produksi rutin.
Examples
Catat hanya kesalahan:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=1
Kesalahan log, pernyataan SQL, dan parameter:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=25
Note
Nilainya 25 dihitung sebagai 1 + 8 + 16 (kesalahan + SQL + parameter).
Catat semuanya:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=255
Warning
Nilai flag log yang tinggi (64, 128, 255) menghasilkan output yang verbose dan dapat memengaruhi kinerja. Gunakan hanya untuk debugging.
Pencatat default
Secara bawaan, driver mencatat log ke paket standar log milik Go, yang menulis ke os.Stderr. Keluaran mencakup stempel waktu dan kategori log:
2026/03/28 10:15:30 mssql: login successful
2026/03/28 10:15:30 mssql: SQL: SELECT 1
Pencatat khusus dengan SetLogger
Gunakan mssql.SetLogger untuk mengalihkan output log driver ke logger kustom. Logger harus mengimplementasikan antarmuka mssql.Logger:
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
}
Pencatat sadar konteks dengan SetContextLogger
Gunakan mssql.SetContextLogger untuk menyediakan logger yang memahami konteks. Pencatat harus mengimplementasikan mssql.ContextLogger antarmuka, yang memiliki satu Log metode yang menerima konteks, kategori log, dan string pesan. Pendekatan ini memungkinkan Anda untuk menghubungkan log driver dengan data pelacakan cakupan permintaan (misalnya, ID pelacakan):
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
}
Daftar periksa diagnostik
Saat memecahkan masalah koneksi atau kueri:
- Mulailah dengan
log=1untuk kesalahan, ataulog=3jika Anda juga memerlukan pesan server. - Reproduksi masalah tersebut dan tinjau pesan kesalahan sebelum mengaktifkan lebih banyak kategori.
- Tambahkan
8jika Anda perlu mengonfirmasi pernyataan SQL atau panggilan prosedur mana yang dikirim. - Tambahkan
16atau4hanya di lingkungan yang aman di mana nilai parameter dan baris yang ditampilkan dapat dicatat tanpa mengekspos data sensitif. - Jika masalah tampak berada di tingkat protokol atau terkait dengan percobaan ulang, tingkatkan ke
log=64atau tambahkan128untuk diagnostik percobaan ulang. - Hapus atau kurangi pengelogan setelah masalah diselesaikan.
Pencatatan terstruktur dengan log/slog
Go 1.21 memperkenalkan log/slog untuk logging terstruktur. Gunakan SetContextLogger untuk merutekan output driver melalui 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.
}
Integrasi dengan zerolog
Zerolog adalah pencatat terstruktur tanpa alokasi. Arahkan log driver melalui 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})
}
Integrasi dengan zap
ZAP adalah logger terstruktur berkinerja tinggi. Arahkan log driver melalui 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})
}
Propagasi ID korelasi
Dalam sistem terdistribusi, menyebarkan ID korelasi melalui konteks sehingga log driver dapat dikorelasikan dengan permintaan yang memicunya:
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)),
)
}
Kemudian teruskan ID korelasi melalui konteks permintaan Anda:
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")
// ...
}
Cara menggunakan ID korelasi dalam praktik
Gunakan ID korelasi sebagai kunci pelacakan di seluruh log, percobaan ulang, dan panggilan database:
- Buat atau terima ID korelasi di batas permintaan.
- Simpan dalam konteks permintaan dan sertakan dalam log aplikasi dan driver.
- Untuk pemecahan masalah di sisi SQL, tetapkan dalam konteks sesi dengan
sp_set_session_contextdan baca denganSESSION_CONTEXT.
ID korelasi tidak secara otomatis disimpan dalam tabel SQL Server.
SESSION_CONTEXT memiliki cakupan sesi, sehingga nilainya hanya berlaku untuk koneksi saat ini dan tidak dipertahankan setelah sesi berakhir.
Jika Anda memerlukan riwayat yang tahan lama, tulis ID korelasi secara eksplisit ke tabel audit atau bisnis Anda (misalnya, AuditLog tabel dengan correlation_id, stempel waktu, operasi, dan status).
Konfigurasi pengelogan produksi
Dalam produksi, aktifkan pengelogan minimal untuk menghindari overhead performa dan mencegah data sensitif muncul di log:
| Lingkungan | Nilai yang direkomendasikan log |
Apa yang ditangkapnya |
|---|---|---|
| Development |
63 (kesalahan + pesan + baris + SQL + parameter + transaksi) |
Visibilitas penuh untuk debugging. |
| Staging |
3 (kesalahan + pesan) |
Kesalahan dan pesan server tanpa detail kueri. |
| Production |
1 (error) atau 0 (nonaktif) |
Kesalahan saja, atau nonaktifkan pencatatan log driver sepenuhnya. |
Caution
Bendera Parameters (16) mencatat nilai parameter aktual, yang dapat mencakup informasi identitas pribadi (PII), kata sandi, atau data sensitif lainnya. Jangan pernah mengaktifkan flag ini di lingkungan produksi. Untuk penilaian risiko lengkap dari setiap bendera, lihat Praktik terbaik keamanan.
Nonaktifkan pencatatan log di lingkungan produksi
Gunakan variabel lingkungan untuk mengontrol tingkat log per tahap penyebaran:
if os.Getenv("APP_ENV") == "production" {
// Use only error-level logging in production.
connString += "&log=1"
} else {
// Full logging in development.
connString += "&log=63"
}