Permalink
Browse files

first public commit

  • Loading branch information...
0 parents commit 498e4b5c49c4f10959996b2977bf1099f25910ef Scott White committed Jan 17, 2012
Showing with 1,140 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +8 −0 LICENSE.md
  3. +14 −0 Makefile
  4. +62 −0 README.md
  5. +33 −0 buffered_writer.go
  6. +20 −0 console_writer.go
  7. +38 −0 file_writer.go
  8. +216 −0 pattern_formatter.go
  9. +74 −0 pattern_formatter_test.go
  10. +39 −0 socket_writer.go
  11. +422 −0 timber.go
  12. +42 −0 timber.xml
  13. +47 −0 timber_test.go
  14. +122 −0 xml_config.go
@@ -0,0 +1,3 @@
+*.out
+_*
+*.log
@@ -0,0 +1,8 @@
+Copyright (c) 2012 ngmoco:) inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
@@ -0,0 +1,14 @@
+include $(GOROOT)/src/Make.inc
+
+TARG=timber
+GOFILES=\
+ timber.go\
+ pattern_formatter.go\
+ console_writer.go\
+ buffered_writer.go\
+ socket_writer.go\
+ file_writer.go\
+ xml_config.go\
+
+include $(GOROOT)/src/Make.pkg
+
@@ -0,0 +1,62 @@
+Timber!
+=======
+
+Timber is a logger for go with a similar interface as log4go and also can be used as a drop-in replacement for the go standard logger.
+
+Features
+--------
+* Log levels: Finest, Fine, Debug, Trace, Info, Warn, Error, Critical
+* External configuration via XML
+* Multiple log destinations (console, file, socket)
+* Configurable format per destination
+* Extensible and pluggable design (if you configure via code rather than XML)
+
+Motivation
+----------
+I like the log4go design with multiple configurable loggers, but it did not support adding formatters to all of the loggers (it is only supported for files). I thought about trying to contribute patches to log4go but some of the features I wanted would break complete backwards compatibility so I decided to do a rewrite from scratch.
+
+I try to expose everything possible that I think might be useful for someone to replace or extend.
+
+Usage
+-----
+The easiest way to use Timber is to use configure the built-in singleton:
+
+ import (
+ log "timber"
+ )
+
+ func main() {
+ // load xml config
+ log.LoadConfiguration("timber.xml")
+ log.Info("Timber!!!")
+ }
+
+An example timber.xml file is included in the package. Timber does implement the interface of the go log package so replacing the log with Timber will work ok.
+
+`log.Close()` should be called before your program exits to make sure all the buffers are drained and all messages are printed.
+
+
+Design
+------
+
+`Logger` is the interface that is used for logging itself with methods like Warn, Critical, Error, etc. All of these functions expect a Printf-like arguments and syntax for the message.
+
+`LogFormatter` is a generic interface for taking a `LogRecord` and formatting into a string to be logged. `PatFormatter` is the only included implementation of this interface.
+
+`LogWriter` interface wraps an underlying `Writer` but doesn't allow errors to propagate. There are implementations for writing to files, sockets and the console.
+
+`Timber` is a `MultiLogger` which just means that it implements the `Logger` interface but can log messages to multiple destinations. Each destination has a `LogWriter`, `level` and `LogFormatter`.
+
+`Global` is the default unconfigured instance of `Timber` which may be configured and used or, less commonly, replaced with your own instance (be sure to call `Global.Close()` before replacing for proper cleanup).
+
+Are you planning to wrap Timber in your own logger? Ever notice that if you wrap the go log package or log4go the source file that gets printed is always your wrapper? `Timber.FileDepth` sets how far up the stack to go to find the file you actually want. It's set to `DefaultFileDepth` so add your wrapper stack depth to that.
+
+Completeness
+------------
+* Some of the runtime configuration changes have not been implemented, such as `MultiLogger.SetLevel` and `MultiLogger.SetFormatter` which change the Level or `LogFormatter` on-the-fly. Loggers may be added at any time with `AddLogger` but there is no way to delete loggers right now.
+
+Compatibility
+-------------
+* I don't support the log4go special handling of the first parameter and probably never will. Right now, all of the `Logger` methods just expect a Printf-like syntax. If there is demand, I may get the proc syntax in for delayed evaluation.
+* `PatFormatter` format codes are not the same as log4go
+* `PatFormatter` always adds a newline at the end of the string so if there's already one there, then you'll get 2 so using Timber to replace the go log package may look a bit messy depending on how you formatted your logging.
@@ -0,0 +1,33 @@
+package timber
+
+import (
+ "bufio"
+ "io"
+ "log"
+)
+
+// Use this of you need some buffering, or not
+type BufferedWriter struct {
+ buf *bufio.Writer
+ writer io.WriteCloser
+}
+
+func NewBufferedWriter(writer io.WriteCloser) *BufferedWriter {
+ bw := new(BufferedWriter)
+ bw.writer = writer
+ bw.buf = bufio.NewWriter(writer)
+ return bw
+}
+
+func (bw *BufferedWriter) LogWrite(msg string) {
+ _, err := bw.buf.Write([]byte(msg))
+ if err != nil {
+ // uh-oh... what do i do if logging fails; punt!
+ log.Printf("TIMBER! epic fail: %v", err)
+ }
+}
+
+func (bw *BufferedWriter) Close() {
+ bw.buf.Flush()
+ bw.writer.Close()
+}
@@ -0,0 +1,20 @@
+package timber
+
+import (
+ "log"
+)
+
+func init() {
+ log.SetFlags(0)
+}
+
+// This uses the standard go logger to write the messages
+type ConsoleWriter func(string)
+
+func (c ConsoleWriter) LogWrite(msg string) {
+ log.Print(msg)
+}
+
+func (c ConsoleWriter) Close() {
+ // Nothing
+}
@@ -0,0 +1,38 @@
+package timber
+
+import (
+ "os"
+ "fmt"
+)
+/* unbuffered impl
+type FileWriter struct {
+ file io.WriteCloser
+}
+func NewFileWriter(name string) (*FileWriter) {
+ fw := new(FileWriter)
+ file, err := os.OpenFile(name, os.O_WRONLY | os.O_APPEND | os.O_CREATE, 0666)
+ if err != nil {
+ panic(fmt.Sprintf("TIMBER! Can't open: %v", name))
+ }
+ fw.file = file
+ return fw
+}
+
+func (fw *FileWriter) LogWrite(msg string) {
+ fw.file.Write([]byte(msg))
+}
+
+func (fw *FileWriter) Close() {
+ fw.file.Close()
+}
+*/
+
+// This writer has a buffer that I don't ever bother to flush, so it may take a while
+// to see messages
+func NewFileWriter(name string) LogWriter {
+ file, err := os.OpenFile(name, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
+ if err != nil {
+ panic(fmt.Sprintf("TIMBER! Can't open: %v", name))
+ }
+ return NewBufferedWriter(file)
+}
Oops, something went wrong.

0 comments on commit 498e4b5

Please sign in to comment.