mirror of https://github.com/statping/statping
Merge pull request #49 from oitimon/feature/extend-logs
commit
4189db804a
|
@ -79,7 +79,15 @@ func LogsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ExecuteResponse(w, r, "logs.html", nil)
|
utils.LockLines.Lock()
|
||||||
|
logs := make([]string, 0)
|
||||||
|
len := len(utils.LastLines)
|
||||||
|
// We need string log lines from end to start.
|
||||||
|
for i := len - 1; i >= 0; i-- {
|
||||||
|
logs = append(logs, utils.LastLines[i].FormatForHtml()+"\r\n")
|
||||||
|
}
|
||||||
|
utils.LockLines.Unlock()
|
||||||
|
ExecuteResponse(w, r, "logs.html", logs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func LogsLineHandler(w http.ResponseWriter, r *http.Request) {
|
func LogsLineHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -87,12 +95,7 @@ func LogsLineHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch v := utils.LastLine.(type) {
|
if lastLine := utils.GetLastLine(); lastLine != nil {
|
||||||
case string:
|
w.Write([]byte(lastLine.FormatForHtml()))
|
||||||
w.Write([]byte(v))
|
|
||||||
case error:
|
|
||||||
w.Write([]byte(v.Error()))
|
|
||||||
case []byte:
|
|
||||||
w.Write(v)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
|
||||||
<textarea id="live_logs" class="form-control" rows="40" readonly></textarea>
|
<textarea id="live_logs" class="form-control" rows="40" readonly>{{range .}}{{.}}{{end}}</textarea>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
34
utils/log.go
34
utils/log.go
|
@ -23,13 +23,15 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logFile *os.File
|
logFile *os.File
|
||||||
fmtLogs *log.Logger
|
fmtLogs *log.Logger
|
||||||
ljLogger *lumberjack.Logger
|
ljLogger *lumberjack.Logger
|
||||||
LastLine interface{}
|
LastLines []*LogRow
|
||||||
|
LockLines sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
func createLog(dir string) error {
|
func createLog(dir string) error {
|
||||||
|
@ -69,6 +71,7 @@ func InitLogs() error {
|
||||||
fmtLogs = log.New(logFile, "", log.Ldate|log.Ltime)
|
fmtLogs = log.New(logFile, "", log.Ldate|log.Ltime)
|
||||||
log.SetOutput(ljLogger)
|
log.SetOutput(ljLogger)
|
||||||
rotate()
|
rotate()
|
||||||
|
LastLines = make([]*LogRow, 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +87,7 @@ func rotate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Log(level int, err interface{}) error {
|
func Log(level int, err interface{}) error {
|
||||||
LastLine = err
|
pushLastLine(err)
|
||||||
var outErr error
|
var outErr error
|
||||||
switch level {
|
switch level {
|
||||||
case 5:
|
case 5:
|
||||||
|
@ -119,6 +122,25 @@ func Http(r *http.Request) string {
|
||||||
msg := fmt.Sprintf("%v (%v) | IP: %v", r.RequestURI, r.Method, r.Host)
|
msg := fmt.Sprintf("%v (%v) | IP: %v", r.RequestURI, r.Method, r.Host)
|
||||||
fmtLogs.Printf("WEB: %v\n", msg)
|
fmtLogs.Printf("WEB: %v\n", msg)
|
||||||
fmt.Printf("WEB: %v\n", msg)
|
fmt.Printf("WEB: %v\n", msg)
|
||||||
LastLine = msg
|
pushLastLine(msg)
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pushLastLine(line interface{}) {
|
||||||
|
LockLines.Lock()
|
||||||
|
defer LockLines.Unlock()
|
||||||
|
LastLines = append(LastLines, NewLogRow(line))
|
||||||
|
// We want to store max 1000 lines in memory (for /logs page).
|
||||||
|
for len(LastLines) > 1000 {
|
||||||
|
LastLines = LastLines[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetLastLine() *LogRow {
|
||||||
|
LockLines.Lock()
|
||||||
|
defer LockLines.Unlock()
|
||||||
|
if len(LastLines) > 0 {
|
||||||
|
return LastLines[len(LastLines) - 1]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Statup
|
||||||
|
// Copyright (C) 2018. Hunter Long and the project contributors
|
||||||
|
// Written by Hunter Long <info@socialeck.com> and the project contributors
|
||||||
|
//
|
||||||
|
// https://github.com/hunterlong/statup
|
||||||
|
//
|
||||||
|
// The licenses for most software and other practical works are designed
|
||||||
|
// to take away your freedom to share and change the works. By contrast,
|
||||||
|
// the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
// share and change all versions of a program--to make sure it remains free
|
||||||
|
// software for all its users.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LogRow struct {
|
||||||
|
Date time.Time
|
||||||
|
Line interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogRow(line interface{}) (logRow *LogRow) {
|
||||||
|
logRow = new(LogRow)
|
||||||
|
logRow.Date = time.Now()
|
||||||
|
logRow.Line = line
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *LogRow) LineAsString() string {
|
||||||
|
switch v := o.Line.(type) {
|
||||||
|
case string:
|
||||||
|
return v
|
||||||
|
case error:
|
||||||
|
return v.Error()
|
||||||
|
case []byte:
|
||||||
|
return string(v)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *LogRow) FormatForHtml() string {
|
||||||
|
return fmt.Sprintf("%s: %s", o.Date.Format("2006-01-02 15:04:05"), o.LineAsString())
|
||||||
|
}
|
Loading…
Reference in New Issue