Skip to content

Commit

Permalink
changed spinner to progres bar and added info to results
Browse files Browse the repository at this point in the history
  • Loading branch information
eze-kiel committed Apr 8, 2021
1 parent 0663175 commit 27c6c0a
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 33 deletions.
74 changes: 54 additions & 20 deletions cmd/slowql-replayer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ import (
"fmt"
"io"
"os"
"strconv"
"strings"
"sync"
"syscall"
"time"

"github.com/briandowns/spinner"
"github.com/cheggaaa/pb/v3"
"github.com/devops-works/slowql"
"github.com/devops-works/slowql/cmd/slowql-replayer/pprof"
"github.com/devops-works/slowql/query"
Expand All @@ -39,6 +38,7 @@ type options struct {
usePass bool
noDryRun bool
showErrors bool
hidePB bool
}

type database struct {
Expand Down Expand Up @@ -81,6 +81,7 @@ func main() {
flag.BoolVar(&opt.usePass, "p", false, "Use a password to connect to database")
flag.BoolVar(&opt.noDryRun, "no-dry-run", false, "Replay the requests on the database for real")
flag.BoolVar(&opt.showErrors, "show-errors", false, "Show SQL errors when they occur")
flag.BoolVar(&opt.hidePB, "hide-progress", false, "Hide progress bar while replaying")
flag.Parse()

if errs := opt.parse(); len(errs) > 0 {
Expand Down Expand Up @@ -126,11 +127,16 @@ func main() {
db.logger.Warn("replaying with dry run")
}

num, err := getQueriesNumber(db.kind, opt.file)
if err != nil {
db.logger.Fatalf("cannot get total number of queries: %s", err)
}

db.logger.Infof("replay started on %s", time.Now().Format("Mon Jan 2 15:04:05"))
db.logger.Infof("estimated time of end: %s", time.Now().
Add(time.Duration(float64(realExec)/db.speedFactor)).Format("Mon Jan 2 15:04:05"))

r, err := db.replay(f)
r, err := db.replay(f, num, opt.hidePB)
if err != nil {
db.logger.Fatalf("cannot replay %s: %s", opt.kind, err)
}
Expand Down Expand Up @@ -244,13 +250,13 @@ func (o options) createDB() (*database, error) {
db.logger.Debugf("db max idle conns: %d", maxIdle)

db.showErrors = o.showErrors
db.logger.Debugf("show errors: %s", db.showErrors)
db.logger.Debugf("show errors: %v", db.showErrors)

return &db, nil
}

// replay replays the queries from a slow query log file to a database
func (db *database) replay(f io.Reader) (results, error) {
func (db *database) replay(f io.Reader, totQ int, hidePB bool) (results, error) {
var r results

p := slowql.NewParser(db.kind, f)
Expand All @@ -268,12 +274,18 @@ func (db *database) replay(f io.Reader) (results, error) {
go db.worker(jobs, errors, queries, db.noDryRun, &wg)
}
db.logger.Debugf("created %d workers successfully", workersCounter)

db.logger.Debug("starting errors collector")
go r.errorsCollector(errors, db.showErrors)

s := newSpinner(34)
s.Start()
go updateSpinner(s, queries)
var bar *pb.ProgressBar
// start all the progress bar stuff is asked
if !hidePB {
tmpl := `{{counters .}} {{ bar . "[" ("▉" | green) (cycle . "▉" " " | green ) "." "]"}} {{speed .}} {{percent .}}`
bar = pb.ProgressBarTemplate(tmpl).Start(totQ)
bar.SetRefreshRate(400 * time.Millisecond)
go updateBar(bar, queries)
}

firstPass := true

Expand All @@ -289,7 +301,7 @@ func (db *database) replay(f io.Reader) (results, error) {

r.queries++

// We need a reference time
// we need a reference time
if firstPass {
firstPass = false
reference = q.Time
Expand All @@ -310,9 +322,13 @@ func (db *database) replay(f io.Reader) (results, error) {
close(errors)
db.logger.Debug("closed errors channel")

s.Stop()
close(queries)
db.logger.Debug("spinned stopped and update channel closed")
// terminate all the stuff related to the progress bar if it has been
// created
if !hidePB {
bar.Finish()
close(queries)
db.logger.Debug("progress bar stopped and update channel closed")
}

r.duration = time.Since(start)
db.logger.Infof("replay ended on %s", time.Now().Format("Mon Jan 2 15:04:05"))
Expand Down Expand Up @@ -342,6 +358,7 @@ func (r results) show(o options) {
=-= Results =-=
Replay duration: %s
real duration: %s
Log file: %s
Dry run: %v
Workers: %d
Expand All @@ -363,6 +380,7 @@ Statistics
%s: the replayer may take a little more time due to the numerous conditions that are verified during the replay.
`,
Bold(r.duration),
Bold(r.realDuration),
Bold(o.file),
Bold(r.dryRun),
Bold(o.workers),
Expand All @@ -383,19 +401,13 @@ Statistics
)
}

func newSpinner(t int) *spinner.Spinner {
return spinner.New(spinner.CharSets[t], 100*time.Millisecond)
}

func updateSpinner(s *spinner.Spinner, newQueries chan int) {
var queries int
func updateBar(bar *pb.ProgressBar, newQueries chan int) {
for {
_, ok := <-newQueries
if !ok {
return
}
queries++
s.Suffix = " queries replayed: " + strconv.Itoa(queries)
bar.Increment()
}
}

Expand Down Expand Up @@ -508,3 +520,25 @@ func getRealTime(k, file string) (time.Duration, error) {
return time.Duration(0), nil
}
}

func getQueriesNumber(k slowql.Kind, f string) (int, error) {
var queriesCounter int

fd, err := os.Open(f)
if err != nil {
return -1, err
}

p := slowql.NewParser(k, fd)

var q query.Query
for {
q = p.GetNext()
if (q == query.Query{}) {
break
}
queriesCounter++
}
fd.Close()
return queriesCounter, nil
}
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ module github.com/devops-works/slowql
go 1.15

require (
github.com/briandowns/spinner v1.12.0
github.com/cheggaaa/pb/v3 v3.0.8
github.com/go-sql-driver/mysql v1.5.0
github.com/kr/pretty v0.1.0 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/sirupsen/logrus v1.8.0
github.com/stretchr/testify v1.4.0 // indirect
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
Expand Down
30 changes: 19 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
github.com/briandowns/spinner v1.12.0 h1:72O0PzqGJb6G3KgrcIOtL/JAGGZ5ptOMCn9cUHmqsmw=
github.com/briandowns/spinner v1.12.0/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ=
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA=
github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
Expand All @@ -16,23 +18,29 @@ github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczG
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down

0 comments on commit 27c6c0a

Please sign in to comment.