cmd: use log in jobsite

This commit is contained in:
Lukas Zapletal 2025-05-06 14:53:17 +02:00 committed by Achilleas Koutsou
parent 71117f3ccc
commit 46f0a71053
2 changed files with 59 additions and 61 deletions

View file

@ -9,6 +9,7 @@ import (
"flag"
"fmt"
"io"
"log/slog"
"net/http"
"os"
"os/exec"
@ -17,12 +18,11 @@ import (
"strings"
"sync"
"time"
"github.com/sirupsen/logrus"
)
const (
ExitOk int = iota
ExitError
)
type State int
@ -79,10 +79,11 @@ func init() {
flag.Parse()
logrus.SetLevel(logrus.InfoLevel)
opts := &slog.HandlerOptions{Level: slog.LevelInfo}
if argJSON {
logrus.SetFormatter(&logrus.JSONFormatter{})
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, opts)))
} else {
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, opts)))
}
}
@ -127,14 +128,15 @@ func (builder *Builder) GetState() State {
func (builder *Builder) GuardState(stateWanted State) {
if stateCurrent := builder.GetState(); stateWanted != stateCurrent {
logrus.Fatalf("Builder.GuardState: Requested guard for %d but we're in %d. Exit", stateWanted, stateCurrent)
slog.Error("Builder.GuardState: Guard state mismatch", "requested", stateWanted, "current", stateCurrent)
os.Exit(ExitError)
}
}
func (builder *Builder) RegisterHandler(h Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := h(w, r); err != nil {
logrus.Fatal(err)
slog.Error("Handler: error", "error", err)
}
})
}
@ -143,14 +145,12 @@ func (builder *Builder) HandleClaim(w http.ResponseWriter, r *http.Request) erro
builder.GuardState(StateClaim)
if r.Method != "POST" {
logrus.WithFields(
logrus.Fields{"method": r.Method},
).Fatal("Builder.HandleClaim: unexpected request method")
slog.Error("Builder.HandleClaim: unexpected request method", "method", r.Method)
}
fmt.Fprintf(w, "%s", "done")
logrus.Info("Builder.HandleClaim: Done")
slog.Info("Builder.HandleClaim: Done")
builder.SetState(StateProvision)
@ -164,7 +164,7 @@ func (builder *Builder) HandleProvision(w http.ResponseWriter, r *http.Request)
return fmt.Errorf("Builder.HandleProvision: Unexpected request method")
}
logrus.WithFields(logrus.Fields{"argBuildPath": argBuildPath}).Debug("Builder.HandleProvision: Opening manifest.json")
slog.Debug("Builder.HandleProvision: Opening manifest.json", "argBuildPath", argBuildPath)
dst, err := os.OpenFile(
path.Join(argBuildPath, "manifest.json"),
@ -182,7 +182,7 @@ func (builder *Builder) HandleProvision(w http.ResponseWriter, r *http.Request)
return fmt.Errorf("Builder.HandleProvision: Failed to open manifest.json")
}
logrus.Debug("Builder.HandleProvision: Writing manifest.json")
slog.Debug("Builder.HandleProvision: Writing manifest.json")
_, err = io.Copy(dst, r.Body)
@ -196,7 +196,7 @@ func (builder *Builder) HandleProvision(w http.ResponseWriter, r *http.Request)
return fmt.Errorf("Builder.HandleProvision: Failed to write response")
}
logrus.Info("Builder.HandleProvision: Done")
slog.Info("Builder.HandleProvision: Done")
builder.SetState(StatePopulate)
@ -256,7 +256,7 @@ func (builder *Builder) HandlePopulate(w http.ResponseWriter, r *http.Request) e
return fmt.Errorf("Builder.HandlePopulate: Failed to write response")
}
logrus.Info("Builder.HandlePopulate: Done")
slog.Info("Builder.HandlePopulate: Done")
builder.SetState(StateBuild)
@ -279,7 +279,8 @@ func (builder *Builder) HandleBuild(w http.ResponseWriter, r *http.Request) erro
}
if builder.Build != nil {
logrus.Fatal("HandleBuild: Build started but Build was non-nil")
slog.Error("HandleBuild: Build started but Build was non-nil")
os.Exit(ExitError)
}
args := []string{
@ -306,7 +307,7 @@ func (builder *Builder) HandleBuild(w http.ResponseWriter, r *http.Request) erro
)
builder.Build.Process.Env = envs
logrus.Infof("BackgroundProcess: Starting %s with %s", builder.Build.Process, envs)
slog.Info("BackgroundProcess: Starting", "process", builder.Build.Process, "env", envs)
builder.Build.Stdout = &bytes.Buffer{}
builder.Build.Process.Stdout = builder.Build.Stdout
@ -325,14 +326,14 @@ func (builder *Builder) HandleBuild(w http.ResponseWriter, r *http.Request) erro
builder.Build.Error = builder.Build.Process.Wait()
builder.Build.Done = true
logrus.Info("BackgroundProcess: Exited")
slog.Info("BackgroundProcess: Exited")
}()
go func() {
scanner := bufio.NewScanner(builder.Build.Stderr)
for scanner.Scan() {
m := scanner.Text()
logrus.Infof("BackgroundProcess: Stderr: %s", m)
slog.Info("BackgroundProcess: Stderr", "text", m)
}
}()
@ -370,7 +371,7 @@ func (builder *Builder) HandleProgress(w http.ResponseWriter, r *http.Request) e
w.WriteHeader(http.StatusAccepted)
}
logrus.Info("Builder.HandleBuild: Done")
slog.Info("Builder.HandleBuild: Done")
return nil
}
@ -404,7 +405,7 @@ func (builder *Builder) HandleExport(w http.ResponseWriter, r *http.Request) err
return fmt.Errorf("Builder.HandleExport: Failed to write response: %s", err)
}
logrus.Info("Builder.HandleExport: Done")
slog.Info("Builder.HandleExport: Done")
builder.SetState(StateDone)
@ -433,16 +434,15 @@ func (builder *Builder) Serve() error {
}
func main() {
logrus.WithFields(
logrus.Fields{
"argJSON": argJSON,
"argBuilderHost": argBuilderHost,
"argBuilderPort": argBuilderPort,
"argTimeoutClaim": argTimeoutClaim,
"argTimeoutProvision": argTimeoutProvision,
"argTimeoutBuild": argTimeoutBuild,
"argTimeoutExport": argTimeoutExport,
}).Info("main: Starting up")
slog.With(
slog.Bool("argJSON", argJSON),
slog.String("argBuilderHost", argBuilderHost),
slog.Int("argBuilderPort", argBuilderPort),
slog.Int("argTimeoutClaim", argTimeoutClaim),
slog.Int("argTimeoutProvision", argTimeoutProvision),
slog.Int("argTimeoutBuild", argTimeoutBuild),
slog.Int("argTimeoutExport", argTimeoutExport),
).Info("main: Starting up")
builder := Builder{
State: StateClaim,
@ -465,14 +465,15 @@ func main() {
if state == StateDone {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
if err := builder.net.Shutdown(ctx); err != nil {
logrus.Errorf("main: server shutdown failed: %v", err)
slog.Error("main: server shutdown failed", "err", err)
}
cancel()
logrus.Info("main: Shutting down successfully")
slog.Info("main: Shutting down successfully")
os.Exit(ExitOk)
}
case err := <-errs:
logrus.Fatal(err)
slog.Error("ErrorChannel", "err", err)
os.Exit(ExitError)
}
}
}

View file

@ -4,11 +4,13 @@ package main
import (
"archive/tar"
"bytes"
"context"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"log/slog"
"net/http"
"net/url"
"os"
@ -18,8 +20,6 @@ import (
"strings"
"syscall"
"time"
"github.com/sirupsen/logrus"
)
const (
@ -94,15 +94,16 @@ func init() {
flag.Parse()
logrus.SetLevel(logrus.InfoLevel)
opts := &slog.HandlerOptions{Level: slog.LevelInfo}
if argJSON {
logrus.SetFormatter(&logrus.JSONFormatter{})
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, opts)))
} else {
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, opts)))
}
}
func main() {
logrus.Info("main: Starting up")
slog.Info("main: Starting up")
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
@ -115,19 +116,13 @@ func main() {
for {
select {
case sig := <-sigs:
logrus.WithFields(
logrus.Fields{
"signal": sig,
}).Info("main: Exiting on signal")
slog.Info("main: Exiting on signal", "signal", sig)
os.Exit(ExitSignal)
case err := <-errs:
logrus.WithFields(
logrus.Fields{
"error": err,
}).Info("main: Exiting on error")
slog.Info("main: Exiting on error", "error", err)
os.Exit(ExitError)
case <-done:
logrus.Info("main: Shutting down succesfully")
slog.Info("main: Shutting down succesfully")
os.Exit(ExitOk)
}
}
@ -175,15 +170,16 @@ func Dance(done chan<- struct{}, errs chan<- error) {
}
func Request(method string, path string, body io.Reader, bodySeeker io.ReadSeeker) (*http.Response, error) {
ctx := context.Background()
cli := &http.Client{}
url := fmt.Sprintf("http://%s:%d/%s", argBuilderHost, argBuilderPort, path)
var req *http.Request
var err error
if bodySeeker != nil {
req, err = http.NewRequest(method, url, bodySeeker)
req, err = http.NewRequestWithContext(ctx, method, url, bodySeeker)
} else {
req, err = http.NewRequest(method, url, body)
req, err = http.NewRequestWithContext(ctx, method, url, body)
}
if err != nil {
return nil, err
@ -193,7 +189,7 @@ func Request(method string, path string, body io.Reader, bodySeeker io.ReadSeeke
// download when the exports are requested.
req.Header.Set("Accept-Encoding", "identity")
logrus.Debugf("Request: Making a %s request to %s", method, url)
slog.DebugContext(ctx, "Request: Making a request", "method", method, "url", url)
for {
res, err := cli.Do(req)
@ -249,7 +245,7 @@ func StepClaim() error {
return
}
logrus.Info("StepClaim: Done")
slog.Info("StepClaim: Done")
close(done)
})
@ -271,7 +267,7 @@ func StepProvision(manifest []byte) error {
return
}
logrus.Info("StepProvision: Done")
slog.Info("StepProvision: Done")
close(done)
})
@ -357,7 +353,7 @@ func StepPopulate() error {
return
}
logrus.Info("StepPopulate: Done")
slog.Info("StepPopulate: Done")
close(done)
})
@ -373,7 +369,8 @@ func StepBuild() error {
dat, err := json.Marshal(arg)
if err != nil {
logrus.Fatalf("StepBuild: Failed to marshal data: %s", err)
slog.Error("StepBuild: Failed to marshal data", "err", err)
os.Exit(ExitError)
}
res, err := Request("POST", "build", bytes.NewBuffer(dat), nil)
@ -390,7 +387,7 @@ func StepBuild() error {
return
}
logrus.Info("StepBuild: Done")
slog.Info("StepBuild: Done")
close(done)
})
@ -409,7 +406,7 @@ func StepProgress() error {
defer res.Body.Close()
if res.StatusCode == http.StatusAccepted {
logrus.Info("StepProgress: Build is pending. Retry")
slog.Info("StepProgress: Build is pending. Retry")
time.Sleep(5 * time.Second)
continue
}
@ -427,7 +424,7 @@ func StepProgress() error {
break
}
logrus.Info("StepProgress: Done")
slog.Info("StepProgress: Done")
close(done)
})
@ -454,7 +451,7 @@ func StepExport() error {
dstDir := filepath.Dir(dstPath)
if _, err := os.Stat(dstDir); os.IsNotExist(err) {
logrus.Infof("StepExport: Destination directory does not exist. Creating %s", dstDir)
slog.Info("StepExport: Destination directory does not exist. Creating", "dir", dstDir)
if err := os.MkdirAll(dstDir, 0700); err != nil {
errs <- fmt.Errorf("StepExport: Failed to create destination directory: %s", err)
}
@ -479,7 +476,7 @@ func StepExport() error {
}
}
logrus.Info("StepExport: Done")
slog.Info("StepExport: Done")
close(done)
})