-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add stat collection to IPTB #65
Changes from 8 commits
7ef9124
e80ab06
a80af49
ba5b49a
27a1aac
acdfbba
6330379
4756f1c
1139529
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
*.so | ||
iptb | ||
.vscode | ||
topologies/* | ||
deb.sh | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ libp2p networks easy! | |
### Example | ||
|
||
``` | ||
$ iptb auto -count 5 >/dev/null | ||
$ iptb auto -count 5 -type <plugin_name> | ||
|
||
$ iptb start | ||
|
||
|
@@ -26,7 +26,7 @@ $ iptb shell 4 | |
$ ipfs cat QmNqugRcYjwh9pEQUK7MLuxvLjxDNZL1DH8PJJgWtQXxuF | ||
hey! | ||
``` | ||
|
||
Available plugins now: Local IPFS node (plugin_name: localipfs), Docker IPFS node (plugin_name: dockeripfs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would also be nice to be able to list available plugins via the CLI. Doesn't have to be in this PR though, just mentioning. |
||
### Usage | ||
``` | ||
NAME: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,15 @@ | ||
package commands | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"strconv" | ||
"strings" | ||
"sync" | ||
"time" | ||
|
||
"github.com/pkg/errors" | ||
cli "github.com/urfave/cli" | ||
|
@@ -121,9 +124,19 @@ func expandDashRange(s string) ([]int, error) { | |
} | ||
|
||
type Result struct { | ||
Node int | ||
Output testbedi.Output | ||
Error error | ||
Node int | ||
Output testbedi.Output | ||
Error error | ||
Elapsed time.Duration | ||
} | ||
|
||
type output struct { | ||
Node int | ||
ExitCode int | ||
Error error | ||
PluginStdout string | ||
PluginStderr string | ||
Elapsed float64 | ||
} | ||
|
||
type outputFunc func(testbedi.Core) (testbedi.Output, error) | ||
|
@@ -141,15 +154,17 @@ func mapWithOutput(list []int, nodes []testbedi.Core, fn outputFunc) ([]Result, | |
wg.Add(1) | ||
go func(i, n int, node testbedi.Core) { | ||
defer wg.Done() | ||
start := time.Now() | ||
out, err := fn(node) | ||
|
||
elapsed := time.Since(start) | ||
lk.Lock() | ||
defer lk.Unlock() | ||
|
||
results[i] = Result{ | ||
Node: n, | ||
Output: out, | ||
Error: errors.Wrapf(err, "node[%d]", n), | ||
Node: n, | ||
Output: out, | ||
Error: errors.Wrapf(err, "node[%d]", n), | ||
Elapsed: elapsed, | ||
} | ||
}(i, n, nodes[n]) | ||
} | ||
|
@@ -175,7 +190,7 @@ func validRange(list []int, total int) error { | |
return nil | ||
} | ||
|
||
func buildReport(results []Result) error { | ||
func buildReport(results []Result, encoding string) error { | ||
var errs []error | ||
|
||
for _, rs := range results { | ||
|
@@ -184,21 +199,41 @@ func buildReport(results []Result) error { | |
} | ||
|
||
if rs.Output != nil { | ||
fmt.Printf("node[%d] exit %d\n", rs.Node, rs.Output.ExitCode()) | ||
if rs.Output.Error() != nil { | ||
fmt.Printf("%s", rs.Output.Error()) | ||
if encoding == "text" { | ||
fmt.Printf("node[%d] exit %d elapsed %s\n", rs.Node, rs.Output.ExitCode(), rs.Elapsed) | ||
if rs.Output.Error() != nil { | ||
fmt.Printf("%s", rs.Output.Error()) | ||
} | ||
io.Copy(os.Stdout, rs.Output.Stdout()) | ||
io.Copy(os.Stdout, rs.Output.Stderr()) | ||
} else { | ||
// Transform plugin stdout to string | ||
pluginOutB, err := ioutil.ReadAll(rs.Output.Stdout()) | ||
if err != nil { | ||
errs = append(errs, err) | ||
} | ||
pluginOut := string(pluginOutB) | ||
// Transform plugin stderr to string | ||
pluginErrB, err := ioutil.ReadAll(rs.Output.Stderr()) | ||
if err != nil { | ||
errs = append(errs, err) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to handle the other side of this error, when the error is not nil. |
||
pluginErr := string(pluginErrB) | ||
// JSONify the plugin output | ||
rsJSON, _ := json.Marshal(output{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing this error |
||
Node: rs.Node, | ||
ExitCode: rs.Output.ExitCode(), | ||
Error: rs.Output.Error(), | ||
PluginStdout: pluginOut, | ||
PluginStderr: pluginErr, | ||
Elapsed: rs.Elapsed.Seconds(), | ||
}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to also handle this error. |
||
fmt.Printf("%s\n", rsJSON) | ||
} | ||
|
||
fmt.Println() | ||
|
||
io.Copy(os.Stdout, rs.Output.Stdout()) | ||
io.Copy(os.Stdout, rs.Output.Stderr()) | ||
|
||
fmt.Println() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should move this up inside of the text encoding section, and then also make sure we have a newline outside of the loop (it can be printed for all cases that are not text). This will make it so that all output for a single command will be ld-json, and between each execution will be a newline. This will help break up the output if appending to the same file. The output should look like if it where being appended to the same file
|
||
} | ||
|
||
} | ||
|
||
if len(errs) != 0 { | ||
return cli.NewMultiError(errs...) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
.vscode
I think is fine, but I don't think we need the other two.