tune performance; more robust selnium
This commit is contained in:
parent
b20a4a06d6
commit
6c88e1be1d
89
benchmark.rb
Normal file
89
benchmark.rb
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'socket'
|
||||||
|
require 'timeout'
|
||||||
|
|
||||||
|
def start(*exe)
|
||||||
|
puts "Starting #{exe}"
|
||||||
|
pid = spawn(*exe, out: "/dev/null")
|
||||||
|
Process.detach(pid)
|
||||||
|
return pid
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_port_open?(ip, port)
|
||||||
|
begin
|
||||||
|
Timeout::timeout(1) do
|
||||||
|
begin
|
||||||
|
s = TCPSocket.new(ip, port)
|
||||||
|
s.close
|
||||||
|
return true
|
||||||
|
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue Timeout::Error
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
def killall(pids)
|
||||||
|
pids.each do |pid|
|
||||||
|
puts "Killing #{pid}"
|
||||||
|
begin
|
||||||
|
Process.kill "TERM", pid
|
||||||
|
Process.wait pid
|
||||||
|
rescue => ex
|
||||||
|
puts "ERROR: Couldn't kill #{pid}. #{ex.class}=#{ex.message}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
ab = ["ab", "-n", "10000", "http://0.0.0.0:9089/main.go"]
|
||||||
|
puts("$ " + ab.join(" "))
|
||||||
|
out = ""
|
||||||
|
IO.popen(ab) do |io|
|
||||||
|
out = io.read
|
||||||
|
puts(out)
|
||||||
|
out.split(/\n/).map do |l|
|
||||||
|
next unless l =~ /^Requests per second:\s+(\d+.\d+)/
|
||||||
|
return $1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
abort("failed to parse ab output: #{out}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def main()
|
||||||
|
pids = []
|
||||||
|
pids << start("docker", "run", "-p", "9089:80", "-v", "#{File.realpath(".")}/:/usr/share/nginx/html:ro", "--rm", "nginx:alpine")
|
||||||
|
open = false
|
||||||
|
10.times do
|
||||||
|
sleep(1)
|
||||||
|
open ||= is_port_open?("0.0.0.0", 9089)
|
||||||
|
rc = Process.waitpid(pids[0], Process::WNOHANG)
|
||||||
|
unless rc.nil?
|
||||||
|
abort("failed to start nginx container")
|
||||||
|
end
|
||||||
|
break if open
|
||||||
|
end
|
||||||
|
unless open
|
||||||
|
abort("failed to start nginx container")
|
||||||
|
end
|
||||||
|
run() # warmup
|
||||||
|
|
||||||
|
median1 = run()
|
||||||
|
pids << start("./callgraph", "-skip-test", "-rancher-host", "rancher.local:8080", "http://sharelatex.local/login", "127.0.0.1")
|
||||||
|
sleep(2)
|
||||||
|
median2 = run()
|
||||||
|
killall([pids.pop]) rescue nil
|
||||||
|
puts (pids)
|
||||||
|
pids << start("sudo", "tcpdump", "-i", "any", "-n")
|
||||||
|
sleep(2)
|
||||||
|
median3 = run()
|
||||||
|
puts "####median request time/s without, with sysdig and with tcpdump: #{median1} #{median2} #{median3}"
|
||||||
|
ensure
|
||||||
|
killall(pids)
|
||||||
|
end
|
||||||
|
|
||||||
|
main
|
@ -11,10 +11,10 @@ function on_init()
|
|||||||
local mapping = {
|
local mapping = {
|
||||||
isread = "evt.is_io_read",
|
isread = "evt.is_io_read",
|
||||||
buflen = "evt.buflen",
|
buflen = "evt.buflen",
|
||||||
proc = "proc.name",
|
--proc = "proc.name",
|
||||||
pid = "proc.pid",
|
--pid = "proc.pid",
|
||||||
tid = "thread.tid",
|
--tid = "thread.tid",
|
||||||
container = "container.name",
|
--container = "container.name",
|
||||||
sip = "fd.sip",
|
sip = "fd.sip",
|
||||||
sport = "fd.sport",
|
sport = "fd.sport",
|
||||||
cip = "fd.cip",
|
cip = "fd.cip",
|
||||||
@ -26,66 +26,46 @@ function on_init()
|
|||||||
for k,v in pairs(mapping) do
|
for k,v in pairs(mapping) do
|
||||||
fields[k] = chisel.request_field(v)
|
fields[k] = chisel.request_field(v)
|
||||||
end
|
end
|
||||||
key_fields = {fields.container, fields.proc, fields.pid, fields.tid, fields.proto, fields.sip, fields.sport, fields.cip, fields.cport}
|
--key_fields = {fields.container, fields.proc, fields.pid, fields.tid, fields.proto, fields.sip, fields.sport, fields.cip, fields.cport}
|
||||||
|
key_fields = {fields.proto, fields.sip, fields.sport, fields.cip, fields.cport}
|
||||||
|
|
||||||
sysdig.set_snaplen(0)
|
sysdig.set_snaplen(0)
|
||||||
chisel.set_filter("evt.is_io=true and (fd.type=ipv4 or fd.type=ipv6) and fd.rip exists and fd.lip exists and container.name!=host")
|
chisel.set_filter("evt.is_io=true and fd.rip exists and container.name!=host")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local stats = {}
|
local stats = {}
|
||||||
|
-- localize function to save scope lookups
|
||||||
local DEBUG = false
|
local table_concat = table.concat
|
||||||
|
local evt_field = evt.field
|
||||||
|
local ipairs = ipairs
|
||||||
|
|
||||||
function on_event()
|
function on_event()
|
||||||
-- only capture connections of servers
|
-- only capture connections of servers
|
||||||
local sip = evt.field(fields.sip)
|
local fields = fields
|
||||||
if not (evt.field(fields.lip) == sip or evt.field(fields.rip) == sip) then
|
local sip = evt_field(fields.sip)
|
||||||
|
|
||||||
|
if not (evt_field(fields.lip) == sip or evt_field(fields.rip) == sip) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local dir
|
|
||||||
if evt.field(fields.isread) then
|
|
||||||
dir = "rx"
|
|
||||||
else
|
|
||||||
dir = "tx"
|
|
||||||
end
|
|
||||||
|
|
||||||
if DEBUG then
|
|
||||||
function to_s(v)
|
|
||||||
return (evt.field(v) or "nil").." "
|
|
||||||
end
|
|
||||||
io.write("DEBUG: ",
|
|
||||||
to_s(fields.container),
|
|
||||||
to_s(fields.proc),
|
|
||||||
to_s(fields.pid),
|
|
||||||
to_s(fields.tid),
|
|
||||||
to_s(fields.proto),
|
|
||||||
to_s(fields.sip),
|
|
||||||
to_s(fields.sport),
|
|
||||||
to_s(fields.cip),
|
|
||||||
to_s(fields.cport),
|
|
||||||
to_s(fields.lip),
|
|
||||||
dir, "\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
local t = { }
|
local t = { }
|
||||||
for k,v in ipairs(key_fields) do
|
for k,v in ipairs(key_fields) do
|
||||||
t[#t+1] = tostring(evt.field(v))
|
t[k] = tostring(evt_field(v))
|
||||||
end
|
end
|
||||||
|
|
||||||
t[#t+1] = dir
|
if evt.field(fields.isread) then
|
||||||
local key = table.concat(t, "\t")
|
t[#t+1] = "rx"
|
||||||
|
else
|
||||||
|
t[#t+1] = "tx"
|
||||||
|
end
|
||||||
|
local key = table_concat(t, "\t")
|
||||||
|
|
||||||
stats[key] = (stats[key] or 0) + (evt.field(fields.buflen) or 0)
|
stats[key] = (stats[key] or 0) + (evt_field(fields.buflen) or 0)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function string.starts(string, prefix)
|
|
||||||
return string.sub(string, 1, string.len(start)) == prefix
|
|
||||||
end
|
|
||||||
|
|
||||||
function on_capture_start()
|
function on_capture_start()
|
||||||
hostname = sysdig.get_machine_info().hostname
|
hostname = sysdig.get_machine_info().hostname
|
||||||
return true
|
return true
|
||||||
@ -93,6 +73,6 @@ end
|
|||||||
|
|
||||||
function on_capture_end()
|
function on_capture_end()
|
||||||
for k, v in pairs(stats) do
|
for k, v in pairs(stats) do
|
||||||
io.write(hostname, "\t", k, "\t", v, "\n")
|
io.write(k, "\t", v, "\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
32
main.go
32
main.go
@ -6,6 +6,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
skipTest = flag.Bool("skip-test", false, "skip selenium integration test")
|
||||||
rancherHost = flag.String("rancher-host", "localhost:8080", "host of rancher server")
|
rancherHost = flag.String("rancher-host", "localhost:8080", "host of rancher server")
|
||||||
rancherAccessKey = flag.String("rancher-access-key", os.Getenv("RANCHER_ACCESS_KEY"), "api access key")
|
rancherAccessKey = flag.String("rancher-access-key", os.Getenv("RANCHER_ACCESS_KEY"), "api access key")
|
||||||
rancherSecretKey = flag.String("rancher-secret-key", os.Getenv("RANCHER_SECRET_KEY"), "api secret key")
|
rancherSecretKey = flag.String("rancher-secret-key", os.Getenv("RANCHER_SECRET_KEY"), "api secret key")
|
||||||
@ -22,7 +24,8 @@ var (
|
|||||||
|
|
||||||
func parseArgs() (sharelatexUrl string, hosts []string) {
|
func parseArgs() (sharelatexUrl string, hosts []string) {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if len(os.Args) < 2 {
|
args := flag.Args()
|
||||||
|
if len(args) < 1 {
|
||||||
fmt.Fprintf(os.Stderr, "USAGE: %s SHARELATEXURL HOSTS...", os.Args[0])
|
fmt.Fprintf(os.Stderr, "USAGE: %s SHARELATEXURL HOSTS...", os.Args[0])
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@ -34,8 +37,9 @@ func parseArgs() (sharelatexUrl string, hosts []string) {
|
|||||||
fmt.Fprintf(os.Stderr, "Set RANCHER_SECRET_KEY environment variable")
|
fmt.Fprintf(os.Stderr, "Set RANCHER_SECRET_KEY environment variable")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
return os.Args[1], os.Args[2:]
|
return args[0], args[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func rancherServices() ([]sysdig.Service, error) {
|
func rancherServices() ([]sysdig.Service, error) {
|
||||||
c := rancher.New(*rancherHost, *rancherAccessKey, *rancherSecretKey)
|
c := rancher.New(*rancherHost, *rancherAccessKey, *rancherSecretKey)
|
||||||
var api rancher.Api
|
var api rancher.Api
|
||||||
@ -63,9 +67,12 @@ func rancherServices() ([]sysdig.Service, error) {
|
|||||||
} else {
|
} else {
|
||||||
name = container.Labels.ProjectServiceName
|
name = container.Labels.ProjectServiceName
|
||||||
}
|
}
|
||||||
|
if name == "Network Agent" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
ip := net.ParseIP(container.PrimaryIpAddress)
|
ip := net.ParseIP(container.PrimaryIpAddress)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, fmt.Errorf("Got invalid IP from api for '%s' container: %s", container.Name, ip)
|
return nil, fmt.Errorf("Got invalid IP from api for '%s' container: %s", container.Name, container.PrimaryIpAddress)
|
||||||
}
|
}
|
||||||
serviceMap[name] = append(serviceMap[name], ip)
|
serviceMap[name] = append(serviceMap[name], ip)
|
||||||
}
|
}
|
||||||
@ -89,12 +96,21 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
die("failed to start sysdig: %v", err)
|
die("failed to start sysdig: %v", err)
|
||||||
}
|
}
|
||||||
time.Sleep(4 * time.Second)
|
|
||||||
err = sharelatex.IntegrationTest(url)
|
if *skipTest {
|
||||||
if err != nil {
|
signalChan := make(chan os.Signal, 1)
|
||||||
die("selenium not running?: %v", err)
|
signal.Notify(signalChan, os.Interrupt)
|
||||||
|
signal.Notify(signalChan, syscall.SIGTERM)
|
||||||
|
<-signalChan
|
||||||
|
} else {
|
||||||
|
time.Sleep(4 * time.Second)
|
||||||
|
err = sharelatex.IntegrationTest(url)
|
||||||
|
if err != nil {
|
||||||
|
die("selenium not running?: %v", err)
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
cmd.SendStopSignal()
|
cmd.SendStopSignal()
|
||||||
|
|
||||||
var records []sysdig.Record
|
var records []sysdig.Record
|
||||||
|
@ -11,6 +11,40 @@ import (
|
|||||||
"github.com/tebeka/selenium"
|
"github.com/tebeka/selenium"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type driver struct {
|
||||||
|
wd selenium.WebDriver
|
||||||
|
retries uint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d driver) FindXpath(selector string) selenium.WebElement {
|
||||||
|
return d.Find(selenium.ByXPATH, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d driver) FindByCSS(selector string) selenium.WebElement {
|
||||||
|
return d.Find(selenium.ByCSSSelector, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d driver) FindByName(selector string) selenium.WebElement {
|
||||||
|
return d.Find(selenium.ByName, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d driver) FindByText(selector string) selenium.WebElement {
|
||||||
|
return d.Find(selenium.ByLinkText, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d driver) Find(by, selector string) selenium.WebElement {
|
||||||
|
for i := uint(0); i < d.retries; i++ {
|
||||||
|
e, err := d.wd.FindElement(by, selector)
|
||||||
|
if err == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(os.Stderr, "elemenet %s not found (%s)", selector, by)
|
||||||
|
os.Exit(1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func IntegrationTest(url string) error {
|
func IntegrationTest(url string) error {
|
||||||
_, err := http.Get(url)
|
_, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -22,61 +56,61 @@ func IntegrationTest(url string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer wd.Quit()
|
defer wd.Quit()
|
||||||
|
d := driver{wd, 100}
|
||||||
|
|
||||||
// Get simple playground interface
|
// Get simple playground interface
|
||||||
|
fmt.Fprintf(os.Stderr, "visit url %s\n", url)
|
||||||
wd.Get(url)
|
wd.Get(url)
|
||||||
|
|
||||||
e, _ := wd.FindElement(selenium.ByXPATH, "//input[@type='email']")
|
e := d.FindXpath("//input[@type='email']")
|
||||||
e.Clear()
|
e.Clear()
|
||||||
e.SendKeys("joerg@higgsboson.tk")
|
e.SendKeys("joerg@higgsboson.tk")
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByXPATH, "//input[@type='password']")
|
e = d.FindXpath("//input[@type='password']")
|
||||||
e.Clear()
|
e.Clear()
|
||||||
e.SendKeys("password")
|
e.SendKeys("password")
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByXPATH, "//button[@type='submit']")
|
e = d.FindXpath("//button[@type='submit']")
|
||||||
e.Click()
|
e.Click()
|
||||||
|
|
||||||
for {
|
d.FindByText("Account")
|
||||||
_, err = wd.FindElement(selenium.ByLinkText, "Account")
|
|
||||||
if err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(time.Millisecond * 4000)
|
e = d.FindByText("New Project")
|
||||||
e, _ = wd.FindElement(selenium.ByLinkText, "New Project")
|
|
||||||
e.Click()
|
e.Click()
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByLinkText, "Blank Project")
|
e = d.FindByText("Blank Project")
|
||||||
e.Click()
|
e.Click()
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByXPATH, "//input[@type='text']")
|
e = d.FindXpath("//input[@type='text']")
|
||||||
e.Clear()
|
e.Clear()
|
||||||
e.SendKeys(fmt.Sprintf("p %d", rand.Int63()))
|
e.SendKeys(fmt.Sprintf("p %d", rand.Int63()))
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByCSSSelector, "button.btn-primary") // Create
|
e = d.FindByCSS("button.btn-primary") // Create
|
||||||
e.Click()
|
|
||||||
time.Sleep(time.Millisecond * 3000)
|
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByCSSSelector, `i.fa-comment`)
|
|
||||||
e.Click()
|
e.Click()
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByCSSSelector, `div.new-message textarea`)
|
e = d.FindXpath("//a[@ng-controller='ShareController']") // Share
|
||||||
|
e.Click()
|
||||||
|
|
||||||
|
e = d.FindByCSS("button.btn-primary") // Close
|
||||||
|
e.Click()
|
||||||
|
|
||||||
|
e = d.FindByCSS(`i.fa-comment`)
|
||||||
|
e.Click()
|
||||||
|
|
||||||
|
e = d.FindByCSS(`div.new-message textarea`)
|
||||||
e.SendKeys("hello world" + selenium.EnterKey)
|
e.SendKeys("hello world" + selenium.EnterKey)
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByCSSSelector, "i.fa.fa-upload") // Upload
|
e = d.FindByCSS("i.fa.fa-upload") // Upload
|
||||||
e.Click()
|
e.Click()
|
||||||
|
|
||||||
e, _ = wd.FindElement(selenium.ByName, "file") // Create
|
e = d.FindByName("file") // Create
|
||||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||||
e.SendKeys(filepath.Join(dir, "./test.txt"))
|
e.SendKeys(filepath.Join(dir, "./test.txt"))
|
||||||
|
|
||||||
time.Sleep(time.Millisecond * 500)
|
e = d.FindByCSS("textarea") // Latex Doc
|
||||||
e, _ = wd.FindElement(selenium.ByCSSSelector, "textarea") // Latex Doc
|
|
||||||
e.Clear()
|
e.Clear()
|
||||||
e.SendKeys(`\documentclass{article} \begin{document} ello \end{document}`)
|
e.SendKeys(`\documentclass{article} \begin{document} ello \end{document}`)
|
||||||
|
|
||||||
time.Sleep(time.Millisecond * 1000)
|
time.Sleep(time.Millisecond * 1000)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
t="$(mktemp)"; f() {
|
t="$(mktemp)"; f() {
|
||||||
rm "$t"
|
rm "$t"
|
||||||
}
|
}
|
||||||
trap f EXIT; cat > "$t"; sudo sysdig -c "$t"
|
trap f EXIT; cat > "$t"; sudo sysdig -N -s0 -c "$t"
|
||||||
|
@ -16,15 +16,15 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Record struct {
|
type Record struct {
|
||||||
Host, Container, Process string
|
//Host, Container, Process string
|
||||||
Pid, Tid uint64
|
//Pid, Tid uint64
|
||||||
Proto string
|
Proto string
|
||||||
ServerIp net.IP
|
ServerIp net.IP
|
||||||
ServerPort uint16
|
ServerPort uint16
|
||||||
ClientIp net.IP
|
ClientIp net.IP
|
||||||
ClientPort uint16
|
ClientPort uint16
|
||||||
Direction int
|
Direction int
|
||||||
Bytes uint64
|
Bytes uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseOutput(result string) ([]Record, error) {
|
func ParseOutput(result string) ([]Record, error) {
|
||||||
@ -40,51 +40,35 @@ func ParseOutput(result string) ([]Record, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
if record[0] == "host" {
|
sip := net.ParseIP(record[1])
|
||||||
continue
|
|
||||||
}
|
|
||||||
pid, err := strconv.ParseUint(record[3], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid pid %s: %v", record[2], err)
|
|
||||||
}
|
|
||||||
tid, err := strconv.ParseUint(record[4], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid tid %s: %v", record[3], err)
|
|
||||||
}
|
|
||||||
sip := net.ParseIP(record[6])
|
|
||||||
if sip == nil {
|
if sip == nil {
|
||||||
return nil, fmt.Errorf("invalid ip '%s'", record[6])
|
return nil, fmt.Errorf("invalid ip '%s'", record[1])
|
||||||
}
|
}
|
||||||
sport, err := strconv.ParseUint(record[7], 10, 16)
|
sport, err := strconv.ParseUint(record[2], 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid port %s: %v", record[7], err)
|
return nil, fmt.Errorf("invalid port %s: %v", record[2], err)
|
||||||
}
|
}
|
||||||
cip := net.ParseIP(record[8])
|
cip := net.ParseIP(record[3])
|
||||||
if cip == nil {
|
if cip == nil {
|
||||||
return nil, fmt.Errorf("invalid ip '%s'", record[8])
|
return nil, fmt.Errorf("invalid ip '%s'", record[3])
|
||||||
}
|
}
|
||||||
cport, err := strconv.ParseUint(record[9], 10, 16)
|
cport, err := strconv.ParseUint(record[4], 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid port %s: %v", record[9], err)
|
return nil, fmt.Errorf("invalid port %s: %v", record[4], err)
|
||||||
}
|
}
|
||||||
var direction int
|
var direction int
|
||||||
if record[10] == "rx" {
|
if record[5] == "rx" {
|
||||||
direction = RX
|
direction = RX
|
||||||
} else {
|
} else {
|
||||||
direction = TX
|
direction = TX
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, err := strconv.ParseUint(record[11], 10, 64)
|
bytes, err := strconv.ParseUint(record[6], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid transmission size %s: %v", record[11], err)
|
return nil, fmt.Errorf("invalid transmission size %s: %v", record[11], err)
|
||||||
}
|
}
|
||||||
records = append(records, Record{
|
records = append(records, Record{
|
||||||
record[0],
|
record[0],
|
||||||
record[1],
|
|
||||||
record[2],
|
|
||||||
pid,
|
|
||||||
tid,
|
|
||||||
record[5],
|
|
||||||
sip,
|
sip,
|
||||||
uint16(sport),
|
uint16(sport),
|
||||||
cip,
|
cip,
|
||||||
|
Loading…
Reference in New Issue
Block a user