|
|
@ -1,6 +1,11 @@ |
|
|
|
package profiler |
|
|
|
package profiler |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
|
|
|
|
"bytes" |
|
|
|
|
|
|
|
"net/http" |
|
|
|
|
|
|
|
"net/url" |
|
|
|
|
|
|
|
"os" |
|
|
|
|
|
|
|
"sync" |
|
|
|
"time" |
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/shirou/gopsutil/process" |
|
|
|
"github.com/shirou/gopsutil/process" |
|
|
@ -8,15 +13,30 @@ import ( |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
type Profiler struct { |
|
|
|
type Profiler struct { |
|
|
|
|
|
|
|
// parameters
|
|
|
|
logger log.Logger |
|
|
|
logger log.Logger |
|
|
|
PID int32 |
|
|
|
pid int32 |
|
|
|
ShardID string |
|
|
|
shardID string |
|
|
|
|
|
|
|
MetricsReportURL string |
|
|
|
|
|
|
|
// Internal
|
|
|
|
proc *process.Process |
|
|
|
proc *process.Process |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func NewProfiler(logger log.Logger, pid int, shardID string) *Profiler { |
|
|
|
var singleton *Profiler |
|
|
|
profiler := Profiler{logger, int32(pid), shardID, nil} |
|
|
|
var once sync.Once |
|
|
|
return &profiler |
|
|
|
|
|
|
|
|
|
|
|
func GetProfiler() *Profiler { |
|
|
|
|
|
|
|
once.Do(func() { |
|
|
|
|
|
|
|
singleton = &Profiler{} |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
return singleton |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (profiler *Profiler) Config(logger log.Logger, shardID string, metricsReportURL string) { |
|
|
|
|
|
|
|
profiler.logger = logger |
|
|
|
|
|
|
|
profiler.pid = int32(os.Getpid()) |
|
|
|
|
|
|
|
profiler.shardID = shardID |
|
|
|
|
|
|
|
profiler.MetricsReportURL = metricsReportURL |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (profiler *Profiler) LogMemory() { |
|
|
|
func (profiler *Profiler) LogMemory() { |
|
|
@ -24,7 +44,7 @@ func (profiler *Profiler) LogMemory() { |
|
|
|
// log mem usage
|
|
|
|
// log mem usage
|
|
|
|
info, _ := profiler.proc.MemoryInfo() |
|
|
|
info, _ := profiler.proc.MemoryInfo() |
|
|
|
memMap, _ := profiler.proc.MemoryMaps(false) |
|
|
|
memMap, _ := profiler.proc.MemoryMaps(false) |
|
|
|
profiler.logger.Info("Mem Report", "info", info, "map", memMap, "shardID", profiler.ShardID) |
|
|
|
profiler.logger.Info("Mem Report", "info", info, "map", memMap, "shardID", profiler.shardID) |
|
|
|
|
|
|
|
|
|
|
|
time.Sleep(3 * time.Second) |
|
|
|
time.Sleep(3 * time.Second) |
|
|
|
} |
|
|
|
} |
|
|
@ -35,14 +55,22 @@ func (profiler *Profiler) LogCPU() { |
|
|
|
// log cpu usage
|
|
|
|
// log cpu usage
|
|
|
|
percent, _ := profiler.proc.CPUPercent() |
|
|
|
percent, _ := profiler.proc.CPUPercent() |
|
|
|
times, _ := profiler.proc.Times() |
|
|
|
times, _ := profiler.proc.Times() |
|
|
|
profiler.logger.Info("CPU Report", "percent", percent, "times", times, "shardID", profiler.ShardID) |
|
|
|
profiler.logger.Info("CPU Report", "percent", percent, "times", times, "shardID", profiler.shardID) |
|
|
|
|
|
|
|
|
|
|
|
time.Sleep(3 * time.Second) |
|
|
|
time.Sleep(3 * time.Second) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (profiler *Profiler) LogMetrics(metrics url.Values) { |
|
|
|
|
|
|
|
body := bytes.NewBufferString(metrics.Encode()) |
|
|
|
|
|
|
|
rsp, err := http.Post(profiler.MetricsReportURL, "application/x-www-form-urlencoded", body) |
|
|
|
|
|
|
|
if err == nil { |
|
|
|
|
|
|
|
defer rsp.Body.Close() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (profiler *Profiler) Start() { |
|
|
|
func (profiler *Profiler) Start() { |
|
|
|
profiler.proc, _ = process.NewProcess(profiler.PID) |
|
|
|
profiler.proc, _ = process.NewProcess(profiler.pid) |
|
|
|
go profiler.LogCPU() |
|
|
|
go profiler.LogCPU() |
|
|
|
go profiler.LogMemory() |
|
|
|
go profiler.LogMemory() |
|
|
|
} |
|
|
|
} |
|
|
|