mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 03:10:42 +08:00
103 lines
3.1 KiB
Go
103 lines
3.1 KiB
Go
//go:build debug
|
|
// +build debug
|
|
|
|
package debug
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
"runtime/pprof"
|
|
"runtime/trace"
|
|
|
|
"github.com/shadow1ng/fscan/common/i18n"
|
|
)
|
|
|
|
var (
|
|
cpuProfile *os.File
|
|
traceFile *os.File
|
|
profilesPath = "./profiles"
|
|
)
|
|
|
|
func Start() {
|
|
if err := os.MkdirAll(profilesPath, 0755); err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_create_profiles_failed", err))
|
|
return
|
|
}
|
|
|
|
var err error
|
|
cpuProfile, err = os.Create(profilesPath + "/cpu.prof")
|
|
if err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_create_cpu_profile_failed", err))
|
|
} else {
|
|
if err := pprof.StartCPUProfile(cpuProfile); err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_start_cpu_profile_failed", err))
|
|
cpuProfile.Close()
|
|
cpuProfile = nil
|
|
} else {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_cpu_profile_started", profilesPath))
|
|
}
|
|
}
|
|
|
|
traceFile, err = os.Create(profilesPath + "/trace.out")
|
|
if err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_create_trace_failed", err))
|
|
} else {
|
|
if err := trace.Start(traceFile); err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_start_trace_failed", err))
|
|
traceFile.Close()
|
|
traceFile = nil
|
|
} else {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_trace_started", profilesPath))
|
|
}
|
|
}
|
|
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_profiling_started", profilesPath))
|
|
}
|
|
|
|
func Stop() {
|
|
if cpuProfile != nil {
|
|
pprof.StopCPUProfile()
|
|
cpuProfile.Close()
|
|
fmt.Printf("[DEBUG] %s\n", i18n.GetText("debug_cpu_profile_saved"))
|
|
}
|
|
|
|
if traceFile != nil {
|
|
trace.Stop()
|
|
traceFile.Close()
|
|
fmt.Printf("[DEBUG] %s\n", i18n.GetText("debug_trace_saved"))
|
|
}
|
|
|
|
memProfile, err := os.Create(profilesPath + "/mem.prof")
|
|
if err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_create_mem_profile_failed", err))
|
|
} else {
|
|
runtime.GC()
|
|
if err := pprof.WriteHeapProfile(memProfile); err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_write_mem_profile_failed", err))
|
|
} else {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_mem_profile_saved", profilesPath))
|
|
}
|
|
memProfile.Close()
|
|
}
|
|
|
|
goroutineProfile, err := os.Create(profilesPath + "/goroutine.prof")
|
|
if err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_create_goroutine_profile_failed", err))
|
|
} else {
|
|
if err := pprof.Lookup("goroutine").WriteTo(goroutineProfile, 0); err != nil {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_write_goroutine_profile_failed", err))
|
|
} else {
|
|
fmt.Printf("[DEBUG] %s\n", i18n.Tr("debug_goroutine_profile_saved", profilesPath))
|
|
}
|
|
goroutineProfile.Close()
|
|
}
|
|
|
|
fmt.Printf("\n[DEBUG] %s\n", i18n.Tr("debug_profiles_saved", profilesPath))
|
|
fmt.Printf("[DEBUG] %s\n", i18n.GetText("debug_view_methods"))
|
|
fmt.Printf(" %s: go tool pprof -http=:8081 %s/cpu.prof\n", i18n.GetText("debug_cpu_flamegraph"), profilesPath)
|
|
fmt.Printf(" %s: go tool pprof -http=:8081 %s/mem.prof\n", i18n.GetText("debug_mem_flamegraph"), profilesPath)
|
|
fmt.Printf(" %s: go tool pprof -http=:8081 %s/goroutine.prof\n", i18n.GetText("debug_goroutine_analysis"), profilesPath)
|
|
fmt.Printf(" %s: go tool trace %s/trace.out\n", i18n.GetText("debug_execution_timeline"), profilesPath)
|
|
}
|