Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O go-mssqldb driver fornece registos configuráveis para resolver problemas de ligação, problemas de consulta e análise de desempenho. Este artigo descreve os indicadores de registo disponíveis e como utilizar registadores personalizados.
Sinalizadores de registo
Use o log parâmetro de ligação para ativar a saída de diagnóstico. As flags de registo são valores de máscara de bits, o que significa que pode combiná-las somando os respetivos valores inteiros:
| Valor da bandeira | Categoria | Description |
|---|---|---|
1 |
Errors | Registar mensagens de erro. |
2 |
Messages | Registar mensagens de informação do servidor. |
4 |
Rows | Registar os dados da linha. |
8 |
SQL | Registar as instruções SQL enviadas ao servidor. |
16 |
Parâmetros | Registe os nomes e os valores dos parâmetros. |
32 |
Transactions | Regista os eventos de início, confirmação e rollback das transações. |
64 |
Debug | Registar detalhes do protocolo de baixo nível e do TDS. |
128 |
Reintentos | Registar tentativas de repetição da ligação. |
Sinalizadores 4 (linhas) e 16 (parâmetros) podem expor dados da aplicação, segredos ou informações de identificação pessoal. Trata-os como sinais de diagnóstico de curta duração, não como configurações de produção rotineiras.
Examples
Apenas erros de log:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=1
Erros de log, instruções SQL e parâmetros:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=25
Note
O valor 25 é calculado como 1 + 8 + 16 (erros + SQL + parâmetros).
Registe tudo:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=255
Warning
Valores elevados de sinalização logarítmica (64, 128, 255) produzem uma saída verbosa e podem afetar o desempenho. Usa-os apenas para depuração.
Registador predefinido
Por defeito, o driver regista-se no pacote padrão log do Go, que escreve em os.Stderr. A saída inclui marcas temporais e a categoria de registo:
2026/03/28 10:15:30 mssql: login successful
2026/03/28 10:15:30 mssql: SQL: SELECT 1
Logger personalizado com SetLogger
Use mssql.SetLogger para redirecionar a saída de registo do controlador para um registador personalizado. O registador deve implementar a interface 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
}
Registador sensível ao contexto com SetContextLogger
Utilize mssql.SetContextLogger para fornecer um logger sensível ao contexto. O logger deve implementar a mssql.ContextLogger interface, que tem um único Log método que recebe o contexto, uma categoria de logs e uma cadeia de mensagens. Esta abordagem permite correlacionar registos do controlador com dados de rastreio associados ao pedido (por exemplo, IDs de rastreio):
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
}
Lista de verificação diagnóstica
Ao resolver um problema de ligação ou consulta:
- Comece por
log=1para erros, oulog=3se também precisar de mensagens do servidor. - Reproduza o problema e reveja o texto do erro antes de ativar mais categorias.
- Adiciona
8se precisares de confirmar qual instrução SQL ou chamada de procedimento foi enviada. - Adicionar
16ou4apenas num ambiente seguro onde os valores dos parâmetros e as linhas retornadas possam ser registados sem expor dados sensíveis. - Se o problema parecer estar relacionado com o protocolo ou com novas tentativas, aumente o valor para
log=64ou adicione128para diagnóstico de novas tentativas. - Remova ou reduza o registo depois de o problema estar resolvido.
Registo estruturado com log/slog
O Go 1.21 introduziu log/slog para registo estruturado. Utilize SetContextLogger para encaminhar a saída do controlador através de 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.
}
Integração com zerolog
Zerolog é um logger estruturado de alocação zero. Encaminhar os registos do controlador através do 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})
}
Integração com ZAP
O ZAP é um logger estruturado de alto desempenho. O motorista de rota inicia sessão através do 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})
}
Propagação do ID de correlação
Em sistemas distribuídos, propaga um ID de correlação através do contexto para que os registos de drivers possam ser correlacionados com o pedido que os desencadeou:
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)),
)
}
Depois passa o ID de correlação pelo contexto do teu pedido:
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")
// ...
}
Como usar IDs de correlação na prática
Utilize IDs de correlação como chave de rastreio em logs, novas tentativas e chamadas à base de dados:
- Gerar ou aceitar um ID de correlação na fronteira do pedido.
- Guarde-a no contexto do pedido e inclua-a nos registos da aplicação e do controlador.
- Para resolução de problemas do lado SQL, defina-o no contexto da sessão com
sp_set_session_contexte leia-o comSESSION_CONTEXT.
Os IDs de correlação não são armazenados automaticamente em tabelas do SQL Server.
SESSION_CONTEXT é com âmbito de sessão, por isso os valores aplicam-se apenas à ligação atual e não persistem após o fim da sessão.
Se precisar de histórico duradouro, escreva explicitamente o ID de correlação nas suas tabelas de auditoria ou de negócio (por exemplo, uma AuditLog tabela com correlation_id, carimbo temporal, operação e estado).
Configuração do registo de produção
Em produção, permita o mínimo registo para evitar sobrecarga de desempenho e evitar que dados sensíveis apareçam nos registos:
| Meio Ambiente | Valor recomendado log |
O que capta |
|---|---|---|
| Development |
63 (erros + mensagens + linhas + SQL + parâmetros + transações) |
Visibilidade total para depuração. |
| Staging |
3 (erros + mensagens) |
Erros e mensagens do servidor sem detalhes de consulta. |
| Produção |
1 (erros) ou 0 (desativado) |
Apenas erros, ou desativar completamente o registo de controladores. |
Caution
A Parameters flag (16) regista os valores reais dos parâmetros, que podem incluir informações pessoais identificáveis (PII), palavras-passe ou outros dados sensíveis. Nunca ative esta opção em produção. Para uma avaliação completa de risco de cada bandeira, consulte as melhores práticas de segurança.
Suprimir registos em produção
Utilize variáveis de ambiente para controlar o nível de registo para cada fase de implementação:
if os.Getenv("APP_ENV") == "production" {
// Use only error-level logging in production.
connString += "&log=1"
} else {
// Full logging in development.
connString += "&log=63"
}