123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package log
- import (
- "bytes"
- "fmt"
- "io"
- "path"
- "runtime"
- "strings"
- "sync"
- "time"
- )
- var patternMap = map[string]func(map[string]interface{}) string{
- "T": longTime,
- "t": shortTime,
- "D": longDate,
- "d": shortDate,
- "L": keyFactory(_level),
- "f": keyFactory(_source),
- "i": keyFactory(_instanceID),
- "e": keyFactory(_deplyEnv),
- "z": keyFactory(_zone),
- "S": longSource,
- "s": shortSource,
- "M": message,
- }
- // newPatternRender new pattern render
- func newPatternRender(format string) Render {
- p := &pattern{
- bufPool: sync.Pool{New: func() interface{} { return &bytes.Buffer{} }},
- }
- b := make([]byte, 0, len(format))
- for i := 0; i < len(format); i++ {
- if format[i] != '%' {
- b = append(b, format[i])
- continue
- }
- if i+1 >= len(format) {
- b = append(b, format[i])
- continue
- }
- f, ok := patternMap[string(format[i+1])]
- if !ok {
- b = append(b, format[i])
- continue
- }
- if len(b) != 0 {
- p.funcs = append(p.funcs, textFactory(string(b)))
- b = b[:0]
- }
- p.funcs = append(p.funcs, f)
- i++
- }
- if len(b) != 0 {
- p.funcs = append(p.funcs, textFactory(string(b)))
- }
- return p
- }
- type pattern struct {
- funcs []func(map[string]interface{}) string
- bufPool sync.Pool
- }
- // Render implemet Formater
- func (p *pattern) Render(w io.Writer, d map[string]interface{}) error {
- buf := p.bufPool.Get().(*bytes.Buffer)
- defer func() {
- buf.Reset()
- p.bufPool.Put(buf)
- }()
- for _, f := range p.funcs {
- buf.WriteString(f(d))
- }
- _, err := buf.WriteTo(w)
- return err
- }
- // Render implemet Formater as string
- func (p *pattern) RenderString(d map[string]interface{}) string {
- // TODO strings.Builder
- buf := p.bufPool.Get().(*bytes.Buffer)
- defer func() {
- buf.Reset()
- p.bufPool.Put(buf)
- }()
- for _, f := range p.funcs {
- buf.WriteString(f(d))
- }
- return buf.String()
- }
- func textFactory(text string) func(map[string]interface{}) string {
- return func(map[string]interface{}) string {
- return text
- }
- }
- func keyFactory(key string) func(map[string]interface{}) string {
- return func(d map[string]interface{}) string {
- if v, ok := d[key]; ok {
- if s, ok := v.(string); ok {
- return s
- }
- return fmt.Sprint(v)
- }
- return ""
- }
- }
- func longSource(map[string]interface{}) string {
- if _, file, lineNo, ok := runtime.Caller(6); ok {
- return fmt.Sprintf("%s:%d", file, lineNo)
- }
- return "unknown:0"
- }
- func shortSource(map[string]interface{}) string {
- if _, file, lineNo, ok := runtime.Caller(6); ok {
- return fmt.Sprintf("%s:%d", path.Base(file), lineNo)
- }
- return "unknown:0"
- }
- func longTime(map[string]interface{}) string {
- return time.Now().Format("15:04:05.000")
- }
- func shortTime(map[string]interface{}) string {
- return time.Now().Format("15:04")
- }
- func longDate(map[string]interface{}) string {
- return time.Now().Format("2006/01/02")
- }
- func shortDate(map[string]interface{}) string {
- return time.Now().Format("01/02")
- }
- func isInternalKey(k string) bool {
- switch k {
- case _level, _levelValue, _time, _source, _instanceID, _appID, _deplyEnv, _zone:
- return true
- }
- return false
- }
- func message(d map[string]interface{}) string {
- var m string
- var s []string
- for k, v := range d {
- if k == _log {
- m = fmt.Sprint(v)
- continue
- }
- if isInternalKey(k) {
- continue
- }
- s = append(s, fmt.Sprintf("%s=%v", k, v))
- }
- s = append(s, m)
- return strings.Join(s, " ")
- }
|