func streamQueryzHandler(queryList *QueryList, w http.ResponseWriter, r *http.Request) { if err := acl.CheckAccessHTTP(r, acl.DEBUGGING); err != nil { acl.SendError(w, err) return } rows := queryList.GetQueryzRows() if err := r.ParseForm(); err != nil { http.Error(w, fmt.Sprintf("cannot parse form: %s", err), http.StatusInternalServerError) return } format := r.FormValue("format") if format == "json" { js, err := json.Marshal(rows) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.Write(js) return } logz.StartHTMLTable(w) defer logz.EndHTMLTable(w) w.Write(streamqueryzHeader) for i := range rows { if err := streamqueryzTmpl.Execute(w, rows[i]); err != nil { log.Errorf("streamlogz: couldn't execute template: %v", err) } } }
func schemazHandler(tables []*schema.Table, w http.ResponseWriter, r *http.Request) { if err := acl.CheckAccessHTTP(r, acl.DEBUGGING); err != nil { acl.SendError(w, err) return } logz.StartHTMLTable(w) defer logz.EndHTMLTable(w) w.Write(schemazHeader) sorter := schemazSorter{ rows: tables, less: func(row1, row2 *schema.Table) bool { return row1.Name > row2.Name }, } sort.Sort(&sorter) envelope := struct { Type []string Table *schema.Table }{ Type: schema.TypeNames, } for _, Value := range sorter.rows { envelope.Table = Value if err := schemazTmpl.Execute(w, envelope); err != nil { log.Errorf("schemaz: couldn't execute template: %v", err) } } }
func showThrottlerLog(w http.ResponseWriter, m *managerImpl, name string) { results, err := m.Log(name) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } logz.StartHTMLTable(w) if _, err := io.WriteString(w, logHeaderHTML); err != nil { panic(fmt.Sprintf("failed to execute logHeader template: %v", err)) } for _, r := range results { // Color based on max(tested state, new state). state := r.TestedState if stateGreater(r.NewState, state) { state = r.NewState } var colorLevel string switch state { case stateIncreaseRate: colorLevel = "low" case stateDecreaseAndGuessRate: colorLevel = "medium" case stateEmergency: colorLevel = "high" } data := struct { result ColorLevel string }{r, colorLevel} if err := logEntryTemplate.Execute(w, data); err != nil { panic(fmt.Sprintf("failed to execute logEntry template: %v", err)) } } logz.EndHTMLTable(w) // Print footer. count := len(results) var d time.Duration if count > 0 { d = results[0].Now.Sub(results[count-1].Now) } if err := logFooterTemplate.Execute(w, map[string]interface{}{ "Count": count, "TimeSpan": fmt.Sprintf("%.1f", d.Minutes()), }); err != nil { panic(fmt.Sprintf("failed to execute logFooter template: %v", err)) } }
// querylogzHandler serves a human readable snapshot of the // current query log. func querylogzHandler(ch chan interface{}, w http.ResponseWriter, r *http.Request) { if err := acl.CheckAccessHTTP(r, acl.DEBUGGING); err != nil { acl.SendError(w, err) return } timeout, limit := parseTimeoutLimitParams(r) logz.StartHTMLTable(w) defer logz.EndHTMLTable(w) w.Write(querylogzHeader) tmr := time.NewTimer(timeout) defer tmr.Stop() for i := 0; i < limit; i++ { select { case out := <-ch: select { case <-tmr.C: return default: } stats, ok := out.(*LogStats) if !ok { err := fmt.Errorf("Unexpected value in %s: %#v (expecting value of type %T)", TxLogger.Name(), out, &LogStats{}) io.WriteString(w, `<tr class="error">`) io.WriteString(w, err.Error()) io.WriteString(w, "</tr>") log.Error(err) continue } var level string if stats.TotalTime().Seconds() < 0.01 { level = "low" } else if stats.TotalTime().Seconds() < 0.1 { level = "medium" } else { level = "high" } tmplData := struct { *LogStats ColorLevel string }{stats, level} if err := querylogzTmpl.Execute(w, tmplData); err != nil { log.Errorf("querylogz: couldn't execute template: %v", err) } case <-tmr.C: return } } }
// txlogzHandler serves a human readable snapshot of the // current transaction log. // Endpoint: /txlogz?timeout=%d&limit=%d // timeout: the txlogz will keep dumping transactions until timeout // limit: txlogz will keep dumping transcations until it hits the limit func txlogzHandler(w http.ResponseWriter, req *http.Request) { if err := acl.CheckAccessHTTP(req, acl.DEBUGGING); err != nil { acl.SendError(w, err) return } timeout, limit := parseTimeoutLimitParams(req) ch := TxLogger.Subscribe("txlogz") defer TxLogger.Unsubscribe(ch) logz.StartHTMLTable(w) defer logz.EndHTMLTable(w) w.Write(txlogzHeader) tmr := time.NewTimer(timeout) defer tmr.Stop() for i := 0; i < limit; i++ { select { case out := <-ch: txc, ok := out.(*TxConnection) if !ok { err := fmt.Errorf("Unexpected value in %s: %#v (expecting value of type %T)", TxLogger.Name(), out, &TxConnection{}) io.WriteString(w, `<tr class="error">`) io.WriteString(w, err.Error()) io.WriteString(w, "</tr>") log.Error(err) continue } duration := txc.EndTime.Sub(txc.StartTime).Seconds() var level string if duration < 0.1 { level = "low" } else if duration < 1.0 { level = "medium" } else { level = "high" } tmplData := struct { *TxConnection Duration float64 ColorLevel string }{txc, duration, level} if err := txlogzTmpl.Execute(w, tmplData); err != nil { log.Errorf("txlogz: couldn't execute template: %v", err) } case <-tmr.C: return } } }
func queryzHandler(si *SchemaInfo, w http.ResponseWriter, r *http.Request) { if err := acl.CheckAccessHTTP(r, acl.DEBUGGING); err != nil { acl.SendError(w, err) return } logz.StartHTMLTable(w) defer logz.EndHTMLTable(w) w.Write(queryzHeader) keys := si.queries.Keys() sorter := queryzSorter{ rows: make([]*queryzRow, 0, len(keys)), less: func(row1, row2 *queryzRow) bool { return row1.timePQ() > row2.timePQ() }, } for _, v := range si.queries.Keys() { plan := si.peekQuery(v) if plan == nil { continue } Value := &queryzRow{ Query: logz.Wrappable(v), Table: plan.TableName, Plan: plan.PlanID, Reason: plan.Reason, } Value.Count, Value.tm, Value.mysqlTime, Value.Rows, Value.Errors = plan.Stats() var timepq time.Duration if Value.Count != 0 { timepq = time.Duration(int64(Value.tm) / Value.Count) } if timepq < 10*time.Millisecond { Value.Color = "low" } else if timepq < 100*time.Millisecond { Value.Color = "medium" } else { Value.Color = "high" } sorter.rows = append(sorter.rows, Value) } sort.Sort(&sorter) for _, Value := range sorter.rows { if err := queryzTmpl.Execute(w, Value); err != nil { log.Errorf("queryz: couldn't execute template: %v", err) } } }