@@ -10,9 +10,13 @@ import (
1010// provided for testing
1111var osExit = os .Exit
1212
13+ type LogOutput interface {
14+ WriteLogLine ([]byte )
15+ }
16+
1317// OutputManager is used to sync data of Output
1418type OutputManager interface {
15- Append ([]byte , func ([] byte ) )
19+ Append ([]byte , LogOutput )
1620 Shutdown ()
1721}
1822
@@ -35,38 +39,66 @@ type sourceGroup struct {
3539 levelsSupported []Level
3640}
3741
42+ func (s * sourceGroup ) WriteLogLine (data []byte ) {
43+ _ , _ = s .writer .Write (data )
44+ }
45+
46+ func (s * sourceGroup ) supportsLevel (l Level ) bool {
47+ for _ , level := range s .levelsSupported {
48+ if l == level {
49+ return true
50+ }
51+ }
52+ return false
53+ }
54+
3855// OutputWriter is the standard logging implementation
3956type OutputWriter struct {
40- groups []sourceGroup
57+ groups []* sourceGroup
4158 syncWriter OutputManager
59+ minLevel Level
4260}
4361
4462// NewOutputWriter create a new logger
4563func NewOutputWriter (syncWriter OutputManager ) * OutputWriter {
4664 return & OutputWriter {
4765 syncWriter : syncWriter ,
48- groups : make ([]sourceGroup , 0 ),
66+ groups : nil ,
67+ minLevel : FatalLevel ,
4968 }
5069}
5170
5271// Add a writer and formatter to output to
5372func (s * OutputWriter ) Add (writer io.Writer , formatter Formatter , levels ... Level ) {
54- s .groups = append (s .groups , sourceGroup {writer : writer , formatter : formatter , levelsSupported : levels })
73+ s .groups = append (s .groups , & sourceGroup {writer : writer , formatter : formatter , levelsSupported : levels })
74+
75+ // track most verbose (lowest) level we need to output
76+ for _ , level := range levels {
77+ if level < s .minLevel {
78+ s .minLevel = level
79+ }
80+ }
5581}
5682
5783// Error writes an error to the logging sources
5884func (s * OutputWriter ) Error (message string ) {
59- s .output (ErrorLevel , message )
85+ if s .minLevel <= ErrorLevel {
86+ s .output (ErrorLevel , message )
87+ }
6088}
6189
6290// Info writes an info string to the logging sources
6391func (s * OutputWriter ) Info (message string ) {
64- s .output (InfoLevel , message )
92+ if s .minLevel <= InfoLevel {
93+ s .output (InfoLevel , message )
94+ }
6595}
6696
6797// Debug writes a debug string to the logging sources
6898func (s * OutputWriter ) Debug (message string ) {
69- s .output (DebugLevel , message )
99+ if s .minLevel <= DebugLevel {
100+ s .output (DebugLevel , message )
101+ }
70102}
71103
72104// Fatal writes a error string to the logging sources and runs does an os.exit()
@@ -78,17 +110,23 @@ func (s *OutputWriter) Fatal(message string) {
78110
79111// Errorf writes a formatted error to the logging sources
80112func (s * OutputWriter ) Errorf (format string , args ... interface {}) {
81- s .output (ErrorLevel , fmt .Sprintf (format , args ... ))
113+ if s .minLevel <= ErrorLevel {
114+ s .output (ErrorLevel , fmt .Sprintf (format , args ... ))
115+ }
82116}
83117
84118// Infof writes a formatted info statement to the logging sources
85119func (s * OutputWriter ) Infof (format string , args ... interface {}) {
86- s .output (InfoLevel , fmt .Sprintf (format , args ... ))
120+ if s .minLevel <= InfoLevel {
121+ s .output (InfoLevel , fmt .Sprintf (format , args ... ))
122+ }
87123}
88124
89125// Debugf writes a formatted debug statement to the logging sources
90126func (s * OutputWriter ) Debugf (format string , args ... interface {}) {
91- s .output (DebugLevel , fmt .Sprintf (format , args ... ))
127+ if s .minLevel <= DebugLevel {
128+ s .output (DebugLevel , fmt .Sprintf (format , args ... ))
129+ }
92130}
93131
94132// Fatalf writes a writes a formatted error statement and runs does an os.exit()
@@ -100,29 +138,14 @@ func (s *OutputWriter) Fatalf(format string, args ...interface{}) {
100138
101139// output does the actual write to the sync manager
102140func (s * OutputWriter ) output (l Level , content string ) {
141+ now := time .Now ()
103142 for _ , group := range s .groups {
104- if isSupported ( group , l ) {
105- logLine := fmt .Sprintf ("%s%s\n " , group .formatter .Timestamp (l , time . Now () ),
143+ if group . supportsLevel ( l ) {
144+ logLine := fmt .Sprintf ("%s%s\n " , group .formatter .Timestamp (l , now ),
106145 group .formatter .Content (l , content ))
107- s .append (group , []byte (logLine ))
108- }
109- }
110- }
111-
112- func (s * OutputWriter ) append (group sourceGroup , logLine []byte ) {
113- s .syncWriter .Append (logLine , func (b []byte ) {
114- group .writer .Write (b )
115- })
116- }
117-
118- // isSupported checks if the log level is supported
119- func isSupported (group sourceGroup , l Level ) bool {
120- for _ , level := range group .levelsSupported {
121- if l == level {
122- return true
146+ s .syncWriter .Append ([]byte (logLine ), group )
123147 }
124148 }
125- return false
126149}
127150
128151// Write implements io.Writer to support SetOutput of the log package
0 commit comments