Skip to content

Commit

Permalink
Add CPU profile saving to E2E tests (#489)
Browse files Browse the repository at this point in the history
Collector was already able to collect own CPU profiles.
This change enables saving CPU profile to a file after each E2E test.
This helps to analyze performance of the Collector in E2E tests.

Resolves #481
  • Loading branch information
tigrannajaryan authored Jan 6, 2020
1 parent c300f13 commit b468dee
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
4 changes: 4 additions & 0 deletions extension/pprofextension/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ type Config struct {
// disables profiling. See https://golang.org/pkg/runtime/#SetMutexProfileFraction
// for details.
MutexProfileFraction int `mapstructure:"mutex_profile_fraction"`

// Optional file name to save the CPU profile to. The profiling starts when the
// Collector starts and is saved to the file when the Collector is terminated.
SaveToFile string `mapstructure:"save_to_file"`
}
13 changes: 13 additions & 0 deletions extension/pprofextension/pprofextension.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import (
"net"
"net/http"
_ "net/http/pprof" // Needed to enable the performance profiler
"os"
"runtime"
"runtime/pprof"

"go.uber.org/zap"

Expand Down Expand Up @@ -52,10 +54,21 @@ func (p *pprofExtension) Start(host extension.Host) error {
}
}()

if p.config.SaveToFile != "" {
f, err := os.Create(p.config.SaveToFile)
if err != nil {
return err
}
pprof.StartCPUProfile(f)
}

return nil
}

func (p *pprofExtension) Shutdown() error {
if p.config.SaveToFile != "" {
pprof.StopCPUProfile()
}
return p.server.Close()
}

Expand Down
22 changes: 20 additions & 2 deletions testbed/tests/scenarios.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ import (
"io/ioutil"
"math/rand"
"os"
"path"
"path/filepath"
"testing"

"github.com/open-telemetry/opentelemetry-collector/testbed/testbed"
)

// createConfigFile creates a collector config file that corresponds to the
// sender and receiver used in the test and returns the config file name.
func createConfigFile(sender testbed.DataSender, receiver testbed.DataReceiver) string {
func createConfigFile(sender testbed.DataSender, receiver testbed.DataReceiver, resultDir string) string {
// Create a config. Note that our DataSender is used to generate a config for Collector's
// receiver and our DataReceiver is used to generate a config for Collector's exporter.
// This is because our DataSender sends to Collector's receiver and our DataReceiver
Expand All @@ -45,7 +47,12 @@ processors:
batch:
queued_retry:
extensions:
pprof:
save_to_file: %v/cpu.prof
service:
extensions: [pprof]
pipelines:
traces:
receivers: [%v]
Expand All @@ -58,7 +65,12 @@ service:
receivers:%v
exporters:%v
extensions:
pprof:
save_to_file: %v/cpu.prof
service:
extensions: [pprof]
pipelines:
metrics:
receivers: [%v]
Expand All @@ -71,6 +83,7 @@ service:
format,
sender.GenConfigYAMLStr(),
receiver.GenConfigYAMLStr(),
resultDir,
sender.ProtocolName(),
receiver.ProtocolName(),
)
Expand Down Expand Up @@ -101,7 +114,12 @@ func Scenario10kItemsPerSecond(
loadOptions testbed.LoadOptions,
resourceSpec testbed.ResourceSpec,
) {
configFile := createConfigFile(sender, receiver)
resultDir, err := filepath.Abs(path.Join("results", t.Name()))
if err != nil {
t.Fatal(err)
}

configFile := createConfigFile(sender, receiver, resultDir)
defer os.Remove(configFile)

if configFile == "" {
Expand Down

0 comments on commit b468dee

Please sign in to comment.