Skip to content
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 metrics to simulator #706

Merged
merged 76 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
414a7cf
add tps
anusha-ctrl Jun 28, 2023
41f94ec
merge
anusha-ctrl Jun 28, 2023
c65a8e7
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jun 28, 2023
bf74d46
get block build metrics
anusha-ctrl Jun 28, 2023
0ed532e
Add issuance time, confirmed time, issued-> acceptance time, verify time
anusha-ctrl Jun 29, 2023
cedb3b0
Log times at end of batch
anusha-ctrl Jun 29, 2023
461c2c6
cleaner
anusha-ctrl Jun 29, 2023
750ed9f
address comments
anusha-ctrl Jun 29, 2023
5c521d7
remove unused code block
anusha-ctrl Jun 29, 2023
3655c66
avoids taking len of channel
darioush Jun 29, 2023
7b0f663
nits
darioush Jun 29, 2023
f225dfb
Merge pull request #707 from ava-labs/add-metrics-to-simulator0
anusha-ctrl Jun 29, 2023
be68d42
pass in stringID
anusha-ctrl Jun 29, 2023
173f847
move to loader
anusha-ctrl Jun 29, 2023
a3b6020
remove unused field
anusha-ctrl Jun 29, 2023
2fef11e
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jun 30, 2023
c8f3da5
revert file back
anusha-ctrl Jun 30, 2023
775e5e9
cleaner
anusha-ctrl Jun 30, 2023
ca504d3
lint
anusha-ctrl Jun 30, 2023
7395f60
make it work for ws or for rpc
anusha-ctrl Jun 30, 2023
c9b9604
protect
anusha-ctrl Jun 30, 2023
35480f8
endpoint
anusha-ctrl Jun 30, 2023
867b81e
no return on defer
anusha-ctrl Jun 30, 2023
4511cc5
sep to a funciton
anusha-ctrl Jun 30, 2023
616d9c8
have blockchainidstr passed in
anusha-ctrl Jun 30, 2023
131ab7d
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jun 30, 2023
5262218
typo
anusha-ctrl Jun 30, 2023
46d1208
pass in metrics through config
anusha-ctrl Jun 30, 2023
6666a59
address comments
anusha-ctrl Jun 30, 2023
c30bf85
address more comments and edit err policy of metrics functions
anusha-ctrl Jun 30, 2023
2048ffa
add more logging to load_test
anusha-ctrl Jun 30, 2023
99e6f27
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jun 30, 2023
d7d09ff
typo
anusha-ctrl Jun 30, 2023
875048e
better check
anusha-ctrl Jul 3, 2023
cce96a7
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jul 3, 2023
59a2d29
fix endpoints
anusha-ctrl Jul 3, 2023
b07cfa9
typo:
anusha-ctrl Jul 3, 2023
710a222
individual
anusha-ctrl Jul 4, 2023
d919724
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jul 6, 2023
63731b7
histogram
anusha-ctrl Jul 6, 2023
9821242
address feedback:
anusha-ctrl Jul 6, 2023
2ad7ad3
remove metrics from default
anusha-ctrl Jul 6, 2023
7856705
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jul 7, 2023
649daca
address comments
anusha-ctrl Jul 11, 2023
2ffda7a
simplify time metrics
anusha-ctrl Jul 11, 2023
e4fb332
better explanation
anusha-ctrl Jul 11, 2023
8849b75
address comments
anusha-ctrl Jul 19, 2023
8e7bbdc
address comments
anusha-ctrl Jul 19, 2023
f7d3850
cleanup
anusha-ctrl Jul 19, 2023
c81454e
more cleanup
anusha-ctrl Jul 19, 2023
2fb7c3b
rename vars for clarity
anusha-ctrl Jul 19, 2023
1773e13
ws
anusha-ctrl Jul 19, 2023
f3867e5
cleanup
anusha-ctrl Jul 19, 2023
3c4f54a
address comments
anusha-ctrl Jul 19, 2023
e918d4d
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jul 19, 2023
14e1d55
ws
anusha-ctrl Jul 19, 2023
ee390f5
expose metrics add flag
anusha-ctrl Jul 19, 2023
cc51ea9
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jul 19, 2023
2825310
fix blocking issue of http server and gracefully stop it
anusha-ctrl Jul 20, 2023
85cc2f8
cleanup
anusha-ctrl Jul 20, 2023
ea1e609
use constant
anusha-ctrl Jul 20, 2023
2651d76
add issuance to confirmation metrics
anusha-ctrl Jul 20, 2023
92bb91f
ws
anusha-ctrl Jul 20, 2023
aa464fb
Merge branch 'master' into add-metrics-to-simulator
aaronbuchwald Jul 26, 2023
c3d777b
simplify metrics server
anusha-ctrl Jul 26, 2023
d049a98
Bump avalanchego to v1.10.5 and bump Subnet-EVM for v0.5.3 release (#…
aaronbuchwald Jul 26, 2023
0fcf0d7
handle control c
anusha-ctrl Jul 27, 2023
ebe20cd
print out output
anusha-ctrl Jul 27, 2023
11d4295
clean up
anusha-ctrl Jul 27, 2023
33cbe16
clean up
anusha-ctrl Jul 27, 2023
5c80926
remove go routines to close client
anusha-ctrl Jul 27, 2023
710bed0
address comments
anusha-ctrl Jul 31, 2023
e1cf6c3
memory leak
anusha-ctrl Jul 31, 2023
8b87e94
fix
anusha-ctrl Jul 31, 2023
a2ff6f9
print
anusha-ctrl Jul 31, 2023
d26845c
Merge branch 'master' into add-metrics-to-simulator
anusha-ctrl Jul 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/simulator/load/funder.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
// DistributeFunds ensures that each address in keys has at least [minFundsPerAddr] by sending funds
// from the key with the highest starting balance.
// This function returns a set of at least [numKeys] keys, each having a minimum balance [minFundsPerAddr].
func DistributeFunds(ctx context.Context, client ethclient.Client, keys []*key.Key, numKeys int, minFundsPerAddr *big.Int) ([]*key.Key, error) {
func DistributeFunds(ctx context.Context, client ethclient.Client, keys []*key.Key, numKeys int, minFundsPerAddr *big.Int, blockchainID string) ([]*key.Key, error) {
darioush marked this conversation as resolved.
Show resolved Hide resolved
if len(keys) < numKeys {
return nil, fmt.Errorf("insufficient number of keys %d < %d", len(keys), numKeys)
}
Expand Down Expand Up @@ -107,6 +107,7 @@ func DistributeFunds(ctx context.Context, client ethclient.Client, keys []*key.K
return nil, fmt.Errorf("failed to generate fund distribution sequence from %s of length %d", maxFundsKey.Address, len(needFundsAddrs))
}
worker := NewSingleAddressTxWorker(ctx, client, maxFundsKey.Address)

txFunderAgent := txs.NewIssueNAgent[*types.Transaction](txSequence, worker, numTxs)

if err := txFunderAgent.Execute(ctx); err != nil {
Expand Down
48 changes: 47 additions & 1 deletion cmd/simulator/load/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import (
"context"
"crypto/ecdsa"
"fmt"
"io/ioutil"
"math/big"
"net/http"
"regexp"
"time"

"github.com/ava-labs/subnet-evm/cmd/simulator/config"
"github.com/ava-labs/subnet-evm/cmd/simulator/key"
Expand All @@ -31,6 +35,14 @@ func ExecuteLoader(ctx context.Context, config config.Config) error {

// Construct the arguments for the load simulator
clients := make([]ethclient.Client, 0, len(config.Endpoints))
// Extract blockchainStrID from the clientURI
re := regexp.MustCompile(`bc\/(.*)\/ws`)
matches := re.FindStringSubmatch(config.Endpoints[0])
if len(matches) < 1 {
return fmt.Errorf("failed to get blockchainStrID from the clientURI %s", config.Endpoints[0])
}
// Get the last element in matches
blockchainIDStr := matches[len(matches)-1]
for i := 0; i < config.Workers; i++ {
clientURI := config.Endpoints[i%len(config.Endpoints)]
client, err := ethclient.Dial(clientURI)
Expand Down Expand Up @@ -63,7 +75,7 @@ func ExecuteLoader(ctx context.Context, config config.Config) error {
maxFeeCap := new(big.Int).Mul(big.NewInt(params.GWei), big.NewInt(config.MaxFeeCap))
minFundsPerAddr := new(big.Int).Mul(maxFeeCap, big.NewInt(int64(config.TxsPerWorker*params.TxGas)))
log.Info("Distributing funds", "numTxsPerWorker", config.TxsPerWorker, "minFunds", minFundsPerAddr)
keys, err = DistributeFunds(ctx, clients[0], keys, config.Workers, minFundsPerAddr)
keys, err = DistributeFunds(ctx, clients[0], keys, config.Workers, minFundsPerAddr, blockchainIDStr)
if err != nil {
return err
}
Expand Down Expand Up @@ -129,5 +141,39 @@ func ExecuteLoader(ctx context.Context, config config.Config) error {
return err
}
log.Info("Tx agents completed successfully.")

logOtherMetrics(blockchainIDStr)
return nil
}

func logOtherMetrics(blockchainIDStr string) error {
getCallStart := time.Now()
resp, err := http.Get("http://127.0.0.1:9650/ext/metrics")
getCallEnd := time.Now()
getCallDuration := getCallEnd.Sub(getCallStart)
darioush marked this conversation as resolved.
Show resolved Hide resolved

log.Info("GET Metrics API Data", "time", getCallDuration.Seconds())
if err != nil {
return fmt.Errorf("failed getting metrics: %w", err)
}

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed reading response body of metrics: %w", err)
}

bodyString := string(body)
re := regexp.MustCompile(fmt.Sprintf(".*avalanche_%s_vm_metervm_build_block_sum.*", blockchainIDStr))
matches := re.FindAllStringSubmatch(bodyString, -1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're repeating the same logic for multiple metrics it should be broken out into its own function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better way to do this than creating a regex over the body?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the metrics API just returns a huge block of text so I have to search for exactly what I want

log.Info("Sum of time (in ns) of a build_block", "time", matches[len(matches)-1])

re = regexp.MustCompile(fmt.Sprintf(".*avalanche_%s_blks_accepted_sum.*", blockchainIDStr))
matches = re.FindAllStringSubmatch(bodyString, -1)
log.Info("Sum of time (in ns) from issuance of a block(s) to its acceptance", "time", matches[len(matches)-1])

re = regexp.MustCompile(fmt.Sprintf(".*avalanche_%s_vm_metervm_verify_sum.*", blockchainIDStr))
matches = re.FindAllStringSubmatch(bodyString, -1)
log.Info("Sum of time (in ns) of a verify", "time", matches[len(matches)-1])

return nil
}
64 changes: 52 additions & 12 deletions cmd/simulator/txs/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import (
"context"
"errors"
"fmt"
"time"

"github.com/ethereum/go-ethereum/log"
)

// TxSequence provides an interface to return a channel of transactions.
Expand Down Expand Up @@ -53,33 +56,70 @@ func (a issueNAgent[T]) Execute(ctx context.Context) error {
}

txChan := a.sequence.Chan()
confirmedCount := 0
batchI := 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
batchI := 1
batchI := 0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought it would be nicer from a user reading the logs to see it 1 -indexed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point haha


// Tracks the total amount of time waiting for issuing and confirming txs
var (
totalIssuedTime time.Duration
totalConfirmedTime time.Duration
)

defer func() error {
return a.worker.Close(ctx)
}()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we returning an error from a deferred function that we're not checking?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


// Start time for execution
start := time.Now()
for {
var (
txs = make([]T, 0, a.n)
tx T
ok bool
txs = make([]T, 0, a.n)
tx T
moreTxs bool
)
// Start issuance batch
issuedStart := time.Now()
L:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know you could do this in Golang, it seems pretty useful in contexts like this!

for i := uint64(0); i < a.n; i++ {
select {
case tx, ok = <-txChan:
if !ok {
return a.worker.Close(ctx)
}
case <-ctx.Done():
return ctx.Err()
case tx, moreTxs = <-txChan:
if !moreTxs {
break L
}
if err := a.worker.IssueTx(ctx, tx); err != nil {
return fmt.Errorf("failed to issue transaction %d: %w", len(txs), err)
}
txs = append(txs, tx)
}

if err := a.worker.IssueTx(ctx, tx); err != nil {
return fmt.Errorf("failed to issue transaction %d: %w", len(txs), err)
}
txs = append(txs, tx)
}
// Get the batch's issuance time and add it to totalIssuedTime
issuedDuration := time.Since(issuedStart)
log.Info("Issuance Batch Done", "batch", batchI, "time", issuedDuration.Seconds())
totalIssuedTime += issuedDuration

// Wait for txs in this batch to confirm
confirmedStart := time.Now()
for i, tx := range txs {
if err := a.worker.ConfirmTx(ctx, tx); err != nil {
return fmt.Errorf("failed to await transaction %d: %w", i, err)
}
confirmedCount++
}
// Get the batch's confirmation time and add it to totalConfirmedTime
confirmedDuration := time.Since(confirmedStart)
log.Info("Confirmed Batch Done", "batch", batchI, "time", confirmedDuration.Seconds())
totalConfirmedTime += confirmedDuration

// Check if this is the last batch, if so write the final log and return
if !moreTxs {
totalTime := time.Since(start).Seconds()
log.Info("Execution complete", "totalTxs", confirmedCount, "totalTime", totalTime, "TPS", float64(confirmedCount)/totalTime,
"issuanceTime", totalIssuedTime.Seconds(), "confirmedTime", totalConfirmedTime.Seconds())
return nil
}

batchI++
}
}
2 changes: 1 addition & 1 deletion ethclient/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ func (ec *client) SubscribeNewAcceptedTransactions(ctx context.Context, ch chan<
return ec.c.EthSubscribe(ctx, ch, "newAcceptedTransactions")
}

// SubscribeNewAcceptedTransactions subscribes to notifications about the accepted transaction hashes on the given channel.
// SubscribeNewPendingTransactions subscribes to notifications about the pending transaction hashes on the given channel.
func (ec *client) SubscribeNewPendingTransactions(ctx context.Context, ch chan<- *common.Hash) (interfaces.Subscription, error) {
aaronbuchwald marked this conversation as resolved.
Show resolved Hide resolved
return ec.c.EthSubscribe(ctx, ch, "newPendingTransactions")
}
Expand Down