Feature/profiling #257 (#264)

This commit is contained in:
Marin 2017-09-01 16:09:11 +02:00 committed by Ivan Tomilov
parent 9f57cf422f
commit 97bba3d835
4 changed files with 132 additions and 0 deletions

View File

@ -53,6 +53,7 @@ ci:
build/env.sh go test -timeout 40m -v ./geth/node
build/env.sh go test -timeout 40m -v ./geth/params
build/env.sh go test -timeout 40m -v ./extkeys
build/env.sh go test -timeout 1m -v ./helpers/...
generate:
cp ./node_modules/web3/dist/web3.js ./static/scripts/web3.js

View File

@ -10,6 +10,7 @@ import (
"github.com/status-im/status-go/geth/common"
"github.com/status-im/status-go/geth/params"
"github.com/status-im/status-go/helpers/profiling"
)
//export GenerateConfig
@ -307,6 +308,24 @@ func Call(chatID *C.char, path *C.char, params *C.char) *C.char {
return C.CString(res)
}
//export StartCPUProfile
func StartCPUProfile(dataDir *C.char) *C.char {
err := profiling.StartCPUProfile(C.GoString(dataDir))
return makeJSONResponse(err)
}
//export StopCPUProfiling
func StopCPUProfiling() *C.char {
err := profiling.StopCPUProfile()
return makeJSONResponse(err)
}
//export WriteHeapProfile
func WriteHeapProfile(dataDir *C.char) *C.char {
err := profiling.WriteHeapFile(C.GoString(dataDir))
return makeJSONResponse(err)
}
func makeJSONResponse(err error) *C.char {
errString := ""
if err != nil {

View File

@ -0,0 +1,57 @@
package profiling
import (
"os"
"path/filepath"
"runtime"
"runtime/pprof"
)
const (
// CPUFilename is a filename in which the CPU profiling is stored.
CPUFilename = "status_cpu.prof"
// MemFilename is a filename in which the memory profiling is stored.
MemFilename = "status_mem.prof"
)
var (
cpuFile *os.File
memFile *os.File
)
// StartCPUProfile enables CPU profiling for the current process. While profiling,
// the profile will be buffered and written to the file in folder dataDir.
func StartCPUProfile(dataDir string) error {
if cpuFile == nil {
var err error
cpuFile, err = os.Create(filepath.Join(dataDir, CPUFilename))
if err != nil {
return err
}
}
return pprof.StartCPUProfile(cpuFile)
}
// StopCPUProfile stops the current CPU profile, if any, and closes the file.
func StopCPUProfile() error {
if cpuFile == nil {
return nil
}
pprof.StopCPUProfile()
return cpuFile.Close()
}
// WriteHeapFile writes heap memory to the file.
func WriteHeapFile(dataDir string) error {
if memFile == nil {
var err error
memFile, err = os.Create(filepath.Join(dataDir, MemFilename))
if err != nil {
return err
}
defer memFile.Close()
}
runtime.GC()
return pprof.WriteHeapProfile(memFile)
}

View File

@ -0,0 +1,55 @@
package profiling
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestProfilingCPU(t *testing.T) {
dir, err := ioutil.TempDir("", "profiling")
require.NoError(t, err)
err = StartCPUProfile(dir)
require.NoError(t, err)
// Block for a bit to collect some metrics.
time.Sleep(time.Second)
err = StopCPUProfile()
require.NoError(t, err)
// Verify that the file has some content.
file, err := os.Open(filepath.Join(dir, CPUFilename))
require.NoError(t, err)
defer file.Close()
t.Logf("CPU profile saved in %s for %s", filepath.Join(dir, CPUFilename), os.Args[0])
info, err := file.Stat()
require.NoError(t, err)
require.True(t, info.Size() > 0, "a file with CPU profile is empty")
}
func TestProfilingMem(t *testing.T) {
dir, err := ioutil.TempDir("", "profiling")
require.NoError(t, err)
err = WriteHeapFile(dir)
require.NoError(t, err)
// Verify that the file has some content.
file, err := os.Open(filepath.Join(dir, MemFilename))
require.NoError(t, err)
defer file.Close()
t.Logf("Memory profile saved in %s for %s", filepath.Join(dir, MemFilename), os.Args[0])
info, err := file.Stat()
require.NoError(t, err)
require.True(t, info.Size() > 0, "a file with memory profile is empty")
}