go: partially rework how slogging works
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
leo 2023-05-09 17:35:00 +02:00
parent e44238600b
commit a879704535
Signed by: wanderer
SSH Key Fingerprint: SHA256:Dp8+iwKHSlrMEHzE3bJnPng70I7LEsa3IJXRH/U+idQ
10 changed files with 138 additions and 43 deletions

@ -7,11 +7,13 @@ import (
"git.dotya.ml/mirre-mt/pcmt/ent"
"git.dotya.ml/mirre-mt/pcmt/slogging"
"github.com/labstack/echo/v4"
"golang.org/x/exp/slog"
)
type App struct {
e *echo.Echo
logger *slogging.Logger
slogger *slogging.Logger
logger slogging.Logger
initialised bool
embeds Embeds
templatesPath string
@ -34,7 +36,11 @@ func (a *App) Init(s *settings.Settings, logger *slogging.Logger, dbclient *ent.
e := echo.New()
a.e = e
a.logger = logger
a.slogger = logger
a.logger = *a.slogger
a.logger.Logger = a.logger.Logger.With(
slog.Group("pcmt extra", slog.String("module", "app")),
)
a.setting = s
@ -76,20 +82,20 @@ func (a *App) E() *echo.Echo {
return a.e
}
// Logger returns app's logger instance.
// Logger returns app's pointer to the global logger instance.
func (a *App) Logger() *slogging.Logger {
return a.logger
return a.slogger
}
// PrintConfiguration outputs relevant settings of the application to console.
func (a *App) PrintConfiguration() {
if a.setting != nil {
if a.setting.IsLive() {
a.Logger().Debug("app config: live mode enabled")
a.Logger().Debug("live mode enabled")
}
if a.setting.IsDevel() {
a.Logger().Debug("app config: devel mode enabled - make sure that browser-sync is running")
a.Logger().Debug("devel mode enabled - make sure that browser-sync is running")
}
return
@ -112,9 +118,6 @@ func (a *App) SetEmbeds(templates, assets embed.FS) {
// setDevel puts the app in devel mode, which loads a browser-sync script in
// templates and expects browser-sync running.
func (a *App) setDevel() {
a.Logger().Info("enabling debug logging for Echo")
a.Logger().Debug("enabling debug logging for Echo")
a.e.Debug = true
a.logger = slogging.SetLevel(slogging.LevelDebug)
a.Logger().Debug("enabled debug logging for the default logger")
}

@ -3,6 +3,7 @@ package settings
import (
"git.dotya.ml/mirre-mt/pcmt/config"
"git.dotya.ml/mirre-mt/pcmt/slogging"
"golang.org/x/exp/slog"
)
type Settings struct {
@ -31,10 +32,13 @@ func New() *Settings {
// the settings struct. Order of preference for values is (from higher to
// lower) as follows: flag -> Env var -> configuration file.
func (s *Settings) Consolidate(conf *config.Config, host *string, port *int, devel *bool, version string) {
log := slogging.GetLogger()
log := *slogging.GetLogger() // have a local copy.
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "app/settings")),
)
log.Debug("starting to consolidate settings")
log.Debug("parsing config")
log.Debug("parsing config values")
s.SetHost(conf.Host)
s.SetPort(conf.Port)

@ -9,6 +9,7 @@ import (
"git.dotya.ml/mirre-mt/pcmt/slogging"
"github.com/philandstuff/dhall-golang/v6"
"golang.org/x/exp/slog"
)
type session struct {
@ -30,35 +31,66 @@ type Config struct {
}
}
var log slogging.Logger
func LoadConfig(conf string, isPath bool) (*Config, error) {
var config Config
var err error
if isPath {
slogging.GetLogger().Debug("config from file")
slogger := slogging.GetLogger()
// initialise if not already initialised.
if slogger == nil {
slogger = slogging.Init(true)
}
// have a local copy.
log = *slogger
// add attr to all statements made with the local copy.
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "config")),
)
switch {
case isPath:
log.Debug("config from file")
err = dhall.UnmarshalFile(conf, &config)
} else {
slogging.GetLogger().Debug("config raw from cmdline")
case !isPath:
log.Debug("config raw from cmdline")
err = dhall.Unmarshal([]byte(conf), &config)
}
if err != nil {
return nil, err
if !config.Logger.Json {
slogger = slogging.Init(false)
log.Logger = slogger.Logger.With(
slog.Group("pcmt extra", slog.String("module", "config")),
)
}
if config.DevelMode {
_ = slogging.SetLevel(slogging.LevelDebug)
log.Debug("set DEBUG level based on config value")
slogging.GetLogger().Debugf("parsed config: %+v", config)
slogger = slogging.SetLevel(slogging.LevelDebug)
log.Logger = slogger.Logger.With(
slog.Group("pcmt extra", slog.String("module", "config")),
)
log.Debugf("parsed config: %+v", config)
if dhallCmdExists() {
_ = prettyPrintConfig(conf, isPath)
}
}
// only return now, one we had a chance to print the loaded config (as
// would be the case if the config adhered to the schema but our type
// definition above didn't - "don't know how to decode <nil> into ...")
if err != nil {
return nil, err
}
return &config, nil
}
@ -75,7 +107,7 @@ func prettyPrintConfig(conf string, isPath bool) error {
output, err := cmd.CombinedOutput()
if err != nil {
slogging.GetLogger().Debug("could not pretty-print config", "error", err)
log.Debug("could not pretty-print config", "error", err)
return err
}
@ -93,7 +125,7 @@ func dhallCmdExists() bool {
defer cancel()
if err := exec.CommandContext(ctx, "/bin/sh", "-c", "command -v dhall").Run(); err != nil {
slogging.GetLogger().Debug("no command dhall")
log.Debug("no command dhall")
return false
}

@ -5,17 +5,23 @@ import (
"git.dotya.ml/mirre-mt/pcmt/app/settings"
"git.dotya.ml/mirre-mt/pcmt/slogging"
"golang.org/x/exp/slog"
)
var (
setting *settings.Settings
appver string
log *slogging.Logger
slogger *slogging.Logger
log slogging.Logger
tmplPath string
)
func InitHandlers(s *settings.Settings, tmpls fs.FS) {
log = slogging.GetLogger()
slogger = slogging.GetLogger()
log = *slogger // have a local copy.
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "handlers")),
)
setting = s

@ -232,7 +232,7 @@ func SignupPost(client *ent.Client) echo.HandlerFunc {
return c.Redirect(http.StatusSeeOther, "/signup")
}
ctx := context.WithValue(context.Background(), moduser.CtxKey{}, log)
ctx := context.WithValue(context.Background(), moduser.CtxKey{}, slogger)
exists, err := moduser.Exists(ctx, client, username, email)
if err != nil {
@ -339,7 +339,7 @@ func Home(client *ent.Client) echo.HandlerFunc {
var u moduser.User
ctx := context.WithValue(context.Background(), moduser.CtxKey{}, log)
ctx := context.WithValue(context.Background(), moduser.CtxKey{}, slogger)
if usr, err := moduser.QueryUser(ctx, client, username); err == nil && usr != nil {
c.Logger().Debug("got usr: ", usr.Username)
c.Logger().Debug("admin? ", usr.IsAdmin)

@ -64,7 +64,7 @@ func SigninPost(client *ent.Client) echo.HandlerFunc {
return c.Redirect(http.StatusFound, "/signin")
}
ctx := context.WithValue(context.Background(), moduser.CtxKey{}, log)
ctx := context.WithValue(context.Background(), moduser.CtxKey{}, slogger)
if usr, err := moduser.QueryUser(ctx, client, username); err == nil {
log.Info("queried user:", &usr.ID)

@ -6,6 +6,7 @@ import (
"git.dotya.ml/mirre-mt/pcmt/ent"
"git.dotya.ml/mirre-mt/pcmt/ent/migrate"
"git.dotya.ml/mirre-mt/pcmt/slogging"
"golang.org/x/exp/slog"
)
// CtxKey serves as a key to context values for this package.
@ -13,7 +14,12 @@ type CtxKey struct{}
// DropAll deletes an re-creates the whole db.
func DropAll(ctx context.Context, client *ent.Client) error {
log := ctx.Value(CtxKey{}).(*slogging.Logger)
slogger := ctx.Value(CtxKey{}).(*slogging.Logger)
log := *slogger
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "modules/db")),
)
err := client.Schema.
Create(
@ -31,7 +37,13 @@ func DropAll(ctx context.Context, client *ent.Client) error {
// IsSetUp deletes the whole db.
func IsSetUp(ctx context.Context, client *ent.Client) (bool, error) {
log := ctx.Value(CtxKey{}).(*slogging.Logger)
slogger := ctx.Value(CtxKey{}).(*slogging.Logger)
log := *slogger
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "modules/db")),
)
is, err := client.Setup.
Query().
Only(ctx)

@ -11,6 +11,7 @@ import (
passwd "git.dotya.ml/mirre-mt/pcmt/modules/password"
"git.dotya.ml/mirre-mt/pcmt/slogging"
"github.com/google/uuid"
"golang.org/x/exp/slog"
)
type User struct {
@ -25,7 +26,12 @@ type User struct {
// CreateUser adds a user entry to the database.
func CreateUser(ctx context.Context, client *ent.Client, email, username, password string) (*ent.User, error) {
log := ctx.Value(CtxKey{}).(*slogging.Logger)
slogger := ctx.Value(CtxKey{}).(*slogging.Logger)
log := *slogger
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "modules/user")),
)
digest, err := passwd.GetHash(password)
if err != nil {
@ -60,7 +66,12 @@ func CreateUser(ctx context.Context, client *ent.Client, email, username, passwo
}
func QueryUser(ctx context.Context, client *ent.Client, username string) (*ent.User, error) {
log := ctx.Value(CtxKey{}).(*slogging.Logger)
slogger := ctx.Value(CtxKey{}).(*slogging.Logger)
log := *slogger
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "modules/user")),
)
u, err := client.User.
Query().
@ -84,7 +95,12 @@ func QueryUser(ctx context.Context, client *ent.Client, username string) (*ent.U
// Exists determines whether the username OR email in question was previously
// used to register a user.
func Exists(ctx context.Context, client *ent.Client, username, email string) (bool, error) {
log := ctx.Value(CtxKey{}).(*slogging.Logger)
slogger := ctx.Value(CtxKey{}).(*slogging.Logger)
log := *slogger
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "modules/user")),
)
usernameExists, err := UsernameExists(ctx, client, username)
if err != nil {
@ -120,8 +136,13 @@ func Exists(ctx context.Context, client *ent.Client, username, email string) (bo
// UsernameExists queries the database to check whether the username is
// available or taken, returns a bool and an error, which will be nil unless
// the error is one of IsNot{Found,Singular}.
func UsernameExists(ctx context.Context, client *ent.Client, username string) (bool, error) {
log := ctx.Value(CtxKey{}).(*slogging.Logger)
func UsernameExists(ctx context.Context, client *ent.Client, username string) (bool, error) { //nolint:dupl
slogger := ctx.Value(CtxKey{}).(*slogging.Logger)
log := *slogger
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "modules/user")),
)
usr, err := client.User.
Query().
@ -155,8 +176,13 @@ func UsernameExists(ctx context.Context, client *ent.Client, username string) (b
// EmailExists queries the database to check whether the email was already
// used; returns a bool and an error, which will be nil unless the error is not
// one of IsNot{Found,Singular}.
func EmailExists(ctx context.Context, client *ent.Client, email string) (bool, error) {
log := ctx.Value(CtxKey{}).(*slogging.Logger)
func EmailExists(ctx context.Context, client *ent.Client, email string) (bool, error) { //nolint:dupl
slogger := ctx.Value(CtxKey{}).(*slogging.Logger)
log := *slogger
log.Logger = log.Logger.With(
slog.Group("pcmt extra", slog.String("module", "modules/user")),
)
usr, err := client.User.
Query().

22
run.go

@ -11,6 +11,7 @@ import (
"syscall"
"time"
"golang.org/x/exp/slog"
// pure go postgres driver.
_ "github.com/lib/pq"
// ent pure go sqlite3 driver instead of "github.com/mattn/go-sqlite3".
@ -61,7 +62,10 @@ var (
devel = flag.Bool("devel", false, "Run the application in dev mode, connect to a local browser-sync instance for hot-reloading")
license = flag.Bool("license", false, "Print licensing information and exit")
version = "dev"
log *slogging.Logger
// the global logger.
slogger *slogging.Logger
// local logger instance.
log slogging.Logger
)
func run() error {
@ -74,8 +78,6 @@ func run() error {
printHeader()
log = slogging.Init(true)
// TODO: allow different configuration formats (toml, ni)
// TODO: rename main.go to pcmt.go
// TODO: add .golangci-lint
@ -87,8 +89,7 @@ func run() error {
conf, err := config.LoadConfig(*configFlag, *configIsPathFlag)
if err != nil {
log.Errorf("error loading config file '%s', bailing", *configFlag)
return err
return fmt.Errorf("couldn't load config file '%s', full err: %w", *configFlag, err)
}
setting := settings.New()
@ -97,6 +98,13 @@ func run() error {
conf, host, port, devel, version,
)
slogger = slogging.GetLogger() // init is performed in the config package.
log = *slogger // local copy.
log.Logger = log.Logger.With(
// local attrs.
slog.Group("pcmt extra", slog.String("module", "run")),
)
// expected connstring form for "github.com/xiaoqidun/entps":
// "file:ent?mode=memory&cache=shared&_fk=1"
// and for the postgres driver "github.com/lib/pq":
@ -117,7 +125,7 @@ func run() error {
}
defer db.Close()
ctx := context.WithValue(context.Background(), moddb.CtxKey{}, log)
ctx := context.WithValue(context.Background(), moddb.CtxKey{}, slogger)
log.Info("making sure that the db is set up")
@ -136,7 +144,7 @@ func run() error {
a := &app.App{}
err = a.Init(setting, log, db)
err = a.Init(setting, slogger, db)
if err != nil {
return err
}

@ -37,6 +37,8 @@ func Init(jsonHandler bool) *Logger {
logger = &Logger{slog.New(opts.NewTextHandler(os.Stderr))}
}
slog.SetDefault(logger.Logger)
logger.Info("slog logger initialised")
return logger
@ -70,6 +72,8 @@ func SetLevel(level int) *Logger {
logger = &Logger{slog.New(opts.NewTextHandler(os.Stderr))}
}
slog.SetDefault(logger.Logger)
return logger
}