Skip to content

Commit

Permalink
Print errors to stderr
Browse files Browse the repository at this point in the history
Signed-off-by: Javier Romero <root@jromero.codes>
  • Loading branch information
jromero committed Dec 28, 2019
1 parent be2137d commit cb29a62
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 154 deletions.
4 changes: 2 additions & 2 deletions internal/app/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ func (i *Image) Run(ctx context.Context, docker *client.Client, ports []string)
ctx,
docker,
ctr.ID,
logging.GetInfoWriter(i.Logger),
logging.GetInfoErrorWriter(i.Logger),
logging.GetOutWriter(i.Logger),
logging.GetErrorWriter(i.Logger),
); err != nil {
return errors.Wrap(err, "run container")
}
Expand Down
2 changes: 1 addition & 1 deletion internal/blob/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (d *downloader) downloadAsStream(ctx context.Context, uri string, etag stri

if resp.StatusCode >= 200 && resp.StatusCode < 300 {
d.logger.Infof("Downloading from %s", style.Symbol(uri))
return withProgress(logging.GetInfoWriter(d.logger), resp.Body, resp.ContentLength), resp.Header.Get("Etag"), nil
return withProgress(logging.GetOutWriter(d.logger), resp.Body, resp.ContentLength), resp.Header.Get("Etag"), nil
}

if resp.StatusCode == 304 {
Expand Down
4 changes: 2 additions & 2 deletions internal/build/phase.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ func (p *Phase) Run(ctx context.Context) error {
ctx,
p.docker,
p.ctr.ID,
logging.NewPrefixWriter(logging.GetInfoWriter(p.logger), p.name),
logging.NewPrefixWriter(logging.GetInfoErrorWriter(p.logger), p.name),
logging.NewPrefixWriter(logging.GetOutWriter(p.logger), p.name),
logging.NewPrefixWriter(logging.GetErrorWriter(p.logger), p.name),
)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/image/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (f *Fetcher) pullImage(ctx context.Context, imageID string) error {
if err != nil {
return err
}
writer := logging.GetInfoWriter(f.logger)
writer := logging.GetOutWriter(f.logger)
type descriptor interface {
Fd() uintptr
}
Expand Down
146 changes: 79 additions & 67 deletions internal/logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,115 +17,127 @@ const (
errorLevelText = "ERROR: "
warnLevelText = "Warning: "
lineFeed = '\n'

// log level to use when quiet is true
quietLevel = log.WarnLevel
// log level to use when debug is true
verboseLevel = log.DebugLevel
// time format the out logging uses
timeFmt = "2006/01/02 15:04:05.000000"
)

// handler implementation.
type handler struct {
type LogWithWriters struct {
sync.Mutex
writer io.Writer
log.Logger
wantTime bool
timer func() time.Time
clock func() time.Time
out io.Writer
errOut io.Writer
}

func formatLevel(ll log.Level) string {
switch ll {
case log.ErrorLevel:
return style.Error(errorLevelText)
case log.WarnLevel:
return style.Warn(warnLevelText)
func WithClock(clock func() time.Time) func(writers *LogWithWriters) {
return func(logger *LogWithWriters) {
logger.clock = clock
}

return ""
}

// preserve behavior of other loggers
func appendMissingLineFeed(msg string) string {
buff := []byte(msg)
if len(buff) == 0 || buff[len(buff)-1] != lineFeed {
buff = append(buff, lineFeed)
// NewLogWithWriters creates a logger to be used with pack CLI.
func NewLogWithWriters(stdout, stderr io.Writer, opts ...func(*LogWithWriters)) *LogWithWriters {
lw := &LogWithWriters{
Logger: log.Logger{
Level: log.InfoLevel,
},
wantTime: false,
clock: time.Now,
out: stdout,
errOut: stderr,
}
return string(buff)
lw.Logger.Handler = lw

for _, opt := range opts {
opt(lw)
}

return lw
}

// HandleLog supports behavior that is unique to Pack CLI, namely toggling colors and timestamps.
func (h *handler) HandleLog(e *log.Entry) error {
h.Lock()
defer h.Unlock()
func (lw *LogWithWriters) HandleLog(e *log.Entry) error {
lw.Lock()
defer lw.Unlock()

if h.wantTime {
ts := h.timer().Format(timeFmt)
_, _ = fmt.Fprint(h.writer, appendMissingLineFeed(fmt.Sprintf("%s %s%s", ts, formatLevel(e.Level), e.Message)))
if lw.Level > e.Level {
return nil
}

_, _ = fmt.Fprint(h.writer, appendMissingLineFeed(fmt.Sprintf("%s%s", formatLevel(e.Level), e.Message)))
writer := lw.out
if e.Level == log.ErrorLevel {
writer = lw.errOut
}

return nil
}
if lw.wantTime {
ts := lw.clock().Format(timeFmt)
_, _ = fmt.Fprint(writer, appendMissingLineFeed(fmt.Sprintf("%s %s%s", ts, formatLevel(e.Level), e.Message)))
return nil
}

type logWithWriters struct {
log.Logger
out io.Writer
errOut io.Writer
handler *handler
_, _ = fmt.Fprint(writer, appendMissingLineFeed(fmt.Sprintf("%s%s", formatLevel(e.Level), e.Message)))

return nil
}

func (lw *logWithWriters) Writer() io.Writer {
func (lw *LogWithWriters) Writer() io.Writer {
return lw.out
}

// DebugInfoWriter - returns stderr if log level is not set to quiet.
func (lw *logWithWriters) InfoErrorWriter() io.Writer {
if lw.Level == log.InfoLevel ||
lw.Level == log.DebugLevel {
return lw.errOut
}
return ioutil.Discard
// ErrorWriter returns the writer for error messages.
func (lw *LogWithWriters) ErrorWriter() io.Writer {
return lw.errOut
}

// InfoWriter returns stdout if logging is not set to quiet.
func (lw *logWithWriters) InfoWriter() io.Writer {
if lw.Level == log.InfoLevel ||
lw.Level == log.DebugLevel {
return lw.out
// OutWriter returns the writer for standard messages.
func (lw *LogWithWriters) OutWriter() io.Writer {
if lw.Level >= quietLevel {
return ioutil.Discard
}
return ioutil.Discard

return lw.out
}

func (lw *logWithWriters) WantTime(f bool) {
lw.handler.wantTime = f
func (lw *LogWithWriters) WantTime(f bool) {
lw.wantTime = f
}

func (lw *logWithWriters) WantQuiet(f bool) {
func (lw *LogWithWriters) WantQuiet(f bool) {
if f {
lw.Level = log.WarnLevel
lw.Level = quietLevel
}
}

func (lw *logWithWriters) WantVerbose(f bool) {
func (lw *LogWithWriters) WantVerbose(f bool) {
if f {
lw.Level = log.DebugLevel
lw.Level = verboseLevel
}
}

func (lw *logWithWriters) IsVerbose() bool {
func (lw *LogWithWriters) IsVerbose() bool {
return lw.Level == log.DebugLevel
}

// NewLogWithWriters creates a logger to be used with pack CLI.
func NewLogWithWriters(stdout, stderr io.Writer) *logWithWriters { //nolint:golint,gosimple
hnd := &handler{
writer: stdout,
timer: time.Now,
func formatLevel(ll log.Level) string {
switch ll {
case log.ErrorLevel:
return style.Error(errorLevelText)
case log.WarnLevel:
return style.Warn(warnLevelText)
}

return ""
}

// preserve behavior of other loggers
func appendMissingLineFeed(msg string) string {
buff := []byte(msg)
if len(buff) == 0 || buff[len(buff)-1] != lineFeed {
buff = append(buff, lineFeed)
}
var lw logWithWriters
lw.handler = hnd
lw.out = hnd.writer
lw.errOut = stderr
lw.Logger.Handler = hnd
lw.Logger.Level = log.InfoLevel
return &lw
return string(buff)
}
Loading

0 comments on commit cb29a62

Please sign in to comment.