httptail/main.go

106 lines
2.4 KiB
Go
Raw Permalink Normal View History

2017-10-02 10:43:44 +00:00
package main
import (
2017-10-02 10:54:27 +00:00
"container/ring"
"fmt"
"github.com/hpcloud/tail"
"encoding/json"
"net/http"
"os"
"regexp"
"strconv"
"strings"
"time"
2017-10-02 10:43:44 +00:00
)
func fileHandler(w http.ResponseWriter, r *http.Request, s string) {
fn := r.URL.Path[5:len(r.URL.Path)]
for _, v := range whitelist {
if !strings.Contains(v, fn) {
sendFile(w, fn, "", "Permission denied")
2017-10-02 10:54:27 +00:00
return
2017-10-02 10:43:44 +00:00
}
}
if _, err := os.Stat(fn); err != nil {
sendFile(w, fn, "", "No such file or directory")
return
}
2017-10-02 13:51:31 +00:00
fmt.Println("watch: %#v", watch)
2017-10-02 10:43:44 +00:00
if (watch == false) {
2017-10-02 13:51:31 +00:00
t, err := tail.TailFile(fn, tail.Config{Follow: false, MustExist: true})
watch = true
if (err == nil) {
fmt.Println(err)
}
2017-10-02 10:43:44 +00:00
}
var m = ""
w.WriteHeader(http.StatusOK)
for line := range t.Lines {
m += fmt.Sprintf("%s\n", line.Text)
logring.Value = line.Text
logring = logring.Next()
}
if m != m_prev {
sendFile(w, fn, m, "")
m_prev = m
}
}
func sendFile(w http.ResponseWriter, fn string, m string, err string) {
2017-10-02 13:51:31 +00:00
json.NewEncoder(w).Encode(map[string]string{"time": strconv.FormatInt(getMsTimestamp(), 16), "Filename": fn, "Text": m, "error": err})
2017-10-02 10:43:44 +00:00
}
2017-10-02 13:51:31 +00:00
func getMsTimestamp() (int64) {
2017-10-02 10:43:44 +00:00
now := time.Now()
ns := now.UnixNano()
ms := ns / 1000000
return ms
}
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
m := validPath.FindStringSubmatch(r.URL.Path)
if m == nil {
http.NotFound(w, r)
return
}
fmt.Println("makeHandler::request::" + r.RequestURI)
fn(w, r, m[2])
}
}
var prj = "httptail"
var version = "0.1.0"
var server_inet6 = "[fdef:c181:4234:7978:6::1]:8080"
var whitelist = map[int]string{
2017-10-02 10:54:27 +00:00
0: "/var/log",
2017-10-02 10:43:44 +00:00
}
var logring = ring.New(1000)
var validPath = regexp.MustCompile("^/(tail*|auth)/(.*)$")
var watch bool = false
var m_prev = ""
func main() {
2017-10-02 10:54:27 +00:00
uid := os.Getuid()
2017-10-02 10:43:44 +00:00
2017-10-02 10:54:27 +00:00
if (uid == -1) {
fmt.Println("Windows is unsupported")
2017-10-02 10:43:44 +00:00
}
2017-10-02 10:54:27 +00:00
if (uid == 0) {
2017-10-02 10:43:44 +00:00
fmt.Println("Refusing to run as root")
2017-10-02 10:54:27 +00:00
return
}
2017-10-02 10:43:44 +00:00
2017-10-02 10:54:27 +00:00
http.HandleFunc("/tail/", makeHandler(fileHandler))
2017-10-02 10:43:44 +00:00
2017-10-02 13:51:31 +00:00
fmt.Println("Serving " + prj + " " + version + " on " + server_inet6)
http.ListenAndServe(server_inet6, nil)
//t.Cleanup()
2017-10-02 10:43:44 +00:00
}