summaryrefslogtreecommitdiffstats
path: root/modules/log
diff options
context:
space:
mode:
Diffstat (limited to 'modules/log')
-rw-r--r--modules/log/conn.go12
-rw-r--r--modules/log/console.go14
-rw-r--r--modules/log/event.go64
-rw-r--r--modules/log/file.go13
-rw-r--r--modules/log/log.go37
-rw-r--r--modules/log/smtp.go5
6 files changed, 144 insertions, 1 deletions
diff --git a/modules/log/conn.go b/modules/log/conn.go
index 8816664526..1abe44c1d4 100644
--- a/modules/log/conn.go
+++ b/modules/log/conn.go
@@ -77,6 +77,13 @@ func (i *connWriter) connect() error {
return nil
}
+func (i *connWriter) releaseReopen() error {
+ if i.innerWriter != nil {
+ return i.connect()
+ }
+ return nil
+}
+
// ConnLogger implements LoggerProvider.
// it writes messages in keep-live tcp connection.
type ConnLogger struct {
@@ -119,6 +126,11 @@ func (log *ConnLogger) GetName() string {
return "conn"
}
+// ReleaseReopen causes the ConnLogger to reconnect to the server
+func (log *ConnLogger) ReleaseReopen() error {
+ return log.out.(*connWriter).releaseReopen()
+}
+
func init() {
Register("conn", NewConn)
}
diff --git a/modules/log/console.go b/modules/log/console.go
index 6cfca8a733..a805021f0b 100644
--- a/modules/log/console.go
+++ b/modules/log/console.go
@@ -68,6 +68,20 @@ func (log *ConsoleLogger) Init(config string) error {
func (log *ConsoleLogger) Flush() {
}
+// ReleaseReopen causes the console logger to reconnect to os.Stdout
+func (log *ConsoleLogger) ReleaseReopen() error {
+ if log.Stderr {
+ log.NewWriterLogger(&nopWriteCloser{
+ w: os.Stderr,
+ })
+ } else {
+ log.NewWriterLogger(&nopWriteCloser{
+ w: os.Stdout,
+ })
+ }
+ return nil
+}
+
// GetName returns the default name for this implementation
func (log *ConsoleLogger) GetName() string {
return "console"
diff --git a/modules/log/event.go b/modules/log/event.go
index 37efa3c230..6975bf749d 100644
--- a/modules/log/event.go
+++ b/modules/log/event.go
@@ -29,6 +29,7 @@ type EventLogger interface {
GetLevel() Level
GetStacktraceLevel() Level
GetName() string
+ ReleaseReopen() error
}
// ChannelledLog represents a cached channel to a LoggerProvider
@@ -117,6 +118,11 @@ func (l *ChannelledLog) Flush() {
l.flush <- true
}
+// ReleaseReopen this ChannelledLog
+func (l *ChannelledLog) ReleaseReopen() error {
+ return l.loggerProvider.ReleaseReopen()
+}
+
// GetLevel gets the level of this ChannelledLog
func (l *ChannelledLog) GetLevel() Level {
return l.loggerProvider.GetLevel()
@@ -145,6 +151,7 @@ type MultiChannelledLog struct {
level Level
stacktraceLevel Level
closed chan bool
+ paused chan bool
}
// NewMultiChannelledLog a new logger instance with given logger provider and config.
@@ -159,6 +166,7 @@ func NewMultiChannelledLog(name string, bufferLength int64) *MultiChannelledLog
stacktraceLevel: NONE,
close: make(chan bool),
closed: make(chan bool),
+ paused: make(chan bool),
}
return m
}
@@ -229,6 +237,33 @@ func (m *MultiChannelledLog) closeLoggers() {
m.closed <- true
}
+// Pause pauses this Logger
+func (m *MultiChannelledLog) Pause() {
+ m.paused <- true
+}
+
+// Resume resumes this Logger
+func (m *MultiChannelledLog) Resume() {
+ m.paused <- false
+}
+
+// ReleaseReopen causes this logger to tell its subloggers to release and reopen
+func (m *MultiChannelledLog) ReleaseReopen() error {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ var accumulatedErr error
+ for _, logger := range m.loggers {
+ if err := logger.ReleaseReopen(); err != nil {
+ if accumulatedErr == nil {
+ accumulatedErr = fmt.Errorf("Error whilst reopening: %s Error: %v", logger.GetName(), err)
+ } else {
+ accumulatedErr = fmt.Errorf("Error whilst reopening: %s Error: %v & %v", logger.GetName(), err, accumulatedErr)
+ }
+ }
+ }
+ return accumulatedErr
+}
+
// Start processing the MultiChannelledLog
func (m *MultiChannelledLog) Start() {
m.mutex.Lock()
@@ -238,8 +273,35 @@ func (m *MultiChannelledLog) Start() {
}
m.started = true
m.mutex.Unlock()
+ paused := false
for {
+ if paused {
+ select {
+ case paused = <-m.paused:
+ if !paused {
+ m.ResetLevel()
+ }
+ case _, ok := <-m.flush:
+ if !ok {
+ m.closeLoggers()
+ return
+ }
+ m.mutex.Lock()
+ for _, logger := range m.loggers {
+ logger.Flush()
+ }
+ m.mutex.Unlock()
+ case <-m.close:
+ m.closeLoggers()
+ return
+ }
+ continue
+ }
select {
+ case paused = <-m.paused:
+ if paused && m.level < INFO {
+ m.level = INFO
+ }
case event, ok := <-m.queue:
if !ok {
m.closeLoggers()
@@ -275,7 +337,7 @@ func (m *MultiChannelledLog) LogEvent(event *Event) error {
select {
case m.queue <- event:
return nil
- case <-time.After(60 * time.Second):
+ case <-time.After(100 * time.Millisecond):
// We're blocked!
return ErrTimeout{
Name: m.name,
diff --git a/modules/log/file.go b/modules/log/file.go
index 877820b8be..925d83f2b7 100644
--- a/modules/log/file.go
+++ b/modules/log/file.go
@@ -249,6 +249,19 @@ func (log *FileLogger) Flush() {
_ = log.mw.fd.Sync()
}
+// ReleaseReopen releases and reopens log files
+func (log *FileLogger) ReleaseReopen() error {
+ closingErr := log.mw.fd.Close()
+ startingErr := log.StartLogger()
+ if startingErr != nil {
+ if closingErr != nil {
+ return fmt.Errorf("Error during closing: %v Error during starting: %v", closingErr, startingErr)
+ }
+ return startingErr
+ }
+ return closingErr
+}
+
// GetName returns the default name for this implementation
func (log *FileLogger) GetName() string {
return "file"
diff --git a/modules/log/log.go b/modules/log/log.go
index 71e88491f1..2a35b5752c 100644
--- a/modules/log/log.go
+++ b/modules/log/log.go
@@ -5,6 +5,7 @@
package log
import (
+ "fmt"
"os"
"runtime"
"strings"
@@ -192,6 +193,42 @@ func IsFatal() bool {
return GetLevel() <= FATAL
}
+// Pause pauses all the loggers
+func Pause() {
+ NamedLoggers.Range(func(key, value interface{}) bool {
+ logger := value.(*Logger)
+ logger.Pause()
+ logger.Flush()
+ return true
+ })
+}
+
+// Resume resumes all the loggers
+func Resume() {
+ NamedLoggers.Range(func(key, value interface{}) bool {
+ logger := value.(*Logger)
+ logger.Resume()
+ return true
+ })
+}
+
+// ReleaseReopen releases and reopens logging files
+func ReleaseReopen() error {
+ var accumulatedErr error
+ NamedLoggers.Range(func(key, value interface{}) bool {
+ logger := value.(*Logger)
+ if err := logger.ReleaseReopen(); err != nil {
+ if accumulatedErr == nil {
+ accumulatedErr = fmt.Errorf("Error reopening %s: %v", key.(string), err)
+ } else {
+ accumulatedErr = fmt.Errorf("Error reopening %s: %v & %v", key.(string), err, accumulatedErr)
+ }
+ }
+ return true
+ })
+ return accumulatedErr
+}
+
// Close closes all the loggers
func Close() {
l, ok := NamedLoggers.Load(DEFAULT)
diff --git a/modules/log/smtp.go b/modules/log/smtp.go
index f912299a73..edf4943619 100644
--- a/modules/log/smtp.go
+++ b/modules/log/smtp.go
@@ -97,6 +97,11 @@ func (log *SMTPLogger) sendMail(p []byte) (int, error) {
func (log *SMTPLogger) Flush() {
}
+// ReleaseReopen does nothing
+func (log *SMTPLogger) ReleaseReopen() error {
+ return nil
+}
+
// GetName returns the default name for this implementation
func (log *SMTPLogger) GetName() string {
return "smtp"