cmd/cli: better error message when log file is empty

While at it, also record the size of logs being sent in debug/error
message.
This commit is contained in:
Cuong Manh Le
2024-12-27 16:28:56 +07:00
committed by Cuong Manh Le
parent ff43c74d8d
commit 5a566c028a
5 changed files with 45 additions and 12 deletions
+22 -9
View File
@@ -19,6 +19,7 @@ import (
"strings"
"time"
"github.com/docker/go-units"
"github.com/kardianos/service"
"github.com/minio/selfupdate"
"github.com/olekukonko/tablewriter"
@@ -48,17 +49,24 @@ func initLogCmd() *cobra.Command {
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK:
mainLog.Load().Notice().Msg("runtime logs sent successfully")
case http.StatusServiceUnavailable:
mainLog.Load().Warn().Msg("runtime logs could only be sent once per minute")
default:
buf, err := io.ReadAll(resp.Body)
if err != nil {
mainLog.Load().Fatal().Err(err).Msg("failed to read response body")
}
mainLog.Load().Error().Msg("failed to send logs")
mainLog.Load().Error().Msg(string(buf))
return
case http.StatusMovedPermanently:
mainLog.Load().Warn().Msg("runtime debugs log is not enabled")
mainLog.Load().Warn().Msg(`ctrld may be run without "--cd" flag or logging is already enabled`)
return
}
var logs logSentResponse
if err := json.NewDecoder(resp.Body).Decode(&logs); err != nil {
mainLog.Load().Fatal().Err(err).Msg("failed to decode sent logs result")
}
size := units.BytesSize(float64(logs.Size))
if logs.Error == "" {
mainLog.Load().Notice().Msgf("runtime logs sent successfully (%s)", size)
} else {
mainLog.Load().Error().Msgf("failed to send logs (%s)", size)
mainLog.Load().Error().Msg(logs.Error)
}
},
}
@@ -85,6 +93,11 @@ func initLogCmd() *cobra.Command {
return
case http.StatusBadRequest:
mainLog.Load().Warn().Msg("runtime debugs log is not available")
buf, err := io.ReadAll(resp.Body)
if err != nil {
mainLog.Load().Fatal().Err(err).Msg("failed to read response body")
}
mainLog.Load().Warn().Msgf("ctrld process response:\n\n%s\n", string(buf))
return
case http.StatusOK:
}
+9 -3
View File
@@ -217,7 +217,7 @@ func (p *prog) registerControlServerHandler() {
p.cs.register(viewLogsPath, http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) {
data, err := p.logContent()
if err != nil {
w.WriteHeader(http.StatusBadRequest)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if len(data) == 0 {
@@ -236,7 +236,7 @@ func (p *prog) registerControlServerHandler() {
}
data, err := p.logContent()
if err != nil {
w.WriteHeader(http.StatusBadRequest)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if len(data) == 0 {
@@ -249,11 +249,17 @@ func (p *prog) registerControlServerHandler() {
LogFile: logFile,
}
mainLog.Load().Debug().Msg("sending log file to ControlD server")
resp := logSentResponse{Size: len(data)}
if err := controld.SendLogs(req, cdDev); err != nil {
mainLog.Load().Error().Msgf("could not send log file to ControlD server: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
resp.Error = err.Error()
w.WriteHeader(http.StatusInternalServerError)
} else {
mainLog.Load().Debug().Msg("sending log file successfully")
w.WriteHeader(http.StatusOK)
}
if err := json.NewEncoder(w).Encode(&resp); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
p.internalLogSent = time.Now()
}))
+11
View File
@@ -24,6 +24,11 @@ type logViewResponse struct {
Data string `json:"data"`
}
type logSentResponse struct {
Size int `json:"size"`
Error string `json:"error"`
}
// logWriter is an internal buffer to keep track of runtime log when no logging is enabled.
type logWriter struct {
mu sync.Mutex
@@ -118,6 +123,9 @@ func (p *prog) logContent() ([]byte, error) {
lw.mu.Lock()
data = lw.buf.Bytes()
lw.mu.Unlock()
if len(data) == 0 {
return nil, errors.New("internal log is empty")
}
} else {
if p.cfg.Service.LogPath == "" {
return nil, nil
@@ -127,6 +135,9 @@ func (p *prog) logContent() ([]byte, error) {
return nil, err
}
data = buf
if len(data) == 0 {
return nil, errors.New("log file is empty")
}
}
return data, nil
}