mirror of
https://github.com/github/codeql.git
synced 2026-06-19 03:41:07 +02:00
Go: Model log/slog as a logging sink
The standard-library structured logger `log/slog` (Go 1.21+) was not modeled, so `go/log-injection` and `go/clear-text-logging` were blind to any code that logs through it. Model its logging functions and `*slog.Logger` methods — `Debug`, `Info`, `Warn`, `Error`, their `Context` variants, and `Log`/`LogAttrs` — as `log-injection` sinks (the kind that feeds `LoggerCall`, powering both queries). Adds `log/slog` cases to the `LoggerCall` library test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
8
go/ql/lib/change-notes/2026-06-17-model-log-slog.md
Normal file
8
go/ql/lib/change-notes/2026-06-17-model-log-slog.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the `log/slog` package (Go 1.21+). Its logging functions and
|
||||
`*slog.Logger` methods (`Debug`/`Info`/`Warn`/`Error`, their `Context`
|
||||
variants, and `Log`/`LogAttrs`) are now recognized as logging sinks, so the
|
||||
`go/log-injection` and `go/clear-text-logging` queries cover code that logs
|
||||
through `slog`.
|
||||
29
go/ql/lib/ext/log.slog.model.yml
Normal file
29
go/ql/lib/ext/log.slog.model.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
# Package-level convenience functions (msg string, args ...any).
|
||||
- ["log/slog", "", False, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["log/slog", "", False, "Info", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["log/slog", "", False, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["log/slog", "", False, "Error", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
# Context variants (ctx, msg string, args ...any).
|
||||
- ["log/slog", "", False, "DebugContext", "", "", "Argument[1..2]", "log-injection", "manual"]
|
||||
- ["log/slog", "", False, "InfoContext", "", "", "Argument[1..2]", "log-injection", "manual"]
|
||||
- ["log/slog", "", False, "WarnContext", "", "", "Argument[1..2]", "log-injection", "manual"]
|
||||
- ["log/slog", "", False, "ErrorContext", "", "", "Argument[1..2]", "log-injection", "manual"]
|
||||
# Log/LogAttrs (ctx, level, msg string, args/attrs ...).
|
||||
- ["log/slog", "", False, "Log", "", "", "Argument[2..3]", "log-injection", "manual"]
|
||||
- ["log/slog", "", False, "LogAttrs", "", "", "Argument[2..3]", "log-injection", "manual"]
|
||||
# Methods on *slog.Logger.
|
||||
- ["log/slog", "Logger", True, "Debug", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "Info", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "Warn", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "Error", "", "", "Argument[0..1]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "DebugContext", "", "", "Argument[1..2]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "InfoContext", "", "", "Argument[1..2]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "WarnContext", "", "", "Argument[1..2]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "ErrorContext", "", "", "Argument[1..2]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "Log", "", "", "Argument[2..3]", "log-injection", "manual"]
|
||||
- ["log/slog", "Logger", True, "LogAttrs", "", "", "Argument[2..3]", "log-injection", "manual"]
|
||||
@@ -1,6 +1,6 @@
|
||||
module codeql-go-tests/concepts/loggercall
|
||||
|
||||
go 1.15
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/golang/glog v1.2.5
|
||||
|
||||
@@ -2,10 +2,12 @@ package main
|
||||
|
||||
const fmt = "formatted %s string"
|
||||
const text = "test"
|
||||
const key = "key"
|
||||
|
||||
var v []byte
|
||||
|
||||
func main() {
|
||||
glogTest(len(v))
|
||||
stdlib()
|
||||
slogTest()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
func slogTest() {
|
||||
ctx := context.Background()
|
||||
var logger *slog.Logger
|
||||
|
||||
// Methods on *slog.Logger: Debug/Info/Warn/Error(msg string, args ...any).
|
||||
logger.Debug(text) // $ logger=text
|
||||
logger.Info(text) // $ logger=text
|
||||
logger.Warn(text) // $ logger=text
|
||||
logger.Error(text) // $ logger=text
|
||||
logger.Info(text, key, v) // $ logger=text logger=key logger=v
|
||||
|
||||
// Context variants: (ctx, msg string, args ...any).
|
||||
logger.DebugContext(ctx, text) // $ logger=text
|
||||
logger.InfoContext(ctx, text) // $ logger=text
|
||||
logger.WarnContext(ctx, text) // $ logger=text
|
||||
logger.ErrorContext(ctx, text) // $ logger=text
|
||||
logger.InfoContext(ctx, text, key, v) // $ logger=text logger=key logger=v
|
||||
|
||||
// Log/LogAttrs: (ctx, level, msg string, args/attrs ...).
|
||||
logger.Log(ctx, slog.LevelInfo, text, key, v) // $ logger=text logger=key logger=v
|
||||
logger.LogAttrs(ctx, slog.LevelInfo, text) // $ logger=text
|
||||
|
||||
// Package-level convenience functions.
|
||||
slog.Debug(text) // $ logger=text
|
||||
slog.Info(text) // $ logger=text
|
||||
slog.Warn(text) // $ logger=text
|
||||
slog.Error(text) // $ logger=text
|
||||
slog.Info(text, key, v) // $ logger=text logger=key logger=v
|
||||
slog.InfoContext(ctx, text, key, v) // $ logger=text logger=key logger=v
|
||||
slog.Log(ctx, slog.LevelInfo, text) // $ logger=text
|
||||
slog.LogAttrs(ctx, slog.LevelInfo, text) // $ logger=text
|
||||
}
|
||||
Reference in New Issue
Block a user