Add debug mode to log

This commit is contained in:
Andrew-71 2024-10-13 11:25:00 +03:00
parent ba31bc24a6
commit c22cf9e7c8
7 changed files with 56 additions and 9 deletions

View file

@ -5,4 +5,4 @@ serve:
go build && ./pye serve go build && ./pye serve
dev: dev:
go build && ./pye serve --db dev-data.db go build && ./pye serve --db dev-data.db --debug

View file

@ -11,15 +11,17 @@ in a state that proves I am competent Go developer.
## Commands ## Commands
## `pye serve [--config] [--port] [--db]` ## JWT server
Serve a simple JWT auth system Serve a simple JWT auth system
**Usage**: `pye serve [--config] [--port] [--db]`
* `POST /register` - register a user with Basic Auth * `POST /register` - register a user with Basic Auth
* `POST /login` - get a JWT token by Basic Auth * `POST /login` - get a JWT token by Basic Auth
* `GET /pem` - get PEM-encoded public RS256 key * `GET /pem` - get PEM-encoded public RS256 key
* Data and RS256 key persistently stored in an SQLite database and a PEM file * Data and RS256 key persistently stored in an SQLite database and a PEM file
## `pye verify <jwt> <pem file>` ## JWT verification
Verify a JWT with a public key from a PEM file Verify a JWT with a public key from a PEM file
**Usage**: `pye verify <jwt> <pem_file>`

View file

@ -9,6 +9,7 @@ import (
"git.a71.su/Andrew71/pye/cmd/serve" "git.a71.su/Andrew71/pye/cmd/serve"
"git.a71.su/Andrew71/pye/cmd/verify" "git.a71.su/Andrew71/pye/cmd/verify"
"git.a71.su/Andrew71/pye/config" "git.a71.su/Andrew71/pye/config"
"git.a71.su/Andrew71/pye/logging"
) )
func Run() { func Run() {
@ -17,8 +18,10 @@ func Run() {
serveConfig := serveCmd.String("config", "", "override config file") serveConfig := serveCmd.String("config", "", "override config file")
servePort := serveCmd.Int("port", 0, "override port") servePort := serveCmd.Int("port", 0, "override port")
serveDb := serveCmd.String("db", "", "override sqlite database") serveDb := serveCmd.String("db", "", "override sqlite database")
serveDebug := serveCmd.Bool("debug", false, "debug logging")
verifyCmd := flag.NewFlagSet("verify", flag.ExitOnError) verifyCmd := flag.NewFlagSet("verify", flag.ExitOnError)
verifyDebug := verifyCmd.Bool("debug", false, "debug logging")
if len(os.Args) < 2 { if len(os.Args) < 2 {
fmt.Println("expected 'serve' or 'verify' subcommands") fmt.Println("expected 'serve' or 'verify' subcommands")
@ -28,6 +31,7 @@ func Run() {
switch os.Args[1] { switch os.Args[1] {
case "serve": case "serve":
serveCmd.Parse(os.Args[2:]) serveCmd.Parse(os.Args[2:])
logging.LogInit(*serveDebug)
if *serveConfig != "" { if *serveConfig != "" {
err := config.LoadConfig(*serveConfig) err := config.LoadConfig(*serveConfig)
if err != nil { if err != nil {
@ -43,8 +47,9 @@ func Run() {
serve.Serve() serve.Serve()
case "verify": case "verify":
verifyCmd.Parse(os.Args[2:]) verifyCmd.Parse(os.Args[2:])
logging.LogInit(*verifyDebug)
if len(os.Args) != 4 { if len(os.Args) != 4 {
fmt.Println("Usage: <jwt> <pem file>") fmt.Println("Usage: <jwt> <pem file> [--debug]")
} }
verify.Verify(os.Args[2], os.Args[3]) verify.Verify(os.Args[2], os.Args[3])
default: default:

View file

@ -28,5 +28,6 @@ func Serve() {
router.HandleFunc("GET /login", func(w http.ResponseWriter, r *http.Request) { auth.Login(w, r, data) }) router.HandleFunc("GET /login", func(w http.ResponseWriter, r *http.Request) { auth.Login(w, r, data) })
slog.Info("🪐 pye started", "port", config.Cfg.Port) slog.Info("🪐 pye started", "port", config.Cfg.Port)
slog.Debug("debug mode active")
http.ListenAndServe(":"+strconv.Itoa(config.Cfg.Port), router) http.ListenAndServe(":"+strconv.Itoa(config.Cfg.Port), router)
} }

View file

@ -10,12 +10,16 @@ type Config struct {
Port int `json:"port"` Port int `json:"port"`
KeyFile string `json:"key-file"` KeyFile string `json:"key-file"`
SQLiteFile string `json:"sqlite-file"` SQLiteFile string `json:"sqlite-file"`
LogToFile bool `json:"log-to-file"`
LogFile string `json:"log-file"`
} }
var DefaultConfig = Config{ var DefaultConfig = Config{
Port: 7102, Port: 7102,
KeyFile: "private.key", KeyFile: "private.key",
SQLiteFile: "data.db", SQLiteFile: "data.db",
LogToFile: false,
LogFile: "pye.log",
} }
var ( var (

34
logging/log.go Normal file
View file

@ -0,0 +1,34 @@
package logging
import (
"io"
"log"
"log/slog"
"os"
"git.a71.su/Andrew71/pye/config"
)
// LogInit makes slog output to both os.Stdout and a file if needed, and sets slog.LevelDebug if enabled.
func LogInit(debugMode bool) {
var w io.Writer
if config.Cfg.LogToFile {
f, err := os.OpenFile(config.Cfg.LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
slog.Error("error opening log file, logging to stdout only", "path", config.Cfg.LogFile, "error", err)
return
}
// No defer f.Close() because that breaks the MultiWriter
w = io.MultiWriter(f, os.Stdout)
} else {
w = os.Stdout
}
// Make slog use intended format
var opts *slog.HandlerOptions
if debugMode {
opts = &slog.HandlerOptions{Level: slog.LevelDebug}
}
slog.SetDefault(slog.New(slog.NewTextHandler(w, opts)))
log.SetFlags(log.LstdFlags | log.Lshortfile)
}

View file

@ -18,6 +18,7 @@ const create string = `
PRIMARY KEY("uuid") PRIMARY KEY("uuid")
);` );`
// SQLiteStorage is a storage.Storage implementation with SQLite3
type SQLiteStorage struct { type SQLiteStorage struct {
db *sql.DB db *sql.DB
} }
@ -64,14 +65,14 @@ func MustLoadSQLite(dataFile string) SQLiteStorage {
} }
db, err := sql.Open("sqlite3", dataFile) db, err := sql.Open("sqlite3", dataFile)
if err != nil { if err != nil {
slog.Error("error opening database", "error", err) slog.Error("error opening sqlite3 database", "error", err)
os.Exit(1) os.Exit(1)
} }
statement, err := db.Prepare(create) statement, err := db.Prepare(create)
if err != nil { if err != nil {
if err.Error() != "table \"users\" already exists" { if err.Error() != "table \"users\" already exists" {
slog.Info("error initialising database table", "error", err) slog.Info("error initialising sqlite3 database table", "error", err)
os.Exit(1) os.Exit(1)
} }
} else { } else {