Skip to content

Commit

Permalink
fix #3: add GetServerMeta method to package
Browse files Browse the repository at this point in the history
  • Loading branch information
eze-kiel committed Mar 9, 2021
1 parent 48fe1fb commit b4aeb06
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 5 deletions.
18 changes: 16 additions & 2 deletions cmd/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ func main() {
}

p := slowql.NewParser(slowql.MySQL, fd)
srv := p.GetServerMeta()
showServer(srv)

var count int
start := time.Now()
for {
Expand All @@ -28,15 +31,15 @@ func main() {
break
}

// show(q)
// showQueries(q)

count++
}
elapsed := time.Since(start)
fmt.Printf("\nparsed %d queries in %s\n", count, elapsed)
}

func show(q slowql.Query) {
func showQueries(q slowql.Query) {
fmt.Printf("Time: %s\nUser: %s\nHost: %s\nID: %d\nSchema: %s\nLast_errno: %d\nKilled: %d\nQuery_time: %f\nLock_time: %f\nRows_sent: %d\nRows_examined: %d\nRows_affected: %d\nBytes_sent: %d\nQuery: %s\n",
q.Time,
q.User,
Expand All @@ -54,3 +57,14 @@ func show(q slowql.Query) {
q.Query,
)
}

func showServer(srv slowql.Server) {
fmt.Printf("Binary: %s\nVersion short: %s\nVersion: %s\nVersion description: %s\nSocket: %s\nPort: %d\n",
srv.Binary,
srv.VersionShort,
srv.Version,
srv.VersionDescription,
srv.Socket,
srv.Port,
)
}
37 changes: 37 additions & 0 deletions mariadb.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package slowql

import (
"regexp"
"strconv"
"strings"
"time"
Expand All @@ -13,6 +14,7 @@ const MariaDB Kind = 1

type mariadbParser struct {
wl chan Query
sm chan Server
}

func (p *mariadbParser) parseBlocs(rawBlocs chan []string) {
Expand Down Expand Up @@ -135,3 +137,38 @@ func (q *Query) parseMariaDBHeader(line string) {
}
}
}

func (p *mariadbParser) parseServerMeta(lines chan []string) {
for {
select {
case header := <-lines:
versions := header[0]
net := header[1]

// Parse server information
versionre := regexp.MustCompile(`^([^,]+),\s+Version:\s+([0-9\.]+)([A-Za-z0-9-]+)\s+\((.*)\)\. started`)
matches := versionre.FindStringSubmatch(versions)

if len(matches) != 5 {
srv.Binary = "unable to parse line"
srv.VersionShort = srv.Binary
srv.Version = srv.Binary
srv.VersionDescription = srv.Binary
srv.Port = 0
srv.Socket = srv.Binary
}

srv.Binary = matches[1]
srv.VersionShort = matches[2]
srv.Version = srv.VersionShort + matches[3]
srv.VersionDescription = matches[4]
srv.Port, _ = strconv.Atoi(strings.Split(net, " ")[2])
srv.Socket = strings.TrimLeft(strings.Split(net, ":")[2], " ")
return
}
}
}

func (p *mariadbParser) GetServerMeta() Server {
return srv
}
40 changes: 40 additions & 0 deletions mysql.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package slowql

import (
"regexp"
"strconv"
"strings"
"time"
Expand All @@ -13,8 +14,12 @@ const MySQL Kind = 0

type mysqlParser struct {
wl chan Query
sm chan Server
}

// srv holds the server configuration so we can access it multiple times
var srv Server

func (p *mysqlParser) parseBlocs(rawBlocs chan []string) {
for {
select {
Expand Down Expand Up @@ -135,3 +140,38 @@ func (q *Query) parseMySQLHeader(line string) {
}
}
}

func (p *mysqlParser) parseServerMeta(lines chan []string) {
for {
select {
case header := <-lines:
versions := header[0]
net := header[1]

// Parse server information
versionre := regexp.MustCompile(`^([^,]+),\s+Version:\s+([0-9\.]+)([A-Za-z0-9-]+)\s+\((.*)\)\. started`)
matches := versionre.FindStringSubmatch(versions)

if len(matches) != 5 {
srv.Binary = "unable to parse line"
srv.VersionShort = srv.Binary
srv.Version = srv.Binary
srv.VersionDescription = srv.Binary
srv.Port = 0
srv.Socket = srv.Binary
}

srv.Binary = matches[1]
srv.VersionShort = matches[2]
srv.Version = srv.VersionShort + matches[3]
srv.VersionDescription = matches[4]
srv.Port, _ = strconv.Atoi(strings.Split(net, " ")[2])
srv.Socket = strings.TrimLeft(strings.Split(net, ":")[2], " ")
return
}
}
}

func (p *mysqlParser) GetServerMeta() Server {
return srv
}
30 changes: 27 additions & 3 deletions slowql.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,71 @@ type Query struct {
Query string
}

// Server holds the SQL server informations that are parsed from the header
type Server struct {
Binary string
Port int
Socket string
Version string
VersionShort string
VersionDescription string
}

// Kind is a database kind
type Kind int

// Parser is the parser interface
type Parser interface {
// GetNext returns the next query of the parser
GetNext() Query
GetServerMeta() Server
parseBlocs(rawBlocs chan []string)
parseServerMeta(chan []string)
}

// NewParser returns a new parser depending on the desired kind
func NewParser(k Kind, r io.Reader) Parser {
var p Parser

rawBlocs := make(chan []string, 1024)
servermeta := make(chan []string)
waitingList := make(chan Query, 1024)
go scan(*bufio.NewScanner(r), rawBlocs)
serverInfos := make(chan Server)
go scan(*bufio.NewScanner(r), rawBlocs, servermeta)

switch k {
case MySQL, PCX:
p = &mysqlParser{
sm: serverInfos,
wl: waitingList,
}
case MariaDB:
p = &mariadbParser{
sm: serverInfos,
wl: waitingList,
}
}

go p.parseServerMeta(servermeta)
go p.parseBlocs(rawBlocs)

// This is gross but we are sure that some queries will be already parsed at
// when the user will call the package's functions
time.Sleep(10 * time.Millisecond)
return p
}

func scan(s bufio.Scanner, rawBlocs chan []string) {
func scan(s bufio.Scanner, rawBlocs, servermeta chan []string) {
var bloc []string
inHeader, inQuery := false, false

// Skip the first three lines of the log file
// Parse the server informations
var lines []string
for i := 0; i < 3; i++ {
s.Scan()
lines = append(lines, s.Text())
}
servermeta <- lines

for s.Scan() {
line := s.Text()
Expand Down

0 comments on commit b4aeb06

Please sign in to comment.