(ctx context.Context, d *Deps, b *Bundle)
| 1166 | } |
| 1167 | |
| 1168 | func collectPprof(ctx context.Context, d *Deps, b *Bundle) Pprof { |
| 1169 | var pprof Pprof |
| 1170 | |
| 1171 | // Check server version before attempting pprof collection. |
| 1172 | if b.Deployment.BuildInfo == nil { |
| 1173 | d.Log.Warn(ctx, "skipping pprof collection: build info not available") |
| 1174 | return pprof |
| 1175 | } |
| 1176 | if !VersionSupportsPprof(b.Deployment.BuildInfo.Version) { |
| 1177 | d.Log.Warn(ctx, "skipping pprof collection: server version too old", |
| 1178 | slog.F("version", b.Deployment.BuildInfo.Version), |
| 1179 | slog.F("min_version", minPprofVersion)) |
| 1180 | return pprof |
| 1181 | } |
| 1182 | |
| 1183 | // Try the consolidated /debug/profile endpoint first. It |
| 1184 | // temporarily enables block/mutex profiling on the server and |
| 1185 | // returns a single tar.gz archive. |
| 1186 | serverPprof, err := PprofInfoFromArchive(ctx, d.Client, d.Log, 30*time.Second) |
| 1187 | if err != nil { |
| 1188 | d.Log.Warn(ctx, "consolidated profile endpoint unavailable, falling back to individual endpoints", |
| 1189 | slog.Error(err)) |
| 1190 | // Fall back to the legacy per-profile endpoint approach. |
| 1191 | serverPprof = PprofInfo(ctx, d.Client, d.Log) |
| 1192 | } |
| 1193 | if serverPprof != nil { |
| 1194 | pprof.Server = serverPprof |
| 1195 | } |
| 1196 | |
| 1197 | if d.AgentID != uuid.Nil { |
| 1198 | conn, err := workspacesdk.New(d.Client). |
| 1199 | DialAgent(ctx, d.AgentID, &workspacesdk.DialAgentOptions{ |
| 1200 | Logger: d.Log.Named("dial-agent-pprof"), |
| 1201 | BlockEndpoints: false, |
| 1202 | }) |
| 1203 | if err != nil { |
| 1204 | d.Log.Warn(ctx, "failed to dial agent for pprof collection", slog.Error(err)) |
| 1205 | } else { |
| 1206 | defer func() { |
| 1207 | if err := conn.Close(); err != nil { |
| 1208 | d.Log.Error(ctx, "failed to close agent pprof connection", slog.Error(err)) |
| 1209 | } |
| 1210 | <-conn.TailnetConn().Closed() |
| 1211 | }() |
| 1212 | |
| 1213 | if conn.AwaitReachable(ctx) { |
| 1214 | agentPprof := PprofInfoFromAgent(ctx, conn, d.Log) |
| 1215 | if agentPprof != nil { |
| 1216 | pprof.Agent = agentPprof |
| 1217 | } |
| 1218 | } else { |
| 1219 | d.Log.Warn(ctx, "agent not reachable for pprof collection") |
| 1220 | } |
| 1221 | } |
| 1222 | } |
| 1223 | |
| 1224 | return pprof |
| 1225 | } |
no test coverage detected