Use single progressbar, tweak styling

dev
Manuel Bua 2020-07-26 15:10:03 +02:00
parent b33a2b6d16
commit 32e20b13e6
3 changed files with 14 additions and 63 deletions

View File

@ -13,7 +13,6 @@ import (
// Encapsulates progress tracking.
type Progress struct {
progress *mpb.Progress
bars map[string]*mpb.Bar
gbar *mpb.Bar
captureData *captureData
stdCaptureMutex *sync.Mutex
@ -33,32 +32,13 @@ func NewProgress(noColor bool) *Progress {
stdout: &strings.Builder{},
stderr: &strings.Builder{},
colorizer: aurora.NewAurora(!noColor),
bars: make(map[string]*mpb.Bar),
}
return p
}
// Creates and returns a progress bar that tracks request progress for a specific template.
func (p *Progress) SetupTemplateProgressbar(templateId string, requestCount int64, priority int) {
if p.bars[templateId] != nil {
panic(fmt.Sprintf("A progressbar is already bound to [%s].", templateId))
}
color := p.colorizer
uiBarName := templateId
const MaxLen = 40
if len(uiBarName) > MaxLen {
uiBarName = uiBarName[:MaxLen] + ".."
}
uiBarName = fmt.Sprintf(fmt.Sprintf("%%-%ds", MaxLen), "[" + color.BrightYellow(uiBarName).String() + "]")
p.bars[templateId] = p.setupProgressbar(uiBarName, requestCount, priority)
}
// Creates and returns a progress bar that tracks all the requests progress.
// This is only useful when multiple templates are processed within the same run.
func (p *Progress) SetupGlobalProgressbar(hostCount int64, templateCount int, requestCount int64) {
func (p *Progress) InitProgressbar(hostCount int64, templateCount int, requestCount int64) {
if p.gbar != nil {
panic("A global progressbar is already present.")
}
@ -72,7 +52,7 @@ func (p *Progress) SetupGlobalProgressbar(hostCount int64, templateCount int, re
color.Bold(color.Cyan(hostCount)),
pluralize(hostCount, "host", "hosts"))
p.gbar = p.setupProgressbar("[" + barName + "]", requestCount, 0)
p.gbar = p.setupProgressbar("["+barName+"]", requestCount, 0)
}
func pluralize(count int64, singular, plural string) string {
@ -83,22 +63,15 @@ func pluralize(count int64, singular, plural string) string {
}
// Update progress tracking information and increments the request counter by one unit.
// If a global progress bar is present it will be updated as well.
func (p *Progress) Update(templateId string) {
p.bars[templateId].Increment()
if p.gbar != nil {
p.gbar.Increment()
}
func (p *Progress) Update() {
p.gbar.Increment()
}
// Drops the specified number of requests from the progress bar total.
// This may be the case when uncompleted requests are encountered and shouldn't be part of the total count.
// If a global progress bar is present it will be updated as well.
func (p *Progress) Drop(templateId string, count int64) {
p.bars[templateId].IncrInt64(count)
if p.gbar != nil {
p.gbar.IncrInt64(count)
}
func (p *Progress) Drop(count int64) {
// mimic dropping by incrementing the completed requests
p.gbar.IncrInt64(count)
}
// Ensures that a progress bar's total count is up-to-date if during an enumeration there were uncompleted requests and
@ -120,36 +93,16 @@ func (p *Progress) setupProgressbar(name string, total int64, priority int) *mpb
mpb.PrependDecorators(
decor.Name(name, decor.WCSyncSpaceR),
decor.CountersNoUnit(color.BrightBlue(" %d/%d").String(), decor.WCSyncSpace),
customFormattedPercentage(color.Bold("%3.0f%%").String(), decor.WCSyncSpace),
decor.NewPercentage(color.Bold("%d").String(), decor.WCSyncSpace),
),
mpb.AppendDecorators(
decor.AverageSpeed(0, color.BrightBlue("%.2f r/s ").String(), decor.WCSyncSpace),
decor.AverageSpeed(0, color.BrightYellow("%.2f").Bold().String() + color.BrightYellow("r/s").String(), decor.WCSyncSpace),
decor.Elapsed(decor.ET_STYLE_GO, decor.WCSyncSpace),
decor.AverageETA(decor.ET_STYLE_GO, decor.WCSyncSpace),
),
)
}
// Helper function to calculate percentage
func computePercentage(total, current int64, width int) float64 {
if total <= 0 {
return 0
}
if current >= total {
return float64(width)
}
return float64(int64(width)*current) / float64(total)
}
// Percentage decorator with custom formatting
func customFormattedPercentage(format string, wcc ...decor.WC) decor.Decorator {
f := func(s decor.Statistics) string {
p := computePercentage(s.Total, s.Current, 100)
return fmt.Sprintf(format, p)
}
return decor.Any(f, wcc...)
}
// Starts capturing stdout and stderr instead of producing visual output that may interfere with the progress bars.
func (p *Progress) StartStdCapture() {
p.stdCaptureMutex.Lock()

View File

@ -256,8 +256,6 @@ func (r *Runner) RunEnumeration() {
barIndex++
template := t.(*templates.Template)
totalRequests += template.GetHTTPRequestsCount()
// track per-template progress
p.SetupTemplateProgressbar(template.ID, r.inputCount*template.GetHTTPRequestsCount(), barIndex)
parsedTemplates = append(parsedTemplates, match)
default:
gologger.Errorf("Could not parse file '%s': %s\n", match, err)
@ -268,7 +266,7 @@ func (r *Runner) RunEnumeration() {
allTemplates = parsedTemplates
// track global progress
p.SetupGlobalProgressbar(r.inputCount, templateCount, r.inputCount*totalRequests)
p.InitProgressbar(r.inputCount, templateCount, r.inputCount*totalRequests)
var (
wgtemplates sync.WaitGroup

View File

@ -110,7 +110,7 @@ func (e *HTTPExecuter) ExecuteHTTP(p *progress.Progress, URL string) (result Res
if e.bulkHttpRequest.HasGenerator(URL) {
return
}
remaining := e.template.GetHTTPRequestsCount()
e.bulkHttpRequest.CreateGenerator(URL)
@ -118,19 +118,19 @@ func (e *HTTPExecuter) ExecuteHTTP(p *progress.Progress, URL string) (result Res
httpRequest, err := e.bulkHttpRequest.MakeHTTPRequest(URL, dynamicvalues, e.bulkHttpRequest.Current(URL))
if err != nil {
result.Error = errors.Wrap(err, "could not build http request")
p.Drop(e.template.ID, remaining)
p.Drop(remaining)
return
}
err = e.handleHTTP(p, URL, httpRequest, dynamicvalues, &result)
if err != nil {
result.Error = errors.Wrap(err, "could not handle http request")
p.Drop(e.template.ID, remaining)
p.Drop(remaining)
return
}
e.bulkHttpRequest.Increment(URL)
p.Update(e.template.ID)
p.Update()
remaining--
}