This repository has been archived by the owner on Jun 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added progress display during discovery
* feat: added progress display during discovery * feat: moved log to own library (prep for future improvement) * update discovery screenshot to illustrate progress during discovery
- Loading branch information
Showing
11 changed files
with
297 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
Copyright © 2021 Opsani <[email protected]> | ||
This file is part of https://github.com/opsani/opsani-ignite | ||
*/ | ||
|
||
package log | ||
|
||
import ( | ||
"io" | ||
|
||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
// SetOutput sets the standard logger output. | ||
func SetOutput(out io.Writer) { | ||
logrus.SetOutput(out) | ||
} | ||
|
||
// SetupLogLevel sets up the standard logger level in accordance with command line options. | ||
func SetupLogLevel(showDebug bool, suppressWarnings bool) { | ||
if showDebug { | ||
logrus.SetLevel(logrus.TraceLevel) | ||
} else if suppressWarnings { | ||
logrus.SetLevel(logrus.ErrorLevel) | ||
} else { | ||
logrus.SetLevel(logrus.InfoLevel) | ||
} | ||
} | ||
|
||
// Trace logs a message at level Trace on the standard logger. | ||
func Trace(args ...interface{}) { | ||
logrus.Trace(args...) | ||
} | ||
|
||
// Info logs a message at level Info on the standard logger. | ||
func Info(args ...interface{}) { | ||
logrus.Info(args...) | ||
} | ||
|
||
// Print logs a message at level Info on the standard logger. | ||
func Print(args ...interface{}) { | ||
logrus.Print(args...) | ||
} | ||
|
||
// Warn logs a message at level Warning on the standard logger. | ||
func Warn(args ...interface{}) { | ||
logrus.Warn(args...) | ||
} | ||
|
||
// Error logs a message at level Error on the standard logger. | ||
func Error(args ...interface{}) { | ||
logrus.Error(args...) | ||
} | ||
|
||
// Fatal logs a message at level Fatal on the standard logger. | ||
func Fatal(args ...interface{}) { | ||
logrus.Fatal(args...) | ||
} | ||
|
||
// Tracef logs a message at level Trace on the standard logger. | ||
func Tracef(format string, args ...interface{}) { | ||
logrus.Tracef(format, args...) | ||
} | ||
|
||
// Infof logs a message at level Info on the standard logger. | ||
func Infof(format string, args ...interface{}) { | ||
logrus.Infof(format, args...) | ||
} | ||
|
||
// Printf logs a message at level Info on the standard logger. | ||
func Printf(format string, args ...interface{}) { | ||
logrus.Printf(format, args...) | ||
} | ||
|
||
// Warnf logs a message at level Warning on the standard logger. | ||
func Warnf(format string, args ...interface{}) { | ||
logrus.Warnf(format, args...) | ||
} | ||
|
||
// Errorf logs a message at level Error on the standard logger. | ||
func Errorf(format string, args ...interface{}) { | ||
logrus.Errorf(format, args...) | ||
} | ||
|
||
// Fatalf logs a message at level Fatal on the standard logger. | ||
func Fatalf(format string, args ...interface{}) { | ||
logrus.Fatalf(format, args...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
Copyright © 2021 Opsani <[email protected]> | ||
This file is part of https://github.com/opsani/opsani-ignite | ||
*/ | ||
|
||
package log | ||
|
||
import ( | ||
"fmt" | ||
"math" | ||
"os" | ||
"sync" | ||
"time" | ||
) | ||
|
||
// ProgressInfo holds the values used to show progress | ||
type ProgressInfo struct { | ||
NamespacesTotal int | ||
NamespacesDone int | ||
WorkloadsTotal int | ||
WorkloadsDone int | ||
} | ||
|
||
// ProgressUpdateFunc is the signature of the progress update callback function. | ||
// The update may set absolute or relative values (relative values are +=). | ||
type ProgressUpdateFunc func(info ProgressInfo, relative bool) | ||
|
||
// RunnerFunc is the signature for the function to run with GoWithProgress | ||
type RunnerFunc func(infoCallback ProgressUpdateFunc) error | ||
|
||
type progressState struct { | ||
lock sync.Mutex | ||
info ProgressInfo | ||
} | ||
|
||
func (s *progressState) updateInfo(info ProgressInfo, relative bool) { | ||
s.lock.Lock() | ||
if relative { | ||
s.info.NamespacesTotal += info.NamespacesTotal | ||
s.info.NamespacesDone += info.NamespacesDone | ||
s.info.WorkloadsTotal += info.WorkloadsTotal | ||
s.info.WorkloadsDone += info.WorkloadsDone | ||
} else { | ||
s.info = info | ||
} | ||
s.lock.Unlock() | ||
} | ||
|
||
func (s *progressState) renderProgress(startTime time.Time, final bool) { | ||
// safely grab a copy of the info | ||
s.lock.Lock() | ||
info := s.info | ||
s.lock.Unlock() | ||
|
||
// display info as progress | ||
now := time.Now() | ||
elapsed := math.Round(now.Sub(startTime).Seconds()*10) / 10 | ||
fmt.Fprintf(os.Stderr, "\rCollecting data (%.1fs): %v of %v namespace(s) and %v of %v application(s) completed... ", | ||
elapsed, info.NamespacesDone, info.NamespacesTotal, info.WorkloadsDone, info.WorkloadsTotal) | ||
if final { | ||
fmt.Fprintf(os.Stderr, "done.\n\n") | ||
} | ||
} | ||
|
||
// GoWithProgress executes the given runner function as a goroutine while showing progress | ||
func GoWithProgress(runner RunnerFunc) error { | ||
done := make(chan error) | ||
state := progressState{} | ||
state.renderProgress(time.Now(), false) | ||
|
||
// run the runner function and notify when done | ||
go func() { | ||
err := runner(func(info ProgressInfo, relative bool) { state.updateInfo(info, relative) }) | ||
done <- err | ||
}() | ||
|
||
startTime := time.Now() | ||
var runnerError error | ||
loop: | ||
for { | ||
select { | ||
case err := <-done: | ||
runnerError = err | ||
break loop | ||
default: | ||
state.renderProgress(startTime, false) | ||
time.Sleep(time.Duration(100 * time.Millisecond)) | ||
} | ||
} | ||
close(done) | ||
state.renderProgress(startTime, true) | ||
|
||
return runnerError | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
Copyright © 2021 Opsani <[email protected]> | ||
This file is part of https://github.com/opsani/opsani-ignite | ||
*/ | ||
|
||
package log | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
func job_abs(update ProgressUpdateFunc) error { | ||
apps := 0 | ||
for n := 0; n < 5; n++ { | ||
for a := 0; a < 7; a++ { | ||
update(ProgressInfo{ | ||
NamespacesTotal: 5, | ||
NamespacesDone: n, | ||
WorkloadsTotal: (n + 1) * 7, | ||
WorkloadsDone: apps, | ||
}, false) | ||
apps++ | ||
time.Sleep(325 * time.Millisecond) | ||
} | ||
} | ||
update(ProgressInfo{ | ||
NamespacesTotal: 5, | ||
NamespacesDone: 5, | ||
WorkloadsTotal: 5 * 7, | ||
WorkloadsDone: apps, | ||
}, false) | ||
return nil | ||
} | ||
|
||
func job_rel(update ProgressUpdateFunc) error { | ||
update(ProgressInfo{ | ||
NamespacesTotal: 5, | ||
NamespacesDone: 0, | ||
WorkloadsTotal: 5 * 7, | ||
WorkloadsDone: 0, | ||
}, false) | ||
for n := 0; n < 5; n++ { | ||
for a := 0; a < 7; a++ { | ||
update(ProgressInfo{WorkloadsDone: 1}, true) | ||
time.Sleep(325 * time.Millisecond) | ||
} | ||
update(ProgressInfo{NamespacesDone: 1}, true) | ||
} | ||
return nil | ||
} | ||
|
||
|
||
func DemoProgress() error { | ||
if err := GoWithProgress(job_abs); err != nil { | ||
return err | ||
} | ||
if err := GoWithProgress(job_rel); err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.