Skip to content

Conversation

@LordofAvernus
Copy link
Collaborator

@LordofAvernus LordofAvernus commented Nov 26, 2025

User description

  • Introduced pprof package for collecting various profiles (heap, goroutine, allocs, block, mutex).
  • Enhanced NotifySignal function to handle SIGUSR1 for triggering pprof profile collection.
  • Registered pprof routes in the API for memory leak diagnosis and profiling access.

关联的 issue

#3177

描述你的变更

  • 新增pprof性能监控

确认项(pr提交后操作)

Tip

请在指定复审人之前,确认并完成以下事项,完成后✅


  • 我已完成自测
  • 我已记录完整日志方便进行诊断
  • 我已在关联的issue里补充了实现方案
  • 我已在关联的issue里补充了测试影响面
  • 我已确认了变更的兼容性,如果不兼容则在issue里标记 not_compatible
  • 我已确认了是否要更新文档,如果要更新则在issue里标记 need_update_doc


Description

  • 新增 pprof 配置项

  • 实现多种 profile 采集功能

  • 新增独立 pprof HTTP 服务器

  • 增强信号处理支持 SIGUSR1


Diagram Walkthrough

flowchart LR
  A["新增 pprof 配置项"] --> B["采集多种 profile 数据"]
  B --> C["启动独立 pprof HTTP 服务器"]
  C --> D["增强 SIGUSR1 信号触发采集"]
Loading

File Walkthrough

Relevant files
Configuration changes
config.go
新增 pprof 端口配置项                                                                                     

sqle/config/config.go

  • 添加 pprof_port 配置项,用于启用 pprof 服务器
+1/-0     
Enhancement
collector.go
新增 pprof 采集模块及工具函数                                                                             

sqle/pprof/collector.go

  • 新增 pprof 采集模块,支持 heap、goroutine、allocs、block、mutex 与 cpu profile
  • 提供通用采集函数 collectProfile
  • 添加 StartPeriodicCollection 定时采集函数
+135/-0 
server.go
新增独立 pprof HTTP 服务器模块                                                                       

sqle/pprof/server.go

  • 新增独立 pprof HTTP 服务器启动函数 StartServer
  • 提供异步启动方法 StartServerAsync
+43/-0   
sqled.go
修改信号处理与启动 pprof 服务                                                                             

sqle/sqled.go

  • 修改 NotifySignal 函数参数,增加 logPath
  • 增加 SIGUSR1 信号处理,触发 pprof 采集
  • 调用 pprof.StartServerAsync 启动 pprof 服务
+36/-15 

- Introduced pprof package for collecting various profiles (heap, goroutine, allocs, block, mutex).
- Enhanced NotifySignal function to handle SIGUSR1 for triggering pprof profile collection.
- Registered pprof routes in the API for memory leak diagnosis and profiling access.
@github-actions
Copy link

PR Reviewer Guide 🔍

🎫 Ticket compliance analysis 🔶

3177 - Partially compliant

Compliant requirements:

  • 新增 pprof 配置项
  • 支持多种 profile 采集
  • 实现独立 pprof HTTP 服务器
  • 增强信号处理支持 SIGUSR1 和 SIGUSR2

Non-compliant requirements:

Requires further human verification:

  • 部署环境中 pprof 服务器的安全性验证
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

安全风险

新增的 pprof HTTP 服务器在监听 0.0.0.0 时可能会暴露敏感性能数据,建议在生产环境中通过防火墙或其他访问控制措施加以限制,确保数据安全。

func StartServer(port int) error {
	if port <= 0 {
		log.Logger().Infof("pprof server disabled (port: %d)", port)
		return nil
	}

	address := fmt.Sprintf("0.0.0.0:%d", port)
	log.Logger().Infof("starting pprof server on %s", address)

	// pprof 包在导入时会自动注册路由到 http.DefaultServeMux
	// 只需要启动一个 HTTP 服务器即可
	if err := http.ListenAndServe(address, nil); err != nil {
		return fmt.Errorf("pprof server failed: %v", err)
	}

	return nil
}
错误处理

在 CollectAllProfiles 函数中,对于各 profile 采集的错误采用覆盖方式记录,建议聚合所有错误信息或分别处理各个错误,以便更全面地监控采集过程中的问题。

func CollectAllProfiles(logPath string) error {
	profiles := []struct {
		name string
		fn   func(string) error
	}{
		{"heap", CollectHeapProfile},
		{"goroutine", CollectGoroutineProfile},
		{"allocs", CollectAllocsProfile},
		{"block", CollectBlockProfile},
		{"mutex", CollectMutexProfile},
	}

	var lastErr error
	for _, p := range profiles {
		if err := p.fn(logPath); err != nil {
			log.Logger().Errorf("failed to collect %s profile: %v", p.name, err)
			lastErr = err
		}
	}

	return lastErr
}

@github-actions
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
删除失败时残留文件

建议在写入 profile 失败时,删除已创建的不完整文件,以防止生成无用或损坏的 profile 文件。这样可以避免占用无效的磁盘资源并保证输出质量。

sqle/pprof/collector.go [83-85]

 if err := writeFunc(f); err != nil {
+    f.Close()
+    os.Remove(filePath)
     return fmt.Errorf("failed to write profile: %v", err)
 }
Suggestion importance[1-10]: 7

__

Why: The suggestion enhances error handling by removing an incomplete profile file on a write failure, which improves resource cleanup and output quality.

Medium
General
异步处理 pprof 收集

建议将 pprof profile 收集操作放入独立的 goroutine
中以异步执行,防止在信号处理过程中长时间阻塞后续信号的处理。这可以提高系统对连续信号触发的响应能力。

sqle/sqled.go [192-201]

 case syscall.SIGUSR1:
-    // Trigger pprof collection
-    log.Logger().Infof("Received SIGUSR1, collecting pprof profiles...")
-    if err := pprof.CollectAllProfiles(logPath); err != nil {
-        log.Logger().Errorf("Failed to collect pprof profiles: %v", err)
-    } else {
-        log.Logger().Infof("pprof profiles collected successfully")
-    }
-    // Continue running after collecting profiles
+    log.Logger().Infof("Received SIGUSR1, collecting pprof profiles asynchronously...")
+    go func() {
+        if err := pprof.CollectAllProfiles(logPath); err != nil {
+            log.Logger().Errorf("Failed to collect pprof profiles: %v", err)
+        } else {
+            log.Logger().Infof("pprof profiles collected successfully")
+        }
+    }()
     continue
Suggestion importance[1-10]: 6

__

Why: The suggestion moves the pprof profile collection into a goroutine to avoid blocking the signal loop. This is a moderate improvement since the signal handler is already in a separate goroutine and may not need asynchronous handling.

Low

@winfredLIN winfredLIN merged commit 93c2390 into main Nov 26, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants