aboutsummaryrefslogtreecommitdiffstats
path: root/logger/sys.go
diff options
context:
space:
mode:
authorTaylor Gerring <taylor.gerring@gmail.com>2015-01-22 00:04:11 +0800
committerTaylor Gerring <taylor.gerring@gmail.com>2015-01-22 00:04:11 +0800
commit7f9c3354872e6fcc63c37abddb184e3e58790bc3 (patch)
tree98721ba3e202456503d9cffc7d0985c9ef35d215 /logger/sys.go
parent87f50659db7a4bf194769b05f541d2ccf02f4fc8 (diff)
downloaddexon-7f9c3354872e6fcc63c37abddb184e3e58790bc3.tar
dexon-7f9c3354872e6fcc63c37abddb184e3e58790bc3.tar.gz
dexon-7f9c3354872e6fcc63c37abddb184e3e58790bc3.tar.bz2
dexon-7f9c3354872e6fcc63c37abddb184e3e58790bc3.tar.lz
dexon-7f9c3354872e6fcc63c37abddb184e3e58790bc3.tar.xz
dexon-7f9c3354872e6fcc63c37abddb184e3e58790bc3.tar.zst
dexon-7f9c3354872e6fcc63c37abddb184e3e58790bc3.zip
Split into multiple files
Diffstat (limited to 'logger/sys.go')
-rw-r--r--logger/sys.go99
1 files changed, 99 insertions, 0 deletions
diff --git a/logger/sys.go b/logger/sys.go
new file mode 100644
index 000000000..5b48241c2
--- /dev/null
+++ b/logger/sys.go
@@ -0,0 +1,99 @@
+package logger
+
+import (
+ "sync"
+)
+
+var (
+ logMessageC = make(chan message)
+ addSystemC = make(chan LogSystem)
+ flushC = make(chan chan struct{})
+ resetC = make(chan chan struct{})
+)
+
+func init() {
+ go dispatchLoop()
+}
+
+// each system can buffer this many messages before
+// blocking incoming log messages.
+const sysBufferSize = 500
+
+func dispatchLoop() {
+ var (
+ systems []LogSystem
+ systemIn []chan message
+ systemWG sync.WaitGroup
+ )
+ bootSystem := func(sys LogSystem) {
+ in := make(chan message, sysBufferSize)
+ systemIn = append(systemIn, in)
+ systemWG.Add(1)
+ go sysLoop(sys, in, &systemWG)
+ }
+
+ for {
+ select {
+ case msg := <-logMessageC:
+ for _, c := range systemIn {
+ c <- msg
+ }
+
+ case sys := <-addSystemC:
+ systems = append(systems, sys)
+ bootSystem(sys)
+
+ case waiter := <-resetC:
+ // reset means terminate all systems
+ for _, c := range systemIn {
+ close(c)
+ }
+ systems = nil
+ systemIn = nil
+ systemWG.Wait()
+ close(waiter)
+
+ case waiter := <-flushC:
+ // flush means reboot all systems
+ for _, c := range systemIn {
+ close(c)
+ }
+ systemIn = nil
+ systemWG.Wait()
+ for _, sys := range systems {
+ bootSystem(sys)
+ }
+ close(waiter)
+ }
+ }
+}
+
+func sysLoop(sys LogSystem, in <-chan message, wg *sync.WaitGroup) {
+ for msg := range in {
+ if sys.GetLogLevel() >= msg.level {
+ sys.LogPrint(msg.level, msg.msg)
+ }
+ }
+ wg.Done()
+}
+
+// Reset removes all active log systems.
+// It blocks until all current messages have been delivered.
+func Reset() {
+ waiter := make(chan struct{})
+ resetC <- waiter
+ <-waiter
+}
+
+// Flush waits until all current log messages have been dispatched to
+// the active log systems.
+func Flush() {
+ waiter := make(chan struct{})
+ flushC <- waiter
+ <-waiter
+}
+
+// AddLogSystem starts printing messages to the given LogSystem.
+func AddLogSystem(sys LogSystem) {
+ addSystemC <- sys
+}