forked from lug/matterbridge
		
	
		
			
				
	
	
		
			127 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (C) 2010, Kyle Lemons <kyle@kylelemons.net>.  All rights reserved.
 | |
| 
 | |
| package log4go
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	FORMAT_DEFAULT = "[%D %T] [%L] (%S) %M"
 | |
| 	FORMAT_SHORT   = "[%t %d] [%L] %M"
 | |
| 	FORMAT_ABBREV  = "[%L] %M"
 | |
| )
 | |
| 
 | |
| type formatCacheType struct {
 | |
| 	LastUpdateSeconds    int64
 | |
| 	shortTime, shortDate string
 | |
| 	longTime, longDate   string
 | |
| }
 | |
| 
 | |
| var formatCache = &formatCacheType{}
 | |
| 
 | |
| // Known format codes:
 | |
| // %T - Time (15:04:05 MST)
 | |
| // %t - Time (15:04)
 | |
| // %D - Date (2006/01/02)
 | |
| // %d - Date (01/02/06)
 | |
| // %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT)
 | |
| // %S - Source
 | |
| // %M - Message
 | |
| // Ignores unknown formats
 | |
| // Recommended: "[%D %T] [%L] (%S) %M"
 | |
| func FormatLogRecord(format string, rec *LogRecord) string {
 | |
| 	if rec == nil {
 | |
| 		return "<nil>"
 | |
| 	}
 | |
| 	if len(format) == 0 {
 | |
| 		return ""
 | |
| 	}
 | |
| 
 | |
| 	out := bytes.NewBuffer(make([]byte, 0, 64))
 | |
| 	secs := rec.Created.UnixNano() / 1e9
 | |
| 
 | |
| 	cache := *formatCache
 | |
| 	if cache.LastUpdateSeconds != secs {
 | |
| 		month, day, year := rec.Created.Month(), rec.Created.Day(), rec.Created.Year()
 | |
| 		hour, minute, second := rec.Created.Hour(), rec.Created.Minute(), rec.Created.Second()
 | |
| 		zone, _ := rec.Created.Zone()
 | |
| 		updated := &formatCacheType{
 | |
| 			LastUpdateSeconds: secs,
 | |
| 			shortTime:         fmt.Sprintf("%02d:%02d", hour, minute),
 | |
| 			shortDate:         fmt.Sprintf("%02d/%02d/%02d", day, month, year%100),
 | |
| 			longTime:          fmt.Sprintf("%02d:%02d:%02d %s", hour, minute, second, zone),
 | |
| 			longDate:          fmt.Sprintf("%04d/%02d/%02d", year, month, day),
 | |
| 		}
 | |
| 		cache = *updated
 | |
| 		formatCache = updated
 | |
| 	}
 | |
| 
 | |
| 	// Split the string into pieces by % signs
 | |
| 	pieces := bytes.Split([]byte(format), []byte{'%'})
 | |
| 
 | |
| 	// Iterate over the pieces, replacing known formats
 | |
| 	for i, piece := range pieces {
 | |
| 		if i > 0 && len(piece) > 0 {
 | |
| 			switch piece[0] {
 | |
| 			case 'T':
 | |
| 				out.WriteString(cache.longTime)
 | |
| 			case 't':
 | |
| 				out.WriteString(cache.shortTime)
 | |
| 			case 'D':
 | |
| 				out.WriteString(cache.longDate)
 | |
| 			case 'd':
 | |
| 				out.WriteString(cache.shortDate)
 | |
| 			case 'L':
 | |
| 				out.WriteString(levelStrings[rec.Level])
 | |
| 			case 'S':
 | |
| 				out.WriteString(rec.Source)
 | |
| 			case 's':
 | |
| 				slice := strings.Split(rec.Source, "/")
 | |
| 				out.WriteString(slice[len(slice)-1])
 | |
| 			case 'M':
 | |
| 				out.WriteString(rec.Message)
 | |
| 			}
 | |
| 			if len(piece) > 1 {
 | |
| 				out.Write(piece[1:])
 | |
| 			}
 | |
| 		} else if len(piece) > 0 {
 | |
| 			out.Write(piece)
 | |
| 		}
 | |
| 	}
 | |
| 	out.WriteByte('\n')
 | |
| 
 | |
| 	return out.String()
 | |
| }
 | |
| 
 | |
| // This is the standard writer that prints to standard output.
 | |
| type FormatLogWriter chan *LogRecord
 | |
| 
 | |
| // This creates a new FormatLogWriter
 | |
| func NewFormatLogWriter(out io.Writer, format string) FormatLogWriter {
 | |
| 	records := make(FormatLogWriter, LogBufferLength)
 | |
| 	go records.run(out, format)
 | |
| 	return records
 | |
| }
 | |
| 
 | |
| func (w FormatLogWriter) run(out io.Writer, format string) {
 | |
| 	for rec := range w {
 | |
| 		fmt.Fprint(out, FormatLogRecord(format, rec))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // This is the FormatLogWriter's output method.  This will block if the output
 | |
| // buffer is full.
 | |
| func (w FormatLogWriter) LogWrite(rec *LogRecord) {
 | |
| 	w <- rec
 | |
| }
 | |
| 
 | |
| // Close stops the logger from sending messages to standard output.  Attempts to
 | |
| // send log messages to this logger after a Close have undefined behavior.
 | |
| func (w FormatLogWriter) Close() {
 | |
| 	close(w)
 | |
| }
 | 
