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)
|
||||
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) {
|
||||
|
@ -87,12 +95,7 @@ func LogsLineHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
switch v := utils.LastLine.(type) {
|
||||
case string:
|
||||
w.Write([]byte(v))
|
||||
case error:
|
||||
w.Write([]byte(v.Error()))
|
||||
case []byte:
|
||||
w.Write(v)
|
||||
if lastLine := utils.GetLastLine(); lastLine != nil {
|
||||
w.Write([]byte(lastLine.FormatForHtml()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<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>
|
||||
|
||||
|
|
34
utils/log.go
34
utils/log.go
|
@ -23,13 +23,15 @@ import (
|
|||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
logFile *os.File
|
||||
fmtLogs *log.Logger
|
||||
ljLogger *lumberjack.Logger
|
||||
LastLine interface{}
|
||||
logFile *os.File
|
||||
fmtLogs *log.Logger
|
||||
ljLogger *lumberjack.Logger
|
||||
LastLines []*LogRow
|
||||
LockLines sync.Mutex
|
||||
)
|
||||
|
||||
func createLog(dir string) error {
|
||||
|
@ -69,6 +71,7 @@ func InitLogs() error {
|
|||
fmtLogs = log.New(logFile, "", log.Ldate|log.Ltime)
|
||||
log.SetOutput(ljLogger)
|
||||
rotate()
|
||||
LastLines = make([]*LogRow, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -84,7 +87,7 @@ func rotate() {
|
|||
}
|
||||
|
||||
func Log(level int, err interface{}) error {
|
||||
LastLine = err
|
||||
pushLastLine(err)
|
||||
var outErr error
|
||||
switch level {
|
||||
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)
|
||||
fmtLogs.Printf("WEB: %v\n", msg)
|
||||
fmt.Printf("WEB: %v\n", msg)
|
||||
LastLine = msg
|
||||
pushLastLine(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