فهرست منبع

feature: Save logs! #174 (#300)

James Read 2 سال پیش
والد
کامیت
8fd98874e2
2فایلهای تغییر یافته به همراه63 افزوده شده و 0 حذف شده
  1. 7 0
      internal/config/config.go
  2. 56 0
      internal/executor/executor.go

+ 7 - 0
internal/config/config.go

@@ -22,6 +22,7 @@ type Action struct {
 	MaxRate                []RateSpec
 	Arguments              []ActionArgument
 	PopupOnStart           string
+	SaveLogs               SaveLogsConfig
 }
 
 // ActionArgument objects appear on Actions.
@@ -119,10 +120,16 @@ type Config struct {
 	InsecureAllowDumpActionMap      bool
 	InsecureAllowDumpJwtClaims      bool
 	Prometheus                      PrometheusConfig
+	SaveLogs                        SaveLogsConfig
 
 	usedConfigDir string
 }
 
+type SaveLogsConfig struct {
+	ResultsDirectory string
+	OutputDirectory  string
+}
+
 type LogDebugOptions struct {
 	SingleFrontendRequests       bool
 	SingleFrontendRequestHeaders bool

+ 56 - 0
internal/executor/executor.go

@@ -9,13 +9,16 @@ import (
 
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/client_golang/prometheus/promauto"
+	"gopkg.in/yaml.v3"
 
 	"bytes"
 	"context"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"os"
 	"os/exec"
+	"path"
 	"runtime"
 	"strings"
 	"sync"
@@ -105,6 +108,7 @@ func DefaultExecutor() *Executor {
 		stepExec,
 		stepExecAfter,
 		stepLogFinish,
+		stepSaveLog,
 		stepTrigger,
 	}
 
@@ -324,6 +328,8 @@ func stepLogStart(req *ExecutionRequest) bool {
 }
 
 func stepLogFinish(req *ExecutionRequest) bool {
+	req.logEntry.ExecutionFinished = true
+
 	log.WithFields(log.Fields{
 		"actionTitle": req.logEntry.ActionTitle,
 		"stdout":      req.logEntry.Stdout,
@@ -460,3 +466,53 @@ func stepTrigger(req *ExecutionRequest) bool {
 
 	return true
 }
+
+func stepSaveLog(req *ExecutionRequest) bool {
+	filename := fmt.Sprintf("%v.%v.%v", req.logEntry.ActionTitle, req.logEntry.DatetimeStarted.Unix(), req.logEntry.ExecutionTrackingID)
+
+	saveLogResults(req, filename)
+	saveLogOutput(req, filename)
+
+	return true
+}
+
+func firstNonEmpty(one, two string) string {
+	if one != "" {
+		return one
+	}
+
+	return two
+}
+
+func saveLogResults(req *ExecutionRequest, filename string) {
+	dir := firstNonEmpty(req.Action.SaveLogs.ResultsDirectory, req.Cfg.SaveLogs.ResultsDirectory)
+
+	if dir != "" {
+		data, err := yaml.Marshal(req.logEntry)
+
+		if err != nil {
+			log.Warnf("%v", err)
+		}
+
+		filepath := path.Join(dir, filename+".yaml")
+		err = ioutil.WriteFile(filepath, data, 0644)
+
+		if err != nil {
+			log.Warnf("%v", err)
+		}
+	}
+}
+
+func saveLogOutput(req *ExecutionRequest, filename string) {
+	dir := firstNonEmpty(req.Action.SaveLogs.OutputDirectory, req.Cfg.SaveLogs.OutputDirectory)
+
+	if dir != "" {
+		data := req.logEntry.Stdout + "\n" + req.logEntry.Stderr
+		filepath := path.Join(dir, filename+".log")
+		err := ioutil.WriteFile(filepath, []byte(data), 0644)
+
+		if err != nil {
+			log.Warnf("%v", err)
+		}
+	}
+}