원클릭으로
arc-go-gin-ssr-fmt-tracing
Add low-cost fmt/time or log.Printf timing probes to Go Gin SSR request paths.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Add low-cost fmt/time or log.Printf timing probes to Go Gin SSR request paths.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use .ai-code-index for local search, symbols, profiles, files, stats, refresh, and diagnostics.
Read-only project/AppSec audit: assets, data map, vuln review; Lark risks via arc:docs.
Local SAST/SCA/secrets/DAST automation with data-value re-ranking and Arc handoffs.
Current-state task docs; security/audit handoff to detailed subtasks with roles and caliber.
Apply backend architecture, DIP, usecase result boundaries, zap logging, Go constants, and helper limits.
Apply Chinese comment conventions; avoid noisy parameter/return boilerplate on obvious usecase contracts.
| name | arc:go-gin-ssr-fmt-tracing |
| description | Add low-cost fmt/time or log.Printf timing probes to Go Gin SSR request paths. |
Use this skill to add coarse performance timing to Go/Gin SSR code paths with minimal dependencies. Treat fmt + time as a low-cost instrumentation method, not as a profiler: it helps answer "which stage is slow", not "which function, allocation, goroutine, or lock is slow".
Use this skill when the user asks to:
Skip this skill when the user needs CPU, heap, allocation, goroutine scheduling, blocking, or lock analysis. Use pprof or go tool trace for those deeper runtime questions.
Use stage timing for:
Do not present this as sufficient for:
Escalate to pprof for CPU/heap detail and to go tool trace for goroutine scheduling and runtime behavior.
log.Printf or fmt.Fprintf(os.Stderr, ...), not plain fmt.Println.Use a helper like this when the project has no existing trace/log helper:
type Trace struct {
name string
start time.Time
}
func NewTrace(name string) *Trace {
return &Trace{
name: name,
start: time.Now(),
}
}
func (t *Trace) Done() {
log.Printf("[TRACE] stage=%s cost_ms=%d", t.name, time.Since(t.start).Milliseconds())
}
For AI-readable logs, prefer JSON lines:
func (t *Trace) Done() {
log.Printf(`{"event":"ssr_trace","stage":"%s","cost_ms":%d}`,
t.name,
time.Since(t.start).Milliseconds(),
)
}
If stage names can contain quotes or user-controlled values, use encoding/json or a structured logger instead of formatting JSON by hand.
When Gin context already contains a request ID, thread it into each trace:
func NewTraceWithID(reqID, stage string) *Trace {
return NewTrace(fmt.Sprintf("[%s] %s", reqID, stage))
}
For cleaner structured output, keep request ID as a separate key:
type Trace struct {
reqID string
stage string
start time.Time
}
func NewTrace(reqID, stage string) *Trace {
return &Trace{reqID: reqID, stage: stage, start: time.Now()}
}
func (t *Trace) Done() {
log.Printf(`{"event":"ssr_trace","request_id":"%s","stage":"%s","cost_ms":%d}`,
t.reqID,
t.stage,
time.Since(t.start).Milliseconds(),
)
}
If request IDs are missing and middleware is in scope:
func RequestID() gin.HandlerFunc {
return func(c *gin.Context) {
c.Set("req_id", uuid.NewString())
c.Next()
}
}
Instrument the standard SSR path like this, adapting names to the repo:
func GetArticle(c *gin.Context) {
reqID, _ := c.Get("req_id")
trace := NewTrace(fmt.Sprint(reqID), "TOTAL")
defer trace.Done()
t1 := NewTrace(fmt.Sprint(reqID), "FETCH")
data, err := service.GetData(c.Request.Context())
t1.Done()
if err != nil {
// Return using the repo's existing error response pattern.
return
}
t2 := NewTrace(fmt.Sprint(reqID), "BUILD_VIEW")
vm := buildViewModel(data)
t2.Done()
t3 := NewTrace(fmt.Sprint(reqID), "RENDER_TEMPLATE")
html, err := renderTemplate(vm)
t3.Done()
if err != nil {
// Return using the repo's existing error response pattern.
return
}
t4 := NewTrace(fmt.Sprint(reqID), "WRITE_RESPONSE")
c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(html))
t4.Done()
}
Use defer only for the total request timer or for stages with multiple returns. For short linear stages, call Done() immediately after the operation so the measured range is obvious.
Prefer one log line per stage:
{"event":"ssr_trace","request_id":"abc","stage":"FETCH","cost_ms":12}
{"event":"ssr_trace","request_id":"abc","stage":"BUILD_VIEW","cost_ms":3}
{"event":"ssr_trace","request_id":"abc","stage":"RENDER_TEMPLATE","cost_ms":45}
{"event":"ssr_trace","request_id":"abc","stage":"TOTAL","cost_ms":67}
Use stable stage names such as TOTAL, FETCH, DB_QUERY, RPC_CALL, BUILD_VIEW, RENDER_TEMPLATE, and WRITE_RESPONSE. Include route, handler, tenant, or user only when safe and useful; never log secrets, tokens, raw authorization headers, full payloads, or sensitive personal data.
log or fmt, time, and possibly os.