func (herd *Herd) showReachableSubsHandler(w io.Writer, req *http.Request) { selector, err := herd.getReachableSelector(url.ParseQuery(req.URL)) if err != nil { fmt.Fprintln(w, err) return } herd.showSubs(w, "reachable ", selector) }
func (lb *LogBuffer) httpDumpHandler(w http.ResponseWriter, req *http.Request) { parsedQuery := url.ParseQuery(req.URL) name, ok := parsedQuery.Table["name"] if !ok { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusBadRequest) return } _, recentFirst := parsedQuery.Flags["recentFirst"] if name == "latest" { lbFilename := "" lb.rwMutex.Lock() if lb.file != nil { lbFilename = lb.file.Name() } lb.rwMutex.Unlock() if lbFilename == "" { writer := bufio.NewWriter(w) defer writer.Flush() lb.Dump(writer, "", "", recentFirst) return } name = path.Base(lbFilename) } file, err := os.Open(path.Join(lb.logDir, path.Base(path.Clean(name)))) if err != nil { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusNotFound) return } defer file.Close() writer := bufio.NewWriter(w) defer writer.Flush() if recentFirst { scanner := bufio.NewScanner(file) lines := make([]string, 0) for scanner.Scan() { line := scanner.Text() if len(line) < 1 { continue } lines = append(lines, line) } if err = scanner.Err(); err == nil { reverseStrings(lines) for _, line := range lines { fmt.Fprintln(writer, line) } } } else { _, err = io.Copy(writer, bufio.NewReader(file)) } if err != nil { fmt.Fprintln(writer, err) } }
func (lb *LogBuffer) httpShowLastHandler(w http.ResponseWriter, req *http.Request) { parsedQuery := url.ParseQuery(req.URL) _, recentFirst := parsedQuery.Flags["recentFirst"] for flag := range parsedQuery.Flags { length := len(flag) if length < 2 { continue } unitChar := flag[length-1] var unit time.Duration switch unitChar { case 's': unit = time.Second case 'm': unit = time.Minute case 'h': unit = time.Hour case 'd': unit = time.Hour * 24 case 'w': unit = time.Hour * 24 * 7 default: continue } if val, err := strconv.ParseUint(flag[:length-1], 10, 64); err != nil { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusBadRequest) return } else { lb.showRecent(w, time.Duration(val)*unit, recentFirst) return } } w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusBadRequest) }
func (lb *LogBuffer) httpListHandler(w http.ResponseWriter, req *http.Request) { if lb.logDir == "" { return } writer := bufio.NewWriter(w) defer writer.Flush() parsedQuery := url.ParseQuery(req.URL) _, recentFirst := parsedQuery.Flags["recentFirst"] names, panicMap, err := lb.list(recentFirst) if err != nil { fmt.Fprintln(writer, err) return } recentFirstString := "" if recentFirst { recentFirstString = "&recentFirst" } if parsedQuery.OutputType() == url.OutputTypeText { for _, name := range names { fmt.Fprintln(writer, name) } return } fmt.Fprintln(writer, "<body>") fmt.Fprint(writer, "Logs: ") if recentFirst { fmt.Fprintf(writer, "showing recent first ") fmt.Fprintln(writer, `<a href="logs">show recent last</a><br>`) } else { fmt.Fprintf(writer, "showing recent last ") fmt.Fprintln(writer, `<a href="logs?recentFirst">show recent first</a><br>`) } showRecentLinks(writer, recentFirstString) fmt.Fprintln(writer, "<p>") currentName := "" lb.rwMutex.Lock() if lb.file != nil { currentName = path.Base(lb.file.Name()) } lb.rwMutex.Unlock() if recentFirst { fmt.Fprintf(writer, "<a href=\"logs/dump?name=latest%s\">current</a><br>\n", recentFirstString) } for _, name := range names { if name == currentName { fmt.Fprintf(writer, "<a href=\"logs/dump?name=%s%s\">%s</a> (current)<br>\n", name, recentFirstString, name) } else { hasPanic := "" if _, ok := panicMap[name]; ok { hasPanic = " (has panic log)" } fmt.Fprintf(writer, "<a href=\"logs/dump?name=%s%s\">%s</a>%s<br>\n", name, recentFirstString, name, hasPanic) } } if !recentFirst { fmt.Fprintf(writer, "<a href=\"logs/dump?name=latest%s\">current</a><br>\n", recentFirstString) } fmt.Fprintln(writer, "</body>") }