mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
The module already called itself github.com/luxfi/node while containing no node in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and the Go column of the matrix measured a VM plugin. A repo that fetches the thing it claims to be has not replaced it, so the Go sources move in — 1515 files, the daemon and everything under it — and the build reaches outside this module for nothing. Rust and C++ sit beside it unchanged and are still measured against it by the differential. That is the point of one repo: the reference implementation and the two ports are the same checkout, so parity is a thing you can run rather than a thing you assert. Verified: builds, and the closure carries no lux-private — checked at build time rather than believed. The daemon starts twelve chains on a local network (P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
135 lines
3.1 KiB
Go
135 lines
3.1 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package profiler
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"runtime/pprof"
|
|
|
|
"github.com/luxfi/node/utils/perms"
|
|
)
|
|
|
|
const (
|
|
// Name of file that CPU profile is written to when StartCPUProfiler called
|
|
cpuProfileFile = "cpu.profile"
|
|
// Name of file that memory profile is written to when MemoryProfile called
|
|
memProfileFile = "mem.profile"
|
|
// Name of file that lock profile is written to
|
|
lockProfileFile = "lock.profile"
|
|
)
|
|
|
|
var (
|
|
_ Profiler = (*profiler)(nil)
|
|
|
|
errCPUProfilerRunning = errors.New("cpu profiler already running")
|
|
errCPUProfilerNotRunning = errors.New("cpu profiler doesn't exist")
|
|
)
|
|
|
|
// Profiler provides helper methods for measuring the current performance of
|
|
// this process
|
|
type Profiler interface {
|
|
// StartCPUProfiler starts measuring the cpu utilization of this process
|
|
StartCPUProfiler() error
|
|
|
|
// StopCPUProfiler stops measuring the cpu utilization of this process
|
|
StopCPUProfiler() error
|
|
|
|
// MemoryProfile dumps the current memory utilization of this process
|
|
MemoryProfile() error
|
|
|
|
// LockProfile dumps the current lock statistics of this process
|
|
LockProfile() error
|
|
}
|
|
|
|
type profiler struct {
|
|
dir,
|
|
cpuProfileName,
|
|
memProfileName,
|
|
lockProfileName string
|
|
|
|
cpuProfileFile *os.File
|
|
}
|
|
|
|
func New(dir string) Profiler {
|
|
return newProfiler(dir)
|
|
}
|
|
|
|
func newProfiler(dir string) *profiler {
|
|
return &profiler{
|
|
dir: dir,
|
|
cpuProfileName: filepath.Join(dir, cpuProfileFile),
|
|
memProfileName: filepath.Join(dir, memProfileFile),
|
|
lockProfileName: filepath.Join(dir, lockProfileFile),
|
|
}
|
|
}
|
|
|
|
func (p *profiler) StartCPUProfiler() error {
|
|
if p.cpuProfileFile != nil {
|
|
return errCPUProfilerRunning
|
|
}
|
|
|
|
if err := os.MkdirAll(p.dir, perms.ReadWriteExecute); err != nil {
|
|
return err
|
|
}
|
|
file, err := perms.Create(p.cpuProfileName, perms.ReadWrite)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := pprof.StartCPUProfile(file); err != nil {
|
|
_ = file.Close() // Return the original error
|
|
return err
|
|
}
|
|
runtime.SetMutexProfileFraction(1)
|
|
|
|
p.cpuProfileFile = file
|
|
return nil
|
|
}
|
|
|
|
func (p *profiler) StopCPUProfiler() error {
|
|
if p.cpuProfileFile == nil {
|
|
return errCPUProfilerNotRunning
|
|
}
|
|
|
|
pprof.StopCPUProfile()
|
|
err := p.cpuProfileFile.Close()
|
|
p.cpuProfileFile = nil
|
|
return err
|
|
}
|
|
|
|
func (p *profiler) MemoryProfile() error {
|
|
if err := os.MkdirAll(p.dir, perms.ReadWriteExecute); err != nil {
|
|
return err
|
|
}
|
|
file, err := perms.Create(p.memProfileName, perms.ReadWrite)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
runtime.GC() // get up-to-date statistics
|
|
if err := pprof.WriteHeapProfile(file); err != nil {
|
|
_ = file.Close() // Return the original error
|
|
return err
|
|
}
|
|
return file.Close()
|
|
}
|
|
|
|
func (p *profiler) LockProfile() error {
|
|
if err := os.MkdirAll(p.dir, perms.ReadWriteExecute); err != nil {
|
|
return err
|
|
}
|
|
file, err := perms.Create(p.lockProfileName, perms.ReadWrite)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
profile := pprof.Lookup("mutex")
|
|
if err := profile.WriteTo(file, 1); err != nil {
|
|
_ = file.Close() // Return the original error
|
|
return err
|
|
}
|
|
return file.Close()
|
|
}
|