@@ -48,6 +48,7 @@ import (
48
48
"github.com/parca-dev/parca-agent/pkg/logger"
49
49
"github.com/parca-dev/parca-agent/pkg/objectfile"
50
50
"github.com/parca-dev/parca-agent/pkg/profiler"
51
+ "github.com/parca-dev/parca-agent/pkg/template"
51
52
)
52
53
53
54
var (
@@ -134,7 +135,6 @@ func main() {
134
135
level .Warn (logger ).Log ("msg" , "--temp-dir is deprecated and will be removed in a future release." )
135
136
}
136
137
137
- mux := http .NewServeMux ()
138
138
reg := prometheus .NewRegistry ()
139
139
reg .MustRegister (
140
140
collectors .NewBuildInfoCollector (),
@@ -192,76 +192,31 @@ func main() {
192
192
flags .SamplingRatio ,
193
193
)
194
194
195
+ mux := http .NewServeMux ()
195
196
mux .Handle ("/metrics" , promhttp .HandlerFor (reg , promhttp.HandlerOpts {}))
196
197
mux .HandleFunc ("/debug/pprof/" , pprof .Index )
197
198
mux .HandleFunc ("/debug/pprof/cmdline" , pprof .Cmdline )
198
199
mux .HandleFunc ("/debug/pprof/profile" , pprof .Profile )
199
200
mux .HandleFunc ("/debug/pprof/symbol" , pprof .Symbol )
200
201
mux .HandleFunc ("/debug/pprof/trace" , pprof .Trace )
201
- /* // Temporarily comment out the web interface
202
- mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
202
+ mux .HandleFunc ("/" , func (w http.ResponseWriter , r * http.Request ) {
203
203
if r .URL .Path == "/favicon.ico" {
204
204
return
205
205
}
206
206
if r .URL .Path == "/" {
207
207
w .Header ().Set ("Content-Type" , "text/html; charset=utf-8" )
208
- activeProfilers := tm.ActiveProfilers()
209
-
208
+ profilers := pp .Profilers ()
210
209
statusPage := template.StatusPage {}
211
210
212
- for _, profilerSet := range activeProfilers {
213
- for _, profiler := range profilerSet {
214
- profileType := ""
215
- labelSet := labels.Labels{}
216
-
217
- for name, value := range profiler.Labels() {
218
- if name == "__name__" {
219
- profileType = string(value)
220
- }
221
- if name != "__name__" {
222
- labelSet = append(labelSet,
223
- labels.Label{Name: string(name), Value: string(value)})
224
- }
225
- }
226
-
227
- sort.Sort(labelSet)
228
-
229
- q := url.Values{}
230
- q.Add("debug", "1")
231
- q.Add("query", labelSet.String())
232
-
233
- statusPage.ActiveProfilers = append(statusPage.ActiveProfilers, template.ActiveProfiler{
234
- Type: profileType,
235
- Labels: labelSet,
236
- Interval: flags.ProfilingDuration,
237
- NextStartedAgo: time.Since(profiler.NextProfileStartedAt()),
238
- Error: profiler.LastError(),
239
- Link: fmt.Sprintf("/query?%s", q.Encode()),
240
- })
241
- }
242
- }
243
-
244
- sort.Slice(statusPage.ActiveProfilers, func(j, k int) bool {
245
- a := statusPage.ActiveProfilers[j].Labels
246
- b := statusPage.ActiveProfilers[k].Labels
247
-
248
- l := len(a)
249
- if len(b) < l {
250
- l = len(b)
251
- }
252
-
253
- for i := 0; i < l; i++ {
254
- if a[i].Name != b[i].Name {
255
- return a[i].Name < b[i].Name
256
- }
257
- if a[i].Value != b[i].Value {
258
- return a[i].Value < b[i].Value
259
- }
260
- }
261
- // If all labels so far were in common, the set with fewer labels comes first.
262
- return len(a)-len(b) < 0
263
- })
211
+ for name , profiler := range profilers {
212
+ statusPage .ActiveProfilers = append (statusPage .ActiveProfilers , template.ActiveProfiler {
213
+ Name : name ,
214
+ Interval : flags .ProfilingDuration ,
215
+ NextStartedAgo : time .Since (profiler .NextProfileStartedAt ()),
216
+ Error : profiler .LastError (),
217
+ })
264
218
219
+ }
265
220
err := template .StatusPageTemplate .Execute (w , statusPage )
266
221
if err != nil {
267
222
http .Error (w ,
@@ -273,68 +228,8 @@ func main() {
273
228
return
274
229
}
275
230
276
- if strings.HasPrefix(r.URL.Path, "/query") {
277
- ctx := r.Context()
278
- query := r.URL.Query().Get("query")
279
- matchers, err := parser.ParseMetricSelector(query)
280
- if err != nil {
281
- http.Error(w,
282
- `query incorrectly formatted, expecting selector in form of: {name1="value1",name2="value2"}`,
283
- http.StatusBadRequest,
284
- )
285
- return
286
- }
287
-
288
- // We profile every ProfilingDuration so leaving 1s wiggle room. If after
289
- // ProfilingDuration+1s no profile has matched, then there is very likely no
290
- // profiler running that matches the label-set.
291
- timeout := flags.ProfilingDuration + time.Second
292
- ctx, cancel := context.WithTimeout(ctx, timeout)
293
- defer cancel()
294
-
295
- profile, err := profileListener.NextMatchingProfile(ctx, matchers)
296
- if profile == nil || errors.Is(err, context.Canceled) {
297
- http.Error(w, fmt.Sprintf(
298
- "No profile taken in the last %s that matches the requested label-matchers query. "+
299
- "Profiles are taken every %s so either the profiler matching the label-set has stopped profiling, "+
300
- "or the label-set was incorrect.",
301
- timeout, flags.ProfilingDuration,
302
- ), http.StatusNotFound)
303
- return
304
- }
305
- if err != nil {
306
- http.Error(w, "Unexpected error occurred: "+err.Error(), http.StatusInternalServerError)
307
- return
308
- }
309
-
310
- v := r.URL.Query().Get("debug")
311
- if v == "1" {
312
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
313
- q := url.Values{}
314
- q.Add("query", query)
315
-
316
- fmt.Fprintf(
317
- w,
318
- "<p><a title='May take up %s to retrieve' href='/query?%s'>Download Next Pprof</a></p>\n",
319
- flags.ProfilingDuration,
320
- q.Encode(),
321
- )
322
- fmt.Fprint(w, "<code><pre>\n")
323
- fmt.Fprint(w, profile.String())
324
- fmt.Fprint(w, "\n</pre></code>")
325
- return
326
- }
327
-
328
- w.Header().Set("Content-Type", "application/vnd.google.protobuf+gzip")
329
- w.Header().Set("Content-Disposition", "attachment;filename=profile.pb.gz")
330
- err = profile.Write(w)
331
- if err != nil {
332
- level.Error(logger).Log("msg", "failed to write profile", "err", err)
333
- }
334
- return
335
- }
336
231
http .NotFound (w , r )
337
- }) */
232
+ })
338
233
339
234
ctx := context .Background ()
340
235
var g run.Group
0 commit comments