ข้ามไปยังเนื้อหา

pprof Profiling

ใน Node.js คุณมี node --prof (V8 CPU profiler), node --inspect (Chrome DevTools) และเครื่องมืออย่าง clinic.js (clinic doctor, clinic flame) สำหรับวิเคราะห์ heap และ event loop ทั้งหมดทำงานแบบ out-of-process หรือไม่ก็ต้อง wrap คำสั่ง start

Go มาพร้อม runtime/pprof ใน standard library และ net/http/pprof สำหรับ profiling ผ่าน HTTP แบบ live — เก็บ profile ได้โดยไม่ต้องพึ่งเครื่องมือภายนอก และคำสั่ง go tool pprof ก็จัดการการวิเคราะห์ให้

หมายเหตุเรื่อง Playground: pprof ต้องเขียนไฟล์ profile ลง disk แล้วรัน go tool pprof บล็อกโค้ดด้านล่างคือไฟล์จริง — รันบนเครื่องคุณ

main.go
package main
import (
"os"
"runtime/pprof"
"log"
)
func main() {
// --- CPU profile ---
cpuFile, err := os.Create("cpu.out")
if err != nil {
log.Fatal(err)
}
defer cpuFile.Close()
if err := pprof.StartCPUProfile(cpuFile); err != nil {
log.Fatal(err)
}
defer pprof.StopCPUProfile()
// ... โค้ดที่ต้องการทดสอบ ...
doWork()
// --- Heap profile (เขียนตอนท้าย) ---
heapFile, err := os.Create("mem.out")
if err != nil {
log.Fatal(err)
}
defer heapFile.Close()
pprof.WriteHeapProfile(heapFile)
}
main.go
package main
import (
"net/http"
_ "net/http/pprof" // blank import register routes /debug/pprof/
"log"
)
func main() {
// Application server ของคุณ
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
// ... rest of app ...
}

endpoint ที่มีให้:

  • http://localhost:6060/debug/pprof/ — index
  • http://localhost:6060/debug/pprof/profile?seconds=30 — CPU profile 30 วินาที
  • http://localhost:6060/debug/pprof/heap — heap snapshot
  • http://localhost:6060/debug/pprof/goroutine — stack ของทุก goroutine
  • http://localhost:6060/debug/pprof/trace?seconds=5 — execution trace
TypeScript
// Node.js — เครื่องมือหลายอย่าง ทั้งหมดภายนอก
// Option 1: built-in V8 profiler
node --prof server.js
node --prof-process isolate-*.log > report.txt
// Option 2: clinic.js (npm install -g clinic)
clinic doctor -- node server.js
clinic flame -- node server.js
// Option 3: Chrome DevTools
node --inspect server.js // open chrome://inspect
Go
// Go — เครื่องมือเดียว มาพร้อม toolchain
// Collect CPU profile 30 วินาที จาก live server:
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
// Collect จากไฟล์ที่เขียนโดย runtime/pprof:
go tool pprof cpu.out
// เปิด interactive web UI (ต้องการ Graphviz):
go tool pprof -http=:8080 cpu.out
Terminal window
# เริ่ม interactive pprof shell
go tool pprof cpu.out
# ภายใน shell:
(pprof) top10 # top 10 functions ตาม CPU time
(pprof) list myFunc # annotated source สำหรับ myFunc
(pprof) web # เปิด SVG flame graph ใน browser
(pprof) pdf # save เป็น PDF
# หรือเปิด web UI โดยตรง (flame graphs สวยกว่า)
go tool pprof -http=:8080 cpu.out

ตัวอย่าง output จาก top10:

Showing nodes accounting for 2.40s, 96.77% of 2.48s total
flat flat% sum% cum cum%
1.20s 48.39% 48.39% 1.20s 48.39% runtime.mallocgc
0.60s 24.19% 72.58% 0.60s 24.19% strings.(*Builder).WriteString
0.30s 12.10% 84.68% 0.30s 12.10% main.processItem
คอลัมน์ความหมาย
flatเวลาที่ใช้ ใน ฟังก์ชันนี้ (ไม่รวม callees)
flat%เปอร์เซ็นต์ของ total profile time
cumเวลา cumulative (ฟังก์ชันนี้ + ฟังก์ชันทั้งหมดที่ฟังก์ชันนี้เรียกต่อ)
cum%เปอร์เซ็นต์ cumulative
Terminal window
go tool pprof mem.out
(pprof) top10 -cum # top allocators ตาม cumulative bytes
(pprof) list myFunc # line-level allocation counts

heap profile แสดง:

  • alloc_objects / alloc_space — allocation รวมทั้งหมดตั้งแต่โปรแกรมเริ่มรัน
  • inuse_objects / inuse_space — object/byte ที่ยังถูกใช้อยู่ (หลัง GC)
Terminal window
# เขียน CPU + memory profiles ระหว่าง benchmark run
go test -bench=BenchmarkFoo -cpuprofile=cpu.out -memprofile=mem.out ./...
# แล้ว analyse
go tool pprof cpu.out
go tool pprof mem.out
Terminal window
# ตรวจสอบ goroutine leaks (ควร flat ตลอดเวลา)
go tool pprof http://localhost:6060/debug/pprof/goroutine
# Execution trace — แสดง scheduling, GC, goroutine lifecycle
curl -s "http://localhost:6060/debug/pprof/trace?seconds=5" > trace.out
go tool trace trace.out

execution trace คือมุมมองที่ละเอียดที่สุด: แสดงทุกครั้งที่ goroutine start/stop, ทุก GC pause, ทุกครั้งที่ block รอ network และ system call — คล้ายกับที่ clinic doctor ทำให้ event loop ของ Node

blank import ใดที่ register HTTP endpoints /debug/pprof/?
ใน pprof output คอลัมน์ "flat" แสดงถึงอะไร?
คำสั่งใดที่เปิด interactive flame graph web UI สำหรับ profile file?
ทำไมถึงไม่ควร expose pprof endpoints บน public interface?