new: added log rotation (closes #374)

This commit is contained in:
evilsocket 2018-10-28 12:43:38 +01:00
commit fc7d8d22b4
No known key found for this signature in database
GPG key ID: 1564D7F30393A456
5 changed files with 161 additions and 7 deletions

View file

@ -4,6 +4,7 @@ import (
"fmt"
"os"
"strconv"
"sync"
"time"
"github.com/bettercap/bettercap/log"
@ -14,9 +15,20 @@ import (
"github.com/evilsocket/islazy/tui"
)
type rotation struct {
sync.Mutex
Enabled bool
Compress bool
Format string
How string
Period int
}
type EventsStream struct {
session.SessionModule
outputName string
output *os.File
rotation rotation
ignoreList *IgnoreList
waitFor string
waitChan chan *session.Event
@ -117,6 +129,28 @@ func NewEventsStream(s *session.Session) *EventsStream {
"",
"If not empty, events will be written to this file instead of the standard output."))
stream.AddParam(session.NewBoolParameter("events.stream.output.rotate",
"true",
"If true will enable log rotation."))
stream.AddParam(session.NewBoolParameter("events.stream.output.rotate.compress",
"true",
"If true will enable log rotation compression."))
stream.AddParam(session.NewStringParameter("events.stream.output.rotate.how",
"size",
"(size|time)",
"Rotate by 'size' or 'time'."))
stream.AddParam(session.NewStringParameter("events.stream.output.rotate.format",
"2006-01-02 15:04:05",
"",
"Datetime format to use for log rotation file names."))
stream.AddParam(session.NewIntParameter("events.stream.output.rotate.when",
"10485760",
"File size or time duration in seconds for log rotation."))
stream.AddParam(session.NewBoolParameter("events.stream.http.request.dump",
"false",
"If true all HTTP requests will be dumped."))
@ -146,10 +180,24 @@ func (s *EventsStream) Configure() (err error) {
if err, output = s.StringParam("events.stream.output"); err == nil {
if output == "" {
s.output = os.Stdout
} else if output, err = fs.Expand(output); err == nil {
s.output, err = os.OpenFile(output, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
} else if s.outputName, err = fs.Expand(output); err == nil {
s.output, err = os.OpenFile(s.outputName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
}
} else if err, s.dumpHttpReqs = s.BoolParam("events.stream.http.request.dump"); err != nil {
}
if err, s.rotation.Enabled = s.BoolParam("events.stream.output.rotate"); err != nil {
return err
} else if err, s.rotation.Compress = s.BoolParam("events.stream.output.rotate.compress"); err != nil {
return err
} else if err, s.rotation.Format = s.StringParam("events.stream.output.rotate.format"); err != nil {
return err
} else if err, s.rotation.How = s.StringParam("events.stream.output.rotate.how"); err != nil {
return err
} else if err, s.rotation.Period = s.IntParam("events.stream.output.rotate.when"); err != nil {
return err
}
if err, s.dumpHttpReqs = s.BoolParam("events.stream.http.request.dump"); err != nil {
return err
} else if err, s.dumpHttpResp = s.BoolParam("events.stream.http.response.dump"); err != nil {
return err

View file

@ -4,6 +4,7 @@ import (
"fmt"
"os"
"strings"
"time"
"github.com/bettercap/bettercap/network"
"github.com/bettercap/bettercap/session"
@ -11,6 +12,7 @@ import (
"github.com/google/go-github/github"
"github.com/evilsocket/islazy/tui"
"github.com/evilsocket/islazy/zip"
)
const eventTimeFormat = "15:04:05"
@ -152,6 +154,53 @@ func (s *EventsStream) viewUpdateEvent(e session.Event) {
*update.HTMLURL)
}
func (s *EventsStream) doRotation() {
if s.output == os.Stdout {
return
} else if !s.rotation.Enabled {
return
}
s.rotation.Lock()
defer s.rotation.Unlock()
doRotate := false
if info, err := s.output.Stat(); err == nil {
if s.rotation.How == "size" {
doRotate = info.Size() >= int64(s.rotation.Period)
} else if s.rotation.How == "time" {
doRotate = info.ModTime().Unix()%int64(s.rotation.Period) == 0
}
}
if doRotate {
var err error
name := fmt.Sprintf("%s-%s", s.outputName, time.Now().Format(s.rotation.Format))
if err := s.output.Close(); err != nil {
fmt.Printf("could not close log for rotation: %s\n", err)
return
}
if err := os.Rename(s.outputName, name); err != nil {
fmt.Printf("could not rename %s to %s: %s\n", s.outputName, name, err)
} else if s.rotation.Compress {
zipName := fmt.Sprintf("%s.zip", name)
if err = zip.Files(zipName, []string{name}); err != nil {
fmt.Printf("error creating %s: %s", zipName, err)
} else if err = os.Remove(name); err != nil {
fmt.Printf("error deleting %s: %s", name, err)
}
}
s.output, err = os.OpenFile(s.outputName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Printf("could not open %s: %s", s.outputName, err)
}
}
}
func (s *EventsStream) View(e session.Event, refresh bool) {
if e.Tag == "sys.log" {
s.viewLogEvent(e)
@ -176,4 +225,6 @@ func (s *EventsStream) View(e session.Event, refresh bool) {
if refresh && s.output == os.Stdout {
s.Session.Refresh()
}
s.doRotation()
}