feat: adopt custom logger
This commit is contained in:
parent
7f97a23945
commit
1a5826149f
6 changed files with 92 additions and 21 deletions
|
@ -1,11 +1,11 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
logger "courgette/internal/logging"
|
||||
runner "courgette/internal/runner"
|
||||
workflow "courgette/internal/workflow"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
func ExecuteWorkflow(configuration Configuration, workflowFile string) error {
|
||||
|
@ -23,19 +23,19 @@ func ExecuteWorkflow(configuration Configuration, workflowFile string) error {
|
|||
workflow, err := workflow.FromYamlFile(workflowFile)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("%#v", err)
|
||||
logger.Error(logger.Red("Failed to read workflow (%s)"), workflowFile)
|
||||
return err
|
||||
}
|
||||
|
||||
validationErrors := workflow.Validate()
|
||||
|
||||
if len(validationErrors) > 0 {
|
||||
for _, err := range validationErrors {
|
||||
log.Printf("Validation error:: %#v", err)
|
||||
logger.Error(logger.Red("Validation error: %s"), err)
|
||||
}
|
||||
|
||||
return errors.New("Jobs encountered errors.")
|
||||
return errors.New("Workflow validation failed.")
|
||||
}
|
||||
|
||||
taskResult := runnerInstance.RunWorkflow(*workflow)
|
||||
|
||||
if !taskResult.HasError() {
|
||||
|
@ -43,7 +43,11 @@ func ExecuteWorkflow(configuration Configuration, workflowFile string) error {
|
|||
}
|
||||
|
||||
for _, job := range taskResult.Context.Jobs {
|
||||
log.Printf("Job %s: %s", job.Id, job.Status)
|
||||
if job.Status == "success" {
|
||||
logger.Info(logger.Green("Job %s: %s"), job.Id, job.Status)
|
||||
} else if job.Status == "failed" {
|
||||
logger.Error(logger.Red("Job %s: %s"), job.Id, job.Status)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Task %s failed with at least 1 error.", taskResult.Id)
|
||||
|
|
|
@ -1,27 +1,32 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
logger "courgette/internal/logging"
|
||||
workflow "courgette/internal/workflow"
|
||||
"errors"
|
||||
"log"
|
||||
)
|
||||
|
||||
func ValidateWorkflow(configuration Configuration, workflowPath string) error {
|
||||
logger.Info("Validating workflow at \"%s\".", workflowPath)
|
||||
|
||||
workflow, err := workflow.FromYamlFile(workflowPath)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("%#v", err)
|
||||
logger.Error(logger.Red("Failed to read and parse workflow from \"%s\"."), workflowPath)
|
||||
return err
|
||||
}
|
||||
|
||||
validationErrors := workflow.Validate()
|
||||
|
||||
if len(validationErrors) > 0 {
|
||||
for _, err := range validationErrors {
|
||||
log.Printf("Validation error:: %#v", err)
|
||||
logger.Error(logger.Red("Validation error: %s"), err)
|
||||
}
|
||||
|
||||
return errors.New("Jobs encountered errors.")
|
||||
return errors.New("Workflow validation failed.")
|
||||
}
|
||||
|
||||
logger.Info(logger.Green(logger.Bold("✅ Workflow \"%s\" is valid!")), workflowPath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
17
internal/logging/colors.go
Normal file
17
internal/logging/colors.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Color utilities to enhance text printed to the screen.
|
||||
//
|
||||
// See: https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
|
||||
package logging
|
||||
|
||||
func Bold(text string) string {
|
||||
return "\033[1m" + text + "\033[0m"
|
||||
}
|
||||
|
||||
func Green(text string) string {
|
||||
return "\033[32m" + text + "\033[0m"
|
||||
}
|
||||
|
||||
func Red(text string) string {
|
||||
return "\033[31m" + text + "\033[0m"
|
||||
}
|
44
internal/logging/logger.go
Normal file
44
internal/logging/logger.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Logging module
|
||||
//
|
||||
// This module is a wrapper around the built-in `log` package
|
||||
// and adds more control around if and how logging shows up
|
||||
// in the code.
|
||||
package logging
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
Info log.Logger
|
||||
Error log.Logger
|
||||
}
|
||||
|
||||
var Log Logger
|
||||
|
||||
// Configures the loggers and initializes each logging level's instance.
|
||||
//
|
||||
// This should be run once and before any logging is done.
|
||||
func ConfigureLogger() {
|
||||
Log = Logger{
|
||||
Info: *log.New(os.Stdout, "[INFO] ", log.Ldate|log.Ltime),
|
||||
Error: *log.New(os.Stderr, "[ERROR] ", log.Ldate|log.Ltime),
|
||||
}
|
||||
}
|
||||
|
||||
func Info(message string, args ...any) {
|
||||
if len(args) == 0 {
|
||||
Log.Info.Print(message)
|
||||
} else {
|
||||
Log.Info.Printf(message, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func Error(message string, args ...any) {
|
||||
if len(args) == 0 {
|
||||
Log.Error.Print(message)
|
||||
} else {
|
||||
Log.Error.Printf(message, args...)
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package runner
|
||||
|
||||
import (
|
||||
logger "courgette/internal/logging"
|
||||
workflow "courgette/internal/workflow"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
@ -35,7 +35,7 @@ func (r *Runner) DeferTask(task func()) {
|
|||
// Each task is executed within a go routine and the call will
|
||||
// wait until all the tasks are completed before returning.
|
||||
func (r *Runner) RunDeferredTasks() {
|
||||
log.Printf("Running %d deferred tasks.", len(r.deferred))
|
||||
logger.Info("Running %d deferred tasks.", len(r.deferred))
|
||||
|
||||
var tracker sync.WaitGroup
|
||||
|
||||
|
@ -84,7 +84,7 @@ func (r *Runner) GetTask(taskId string) *Task {
|
|||
// that the jobs will be executed in, run the jobs's steps and
|
||||
// tear down the container once no longer useful.
|
||||
func (r *Runner) RunWorkflow(workflow workflow.Workflow) Task {
|
||||
log.Printf("Executing workflow: %s", workflow.SourcePath)
|
||||
logger.Info("Executing workflow: %s", workflow.SourcePath)
|
||||
task := r.GetTask(r.AddTask())
|
||||
|
||||
for _, job := range workflow.Jobs {
|
||||
|
@ -94,7 +94,7 @@ func (r *Runner) RunWorkflow(workflow workflow.Workflow) Task {
|
|||
runnerImage := r.GetImageUriByLabel(job.RunsOn)
|
||||
containerName := r.GetContainerName(jobContext.Id)
|
||||
|
||||
log.Printf("Using image %s (label: %s)", runnerImage, job.RunsOn)
|
||||
logger.Info("Using image %s (label: %s)", runnerImage, job.RunsOn)
|
||||
|
||||
if pullError := r.Driver.Pull(runnerImage); pullError != nil {
|
||||
jobContext.SetStatus("failed").SetError(pullError)
|
||||
|
@ -139,13 +139,13 @@ func (r *Runner) RunJobInContainer(imageUri string, containerId string, job work
|
|||
r.Driver.Start(imageUri, containerId)
|
||||
|
||||
r.DeferTask(func() {
|
||||
log.Printf("Started cleaning up %s", containerId)
|
||||
logger.Info("Started cleaning up %s", containerId)
|
||||
r.Driver.Stop(containerId)
|
||||
})
|
||||
|
||||
log.Printf("Started %s", containerId)
|
||||
logger.Info("Started %s", containerId)
|
||||
for _, step := range job.Steps {
|
||||
log.Printf("Run: %s", step.Run)
|
||||
logger.Info("Run: %s", step.Run)
|
||||
|
||||
if err := r.RunCommandInContainer(containerId, step.Run); err != nil {
|
||||
return err
|
||||
|
|
9
main.go
9
main.go
|
@ -3,14 +3,15 @@ package main
|
|||
import (
|
||||
"context"
|
||||
commands "courgette/internal/commands"
|
||||
logger "courgette/internal/logging"
|
||||
"github.com/spf13/cobra"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
var cli = &cobra.Command{
|
||||
Use: "runner",
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
logger.ConfigureLogger()
|
||||
configPath, err := cmd.Flags().GetString("config")
|
||||
|
||||
ctx := cmd.Context()
|
||||
|
@ -19,7 +20,7 @@ var cli = &cobra.Command{
|
|||
configuration, err := commands.NewConfigFromFile(configPath)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed to parse configuration (%s)!", configPath)
|
||||
logger.Error(logger.Red("Failed to parse configuration (%s)!"), configPath)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
@ -38,7 +39,7 @@ var execute = &cobra.Command{
|
|||
config := cmd.Context().Value("config").(*commands.Configuration)
|
||||
|
||||
if err := commands.ExecuteWorkflow(*config, args[0]); err != nil {
|
||||
log.Printf("Failure: %s", err)
|
||||
logger.Error(logger.Red("%s"), err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
|
@ -52,7 +53,7 @@ var validate = &cobra.Command{
|
|||
config := cmd.Context().Value("config").(*commands.Configuration)
|
||||
|
||||
if err := commands.ValidateWorkflow(*config, args[0]); err != nil {
|
||||
log.Printf("Failure: %s", err)
|
||||
logger.Error(logger.Red("%s"), err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue