github.com/phuslu/log@v1.0.100/logger.go (about)

     1  package log
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"math"
     8  	"net"
     9  	"net/netip"
    10  	"os"
    11  	"reflect"
    12  	"runtime"
    13  	"strconv"
    14  	"sync"
    15  	"sync/atomic"
    16  	"time"
    17  	"unsafe"
    18  )
    19  
    20  // DefaultLogger is the global logger.
    21  var DefaultLogger = Logger{
    22  	Level:      DebugLevel,
    23  	Caller:     0,
    24  	TimeField:  "",
    25  	TimeFormat: "",
    26  	Writer:     IOWriter{os.Stderr},
    27  }
    28  
    29  // Entry represents a log entry. It is instanced by one of the level method of Logger and finalized by the Msg or Msgf method.
    30  type Entry struct {
    31  	buf   []byte
    32  	Level Level
    33  	w     Writer
    34  }
    35  
    36  // Writer defines an entry writer interface.
    37  type Writer interface {
    38  	WriteEntry(*Entry) (int, error)
    39  }
    40  
    41  // The WriterFunc type is an adapter to allow the use of
    42  // ordinary functions as log writers. If f is a function
    43  // with the appropriate signature, WriterFunc(f) is a
    44  // [Writer] that calls f.
    45  type WriterFunc func(*Entry) (int, error)
    46  
    47  // WriteEntry calls f(e).
    48  func (f WriterFunc) WriteEntry(e *Entry) (int, error) {
    49  	return f(e)
    50  }
    51  
    52  // IOWriter wraps an io.Writer to Writer.
    53  type IOWriter struct {
    54  	io.Writer
    55  }
    56  
    57  // WriteEntry implements Writer.
    58  func (w IOWriter) WriteEntry(e *Entry) (n int, err error) {
    59  	return w.Writer.Write(e.buf)
    60  }
    61  
    62  // IOWriteCloser wraps an io.IOWriteCloser to Writer.
    63  type IOWriteCloser struct {
    64  	io.WriteCloser
    65  }
    66  
    67  // WriteEntry implements Writer.
    68  func (w IOWriteCloser) WriteEntry(e *Entry) (n int, err error) {
    69  	return w.WriteCloser.Write(e.buf)
    70  }
    71  
    72  // Close implements Writer.
    73  func (w IOWriteCloser) Close() (err error) {
    74  	return w.WriteCloser.Close()
    75  }
    76  
    77  // ObjectMarshaler provides a strongly-typed and encoding-agnostic interface
    78  // to be implemented by types used with Entry's Object methods.
    79  type ObjectMarshaler interface {
    80  	MarshalObject(e *Entry)
    81  }
    82  
    83  // A Logger represents an active logging object that generates lines of JSON output to an io.Writer.
    84  type Logger struct {
    85  	// Level defines log levels.
    86  	Level Level
    87  
    88  	// Caller determines if adds the file:line of the "caller" key.
    89  	// If Caller is negative, adds the full /path/to/file:line of the "caller" key.
    90  	Caller int
    91  
    92  	// TimeField defines the time field name in output.  It uses "time" in if empty.
    93  	TimeField string
    94  
    95  	// TimeFormat specifies the time format in output. It uses time.RFC3339 with milliseconds if empty.
    96  	// If set with `TimeFormatUnix`, `TimeFormatUnixMs`, times are formated as UNIX timestamp.
    97  	TimeFormat string
    98  
    99  	// TimeLocation specifices that the location which TimeFormat used. It uses time.Local if empty.
   100  	TimeLocation *time.Location
   101  
   102  	// Context specifies an optional context of logger.
   103  	Context Context
   104  
   105  	// Writer specifies the writer of output. It uses a wrapped os.Stderr Writer in if empty.
   106  	Writer Writer
   107  }
   108  
   109  // TimeFormatUnix defines a time format that makes time fields to be
   110  // serialized as Unix timestamp integers.
   111  const TimeFormatUnix = "\x01"
   112  
   113  // TimeFormatUnixMs defines a time format that makes time fields to be
   114  // serialized as Unix timestamp integers in milliseconds.
   115  const TimeFormatUnixMs = "\x02"
   116  
   117  // TimeFormatUnixWithMs defines a time format that makes time fields to be
   118  // serialized as Unix timestamp timestamp floats.
   119  const TimeFormatUnixWithMs = "\x03"
   120  
   121  // Trace starts a new message with trace level.
   122  func Trace() (e *Entry) {
   123  	if DefaultLogger.silent(TraceLevel) {
   124  		return nil
   125  	}
   126  	e = DefaultLogger.header(TraceLevel)
   127  	if caller, full := DefaultLogger.Caller, false; caller != 0 {
   128  		if caller < 0 {
   129  			caller, full = -caller, true
   130  		}
   131  		var pc uintptr
   132  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   133  	}
   134  	return
   135  }
   136  
   137  // Debug starts a new message with debug level.
   138  func Debug() (e *Entry) {
   139  	if DefaultLogger.silent(DebugLevel) {
   140  		return nil
   141  	}
   142  	e = DefaultLogger.header(DebugLevel)
   143  	if caller, full := DefaultLogger.Caller, false; caller != 0 {
   144  		if caller < 0 {
   145  			caller, full = -caller, true
   146  		}
   147  		var pc uintptr
   148  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   149  	}
   150  	return
   151  }
   152  
   153  // Info starts a new message with info level.
   154  func Info() (e *Entry) {
   155  	if DefaultLogger.silent(InfoLevel) {
   156  		return nil
   157  	}
   158  	e = DefaultLogger.header(InfoLevel)
   159  	if caller, full := DefaultLogger.Caller, false; caller != 0 {
   160  		if caller < 0 {
   161  			caller, full = -caller, true
   162  		}
   163  		var pc uintptr
   164  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   165  	}
   166  	return
   167  }
   168  
   169  // Warn starts a new message with warning level.
   170  func Warn() (e *Entry) {
   171  	if DefaultLogger.silent(WarnLevel) {
   172  		return nil
   173  	}
   174  	e = DefaultLogger.header(WarnLevel)
   175  	if caller, full := DefaultLogger.Caller, false; caller != 0 {
   176  		if caller < 0 {
   177  			caller, full = -caller, true
   178  		}
   179  		var pc uintptr
   180  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   181  	}
   182  	return
   183  }
   184  
   185  // Error starts a new message with error level.
   186  func Error() (e *Entry) {
   187  	if DefaultLogger.silent(ErrorLevel) {
   188  		return nil
   189  	}
   190  	e = DefaultLogger.header(ErrorLevel)
   191  	if caller, full := DefaultLogger.Caller, false; caller != 0 {
   192  		if caller < 0 {
   193  			caller, full = -caller, true
   194  		}
   195  		var pc uintptr
   196  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   197  	}
   198  	return
   199  }
   200  
   201  // Fatal starts a new message with fatal level.
   202  func Fatal() (e *Entry) {
   203  	if DefaultLogger.silent(FatalLevel) {
   204  		return nil
   205  	}
   206  	e = DefaultLogger.header(FatalLevel)
   207  	if caller, full := DefaultLogger.Caller, false; caller != 0 {
   208  		if caller < 0 {
   209  			caller, full = -caller, true
   210  		}
   211  		var pc uintptr
   212  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   213  	}
   214  	return
   215  }
   216  
   217  // Panic starts a new message with panic level.
   218  func Panic() (e *Entry) {
   219  	if DefaultLogger.silent(PanicLevel) {
   220  		return nil
   221  	}
   222  	e = DefaultLogger.header(PanicLevel)
   223  	if caller, full := DefaultLogger.Caller, false; caller != 0 {
   224  		if caller < 0 {
   225  			caller, full = -caller, true
   226  		}
   227  		var pc uintptr
   228  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   229  	}
   230  	return
   231  }
   232  
   233  // Printf sends a log entry without extra field. Arguments are handled in the manner of fmt.Printf.
   234  func Printf(format string, v ...any) {
   235  	e := DefaultLogger.header(noLevel)
   236  	if caller, full := DefaultLogger.Caller, false; caller != 0 {
   237  		if caller < 0 {
   238  			caller, full = -caller, true
   239  		}
   240  		var pc uintptr
   241  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   242  	}
   243  	e.Msgf(format, v...)
   244  }
   245  
   246  // Trace starts a new message with trace level.
   247  func (l *Logger) Trace() (e *Entry) {
   248  	if l.silent(TraceLevel) {
   249  		return nil
   250  	}
   251  	e = l.header(TraceLevel)
   252  	if caller, full := l.Caller, false; caller != 0 {
   253  		if caller < 0 {
   254  			caller, full = -caller, true
   255  		}
   256  		var pc uintptr
   257  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   258  	}
   259  	return
   260  }
   261  
   262  // Debug starts a new message with debug level.
   263  func (l *Logger) Debug() (e *Entry) {
   264  	if l.silent(DebugLevel) {
   265  		return nil
   266  	}
   267  	e = l.header(DebugLevel)
   268  	if caller, full := l.Caller, false; caller != 0 {
   269  		if caller < 0 {
   270  			caller, full = -caller, true
   271  		}
   272  		var pc uintptr
   273  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   274  	}
   275  	return
   276  }
   277  
   278  // Info starts a new message with info level.
   279  func (l *Logger) Info() (e *Entry) {
   280  	if l.silent(InfoLevel) {
   281  		return nil
   282  	}
   283  	e = l.header(InfoLevel)
   284  	if caller, full := l.Caller, false; caller != 0 {
   285  		if caller < 0 {
   286  			caller, full = -caller, true
   287  		}
   288  		var pc uintptr
   289  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   290  	}
   291  	return
   292  }
   293  
   294  // Warn starts a new message with warning level.
   295  func (l *Logger) Warn() (e *Entry) {
   296  	if l.silent(WarnLevel) {
   297  		return nil
   298  	}
   299  	e = l.header(WarnLevel)
   300  	if caller, full := l.Caller, false; caller != 0 {
   301  		if caller < 0 {
   302  			caller, full = -caller, true
   303  		}
   304  		var pc uintptr
   305  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   306  	}
   307  	return
   308  }
   309  
   310  // Error starts a new message with error level.
   311  func (l *Logger) Error() (e *Entry) {
   312  	if l.silent(ErrorLevel) {
   313  		return nil
   314  	}
   315  	e = l.header(ErrorLevel)
   316  	if caller, full := l.Caller, false; caller != 0 {
   317  		if caller < 0 {
   318  			caller, full = -caller, true
   319  		}
   320  		var pc uintptr
   321  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   322  	}
   323  	return
   324  }
   325  
   326  // Fatal starts a new message with fatal level.
   327  func (l *Logger) Fatal() (e *Entry) {
   328  	if l.silent(FatalLevel) {
   329  		return nil
   330  	}
   331  	e = l.header(FatalLevel)
   332  	if caller, full := l.Caller, false; caller != 0 {
   333  		if caller < 0 {
   334  			caller, full = -caller, true
   335  		}
   336  		var pc uintptr
   337  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   338  	}
   339  	return
   340  }
   341  
   342  // Panic starts a new message with panic level.
   343  func (l *Logger) Panic() (e *Entry) {
   344  	if l.silent(PanicLevel) {
   345  		return nil
   346  	}
   347  	e = l.header(PanicLevel)
   348  	if caller, full := l.Caller, false; caller != 0 {
   349  		if caller < 0 {
   350  			caller, full = -caller, true
   351  		}
   352  		var pc uintptr
   353  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   354  	}
   355  	return
   356  }
   357  
   358  // Log starts a new message with no level.
   359  func (l *Logger) Log() (e *Entry) {
   360  	e = l.header(noLevel)
   361  	if caller, full := l.Caller, false; caller != 0 {
   362  		if caller < 0 {
   363  			caller, full = -caller, true
   364  		}
   365  		var pc uintptr
   366  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   367  	}
   368  	return
   369  }
   370  
   371  // WithLevel starts a new message with level.
   372  func (l *Logger) WithLevel(level Level) (e *Entry) {
   373  	if l.silent(level) {
   374  		return nil
   375  	}
   376  	e = l.header(level)
   377  	if caller, full := l.Caller, false; caller != 0 {
   378  		if caller < 0 {
   379  			caller, full = -caller, true
   380  		}
   381  		var pc uintptr
   382  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   383  	}
   384  	return
   385  }
   386  
   387  // Err starts a new message with error level with err as a field if not nil or with info level if err is nil.
   388  func (l *Logger) Err(err error) (e *Entry) {
   389  	var level = InfoLevel
   390  	if err != nil {
   391  		level = ErrorLevel
   392  	}
   393  	if l.silent(level) {
   394  		return nil
   395  	}
   396  	e = l.header(level)
   397  	if e == nil {
   398  		return nil
   399  	}
   400  	if level == ErrorLevel {
   401  		e = e.Err(err)
   402  	}
   403  	if caller, full := l.Caller, false; caller != 0 {
   404  		if caller < 0 {
   405  			caller, full = -caller, true
   406  		}
   407  		var pc uintptr
   408  		e.caller(caller1(caller, &pc, 1, 1), pc, full)
   409  	}
   410  	return
   411  }
   412  
   413  // SetLevel changes logger default level.
   414  func (l *Logger) SetLevel(level Level) {
   415  	atomic.StoreUint32((*uint32)(&l.Level), uint32(level))
   416  }
   417  
   418  // Printf sends a log entry without extra field. Arguments are handled in the manner of fmt.Printf.
   419  func (l *Logger) Printf(format string, v ...any) {
   420  	e := l.header(noLevel)
   421  	if e != nil {
   422  		if caller, full := l.Caller, false; caller != 0 {
   423  			if caller < 0 {
   424  				caller, full = -caller, true
   425  			}
   426  			var pc uintptr
   427  			e.caller(caller1(caller, &pc, 1, 1), pc, full)
   428  		}
   429  	}
   430  	e.Msgf(format, v...)
   431  }
   432  
   433  var epool = sync.Pool{
   434  	New: func() any {
   435  		return &Entry{
   436  			buf: make([]byte, 0, 1024),
   437  		}
   438  	},
   439  }
   440  
   441  const bbcap = 1 << 16
   442  
   443  const smallsString = "00010203040506070809" +
   444  	"10111213141516171819" +
   445  	"20212223242526272829" +
   446  	"30313233343536373839" +
   447  	"40414243444546474849" +
   448  	"50515253545556575859" +
   449  	"60616263646566676869" +
   450  	"70717273747576777879" +
   451  	"80818283848586878889" +
   452  	"90919293949596979899"
   453  
   454  var timeNow = time.Now
   455  var timeOffset, timeZone = func() (int64, string) {
   456  	now := timeNow()
   457  	_, n := now.Zone()
   458  	s := now.Format("Z07:00")
   459  	return int64(n), s
   460  }()
   461  
   462  func (l *Logger) header(level Level) *Entry {
   463  	e := epool.Get().(*Entry)
   464  	e.buf = e.buf[:0]
   465  	e.Level = level
   466  	if l.Writer != nil {
   467  		e.w = l.Writer
   468  	} else {
   469  		e.w = IOWriter{os.Stderr}
   470  	}
   471  	// time
   472  	if l.TimeField == "" {
   473  		e.buf = append(e.buf, "{\"time\":"...)
   474  	} else {
   475  		e.buf = append(e.buf, '{', '"')
   476  		e.buf = append(e.buf, l.TimeField...)
   477  		e.buf = append(e.buf, '"', ':')
   478  	}
   479  	offset := timeOffset
   480  	if l.TimeLocation != nil {
   481  		if l.TimeLocation == time.UTC {
   482  			offset = 0
   483  		} else if l.TimeLocation == time.Local {
   484  			offset = timeOffset
   485  		} else {
   486  			format := l.TimeFormat
   487  			if format == "" {
   488  				format = "2006-01-02T15:04:05.999Z07:00"
   489  			}
   490  			e.buf = append(e.buf, '"')
   491  			e.buf = timeNow().In(l.TimeLocation).AppendFormat(e.buf, format)
   492  			e.buf = append(e.buf, '"')
   493  			goto headerlevel
   494  		}
   495  	}
   496  	switch l.TimeFormat {
   497  	case "":
   498  		sec, nsec, _ := now()
   499  		var tmp [32]byte
   500  		var buf []byte
   501  		if offset == 0 {
   502  			// "2006-01-02T15:04:05.999Z"
   503  			tmp[25] = '"'
   504  			tmp[24] = 'Z'
   505  			buf = tmp[:26]
   506  		} else {
   507  			// "2006-01-02T15:04:05.999Z07:00"
   508  			tmp[30] = '"'
   509  			tmp[29] = timeZone[5]
   510  			tmp[28] = timeZone[4]
   511  			tmp[27] = timeZone[3]
   512  			tmp[26] = timeZone[2]
   513  			tmp[25] = timeZone[1]
   514  			tmp[24] = timeZone[0]
   515  			buf = tmp[:31]
   516  		}
   517  		// date time
   518  		sec += 9223372028715321600 + offset // unixToInternal + internalToAbsolute + timeOffset
   519  		year, month, day, _ := absDate(uint64(sec), true)
   520  		hour, minute, second := absClock(uint64(sec))
   521  		// year
   522  		a := year / 100 * 2
   523  		b := year % 100 * 2
   524  		tmp[0] = '"'
   525  		tmp[1] = smallsString[a]
   526  		tmp[2] = smallsString[a+1]
   527  		tmp[3] = smallsString[b]
   528  		tmp[4] = smallsString[b+1]
   529  		// month
   530  		month *= 2
   531  		tmp[5] = '-'
   532  		tmp[6] = smallsString[month]
   533  		tmp[7] = smallsString[month+1]
   534  		// day
   535  		day *= 2
   536  		tmp[8] = '-'
   537  		tmp[9] = smallsString[day]
   538  		tmp[10] = smallsString[day+1]
   539  		// hour
   540  		hour *= 2
   541  		tmp[11] = 'T'
   542  		tmp[12] = smallsString[hour]
   543  		tmp[13] = smallsString[hour+1]
   544  		// minute
   545  		minute *= 2
   546  		tmp[14] = ':'
   547  		tmp[15] = smallsString[minute]
   548  		tmp[16] = smallsString[minute+1]
   549  		// second
   550  		second *= 2
   551  		tmp[17] = ':'
   552  		tmp[18] = smallsString[second]
   553  		tmp[19] = smallsString[second+1]
   554  		// milli seconds
   555  		a = int(nsec) / 1000000
   556  		b = a % 100 * 2
   557  		tmp[20] = '.'
   558  		tmp[21] = byte('0' + a/100)
   559  		tmp[22] = smallsString[b]
   560  		tmp[23] = smallsString[b+1]
   561  		// append to e.buf
   562  		e.buf = append(e.buf, buf...)
   563  	case TimeFormatUnix:
   564  		sec, _, _ := now()
   565  		// 1595759807
   566  		var tmp [10]byte
   567  		// seconds
   568  		b := sec % 100 * 2
   569  		sec /= 100
   570  		tmp[9] = smallsString[b+1]
   571  		tmp[8] = smallsString[b]
   572  		b = sec % 100 * 2
   573  		sec /= 100
   574  		tmp[7] = smallsString[b+1]
   575  		tmp[6] = smallsString[b]
   576  		b = sec % 100 * 2
   577  		sec /= 100
   578  		tmp[5] = smallsString[b+1]
   579  		tmp[4] = smallsString[b]
   580  		b = sec % 100 * 2
   581  		sec /= 100
   582  		tmp[3] = smallsString[b+1]
   583  		tmp[2] = smallsString[b]
   584  		b = sec % 100 * 2
   585  		tmp[1] = smallsString[b+1]
   586  		tmp[0] = smallsString[b]
   587  		// append to e.buf
   588  		e.buf = append(e.buf, tmp[:]...)
   589  	case TimeFormatUnixMs:
   590  		sec, nsec, _ := now()
   591  		// 1595759807105
   592  		var tmp [13]byte
   593  		// milli seconds
   594  		a := int64(nsec) / 1000000
   595  		b := a % 100 * 2
   596  		tmp[12] = smallsString[b+1]
   597  		tmp[11] = smallsString[b]
   598  		tmp[10] = byte('0' + a/100)
   599  		// seconds
   600  		b = sec % 100 * 2
   601  		sec /= 100
   602  		tmp[9] = smallsString[b+1]
   603  		tmp[8] = smallsString[b]
   604  		b = sec % 100 * 2
   605  		sec /= 100
   606  		tmp[7] = smallsString[b+1]
   607  		tmp[6] = smallsString[b]
   608  		b = sec % 100 * 2
   609  		sec /= 100
   610  		tmp[5] = smallsString[b+1]
   611  		tmp[4] = smallsString[b]
   612  		b = sec % 100 * 2
   613  		sec /= 100
   614  		tmp[3] = smallsString[b+1]
   615  		tmp[2] = smallsString[b]
   616  		b = sec % 100 * 2
   617  		tmp[1] = smallsString[b+1]
   618  		tmp[0] = smallsString[b]
   619  		// append to e.buf
   620  		e.buf = append(e.buf, tmp[:]...)
   621  	case TimeFormatUnixWithMs:
   622  		sec, nsec, _ := now()
   623  		// 1595759807.105
   624  		var tmp [14]byte
   625  		// milli seconds
   626  		a := int64(nsec) / 1000000
   627  		b := a % 100 * 2
   628  		tmp[13] = smallsString[b+1]
   629  		tmp[12] = smallsString[b]
   630  		tmp[11] = byte('0' + a/100)
   631  		tmp[10] = '.'
   632  		// seconds
   633  		b = sec % 100 * 2
   634  		sec /= 100
   635  		tmp[9] = smallsString[b+1]
   636  		tmp[8] = smallsString[b]
   637  		b = sec % 100 * 2
   638  		sec /= 100
   639  		tmp[7] = smallsString[b+1]
   640  		tmp[6] = smallsString[b]
   641  		b = sec % 100 * 2
   642  		sec /= 100
   643  		tmp[5] = smallsString[b+1]
   644  		tmp[4] = smallsString[b]
   645  		b = sec % 100 * 2
   646  		sec /= 100
   647  		tmp[3] = smallsString[b+1]
   648  		tmp[2] = smallsString[b]
   649  		b = sec % 100 * 2
   650  		tmp[1] = smallsString[b+1]
   651  		tmp[0] = smallsString[b]
   652  		// append to e.buf
   653  		e.buf = append(e.buf, tmp[:]...)
   654  	default:
   655  		e.buf = append(e.buf, '"')
   656  		if l.TimeLocation == time.UTC {
   657  			e.buf = timeNow().UTC().AppendFormat(e.buf, l.TimeFormat)
   658  		} else {
   659  			e.buf = timeNow().AppendFormat(e.buf, l.TimeFormat)
   660  		}
   661  		e.buf = append(e.buf, '"')
   662  	}
   663  headerlevel:
   664  	// level
   665  	switch level {
   666  	case DebugLevel:
   667  		e.buf = append(e.buf, ",\"level\":\"debug\""...)
   668  	case InfoLevel:
   669  		e.buf = append(e.buf, ",\"level\":\"info\""...)
   670  	case WarnLevel:
   671  		e.buf = append(e.buf, ",\"level\":\"warn\""...)
   672  	case ErrorLevel:
   673  		e.buf = append(e.buf, ",\"level\":\"error\""...)
   674  	case TraceLevel:
   675  		e.buf = append(e.buf, ",\"level\":\"trace\""...)
   676  	case FatalLevel:
   677  		e.buf = append(e.buf, ",\"level\":\"fatal\""...)
   678  	case PanicLevel:
   679  		e.buf = append(e.buf, ",\"level\":\"panic\""...)
   680  	}
   681  	// context
   682  	if l.Context != nil {
   683  		e.buf = append(e.buf, l.Context...)
   684  	}
   685  	return e
   686  }
   687  
   688  // Time append append t formated as string using time.RFC3339Nano.
   689  func (e *Entry) Time(key string, t time.Time) *Entry {
   690  	if e == nil {
   691  		return nil
   692  	}
   693  	e.buf = append(e.buf, ',', '"')
   694  	e.buf = append(e.buf, key...)
   695  	e.buf = append(e.buf, '"', ':', '"')
   696  	e.buf = t.AppendFormat(e.buf, "2006-01-02T15:04:05.999Z07:00")
   697  	e.buf = append(e.buf, '"')
   698  	return e
   699  }
   700  
   701  // TimeFormat append append t formated as string using timefmt.
   702  func (e *Entry) TimeFormat(key string, timefmt string, t time.Time) *Entry {
   703  	if e == nil {
   704  		return nil
   705  	}
   706  	e.buf = append(e.buf, ',', '"')
   707  	e.buf = append(e.buf, key...)
   708  	e.buf = append(e.buf, '"', ':')
   709  	switch timefmt {
   710  	case TimeFormatUnix:
   711  		e.buf = strconv.AppendInt(e.buf, t.Unix(), 10)
   712  	case TimeFormatUnixMs:
   713  		e.buf = strconv.AppendInt(e.buf, t.UnixNano()/1000000, 10)
   714  	case TimeFormatUnixWithMs:
   715  		e.buf = strconv.AppendInt(e.buf, t.Unix(), 10)
   716  		e.buf = append(e.buf, '.')
   717  		e.buf = strconv.AppendInt(e.buf, t.UnixNano()/1000000%1000, 10)
   718  	default:
   719  		e.buf = append(e.buf, '"')
   720  		e.buf = t.AppendFormat(e.buf, timefmt)
   721  		e.buf = append(e.buf, '"')
   722  	}
   723  	return e
   724  }
   725  
   726  // Times append append a formated as string array using time.RFC3339Nano.
   727  func (e *Entry) Times(key string, a []time.Time) *Entry {
   728  	if e == nil {
   729  		return nil
   730  	}
   731  	e.buf = append(e.buf, ',', '"')
   732  	e.buf = append(e.buf, key...)
   733  	e.buf = append(e.buf, '"', ':', '[')
   734  	for i, t := range a {
   735  		if i != 0 {
   736  			e.buf = append(e.buf, ',')
   737  		}
   738  		e.buf = append(e.buf, '"')
   739  		e.buf = t.AppendFormat(e.buf, time.RFC3339Nano)
   740  		e.buf = append(e.buf, '"')
   741  	}
   742  	e.buf = append(e.buf, ']')
   743  
   744  	return e
   745  }
   746  
   747  // TimesFormat append append a formated as string array using timefmt.
   748  func (e *Entry) TimesFormat(key string, timefmt string, a []time.Time) *Entry {
   749  	if e == nil {
   750  		return nil
   751  	}
   752  	e.buf = append(e.buf, ',', '"')
   753  	e.buf = append(e.buf, key...)
   754  	e.buf = append(e.buf, '"', ':', '[')
   755  	for i, t := range a {
   756  		if i != 0 {
   757  			e.buf = append(e.buf, ',')
   758  		}
   759  		switch timefmt {
   760  		case TimeFormatUnix:
   761  			e.buf = strconv.AppendInt(e.buf, t.Unix(), 10)
   762  		case TimeFormatUnixMs:
   763  			e.buf = strconv.AppendInt(e.buf, t.UnixNano()/1000000, 10)
   764  		case TimeFormatUnixWithMs:
   765  			e.buf = strconv.AppendInt(e.buf, t.Unix(), 10)
   766  			e.buf = append(e.buf, '.')
   767  			e.buf = strconv.AppendInt(e.buf, t.UnixNano()/1000000%1000, 10)
   768  		default:
   769  			e.buf = append(e.buf, '"')
   770  			e.buf = t.AppendFormat(e.buf, timefmt)
   771  			e.buf = append(e.buf, '"')
   772  		}
   773  	}
   774  	e.buf = append(e.buf, ']')
   775  
   776  	return e
   777  }
   778  
   779  // Bool append append the val as a bool to the entry.
   780  func (e *Entry) Bool(key string, b bool) *Entry {
   781  	if e == nil {
   782  		return nil
   783  	}
   784  	e.buf = append(e.buf, ',', '"')
   785  	e.buf = append(e.buf, key...)
   786  	e.buf = append(e.buf, '"', ':')
   787  	e.buf = strconv.AppendBool(e.buf, b)
   788  	return e
   789  }
   790  
   791  // Bools adds the field key with val as a []bool to the entry.
   792  func (e *Entry) Bools(key string, b []bool) *Entry {
   793  	if e == nil {
   794  		return nil
   795  	}
   796  	e.buf = append(e.buf, ',', '"')
   797  	e.buf = append(e.buf, key...)
   798  	e.buf = append(e.buf, '"', ':', '[')
   799  	for i, a := range b {
   800  		if i != 0 {
   801  			e.buf = append(e.buf, ',')
   802  		}
   803  		e.buf = strconv.AppendBool(e.buf, a)
   804  	}
   805  	e.buf = append(e.buf, ']')
   806  	return e
   807  }
   808  
   809  // Dur adds the field key with duration d to the entry.
   810  func (e *Entry) Dur(key string, d time.Duration) *Entry {
   811  	if e == nil {
   812  		return nil
   813  	}
   814  	e.buf = append(e.buf, ',', '"')
   815  	e.buf = append(e.buf, key...)
   816  	e.buf = append(e.buf, '"', ':')
   817  	if d < 0 {
   818  		d = -d
   819  		e.buf = append(e.buf, '-')
   820  	}
   821  	e.buf = strconv.AppendInt(e.buf, int64(d/time.Millisecond), 10)
   822  	if n := (d % time.Millisecond); n != 0 {
   823  		var tmp [7]byte
   824  		b := n % 100 * 2
   825  		n /= 100
   826  		tmp[6] = smallsString[b+1]
   827  		tmp[5] = smallsString[b]
   828  		b = n % 100 * 2
   829  		n /= 100
   830  		tmp[4] = smallsString[b+1]
   831  		tmp[3] = smallsString[b]
   832  		b = n % 100 * 2
   833  		tmp[2] = smallsString[b+1]
   834  		tmp[1] = smallsString[b]
   835  		tmp[0] = '.'
   836  		e.buf = append(e.buf, tmp[:]...)
   837  	}
   838  	return e
   839  }
   840  
   841  // TimeDiff adds the field key with positive duration between time t and start.
   842  // If time t is not greater than start, duration will be 0.
   843  // Duration format follows the same principle as Dur().
   844  func (e *Entry) TimeDiff(key string, t time.Time, start time.Time) *Entry {
   845  	if e == nil {
   846  		return e
   847  	}
   848  	var d time.Duration
   849  	if t.After(start) {
   850  		d = t.Sub(start)
   851  	}
   852  	e.buf = append(e.buf, ',', '"')
   853  	e.buf = append(e.buf, key...)
   854  	e.buf = append(e.buf, '"', ':')
   855  	e.buf = strconv.AppendInt(e.buf, int64(d/time.Millisecond), 10)
   856  	if n := (d % time.Millisecond); n != 0 {
   857  		var tmp [7]byte
   858  		b := n % 100 * 2
   859  		n /= 100
   860  		tmp[6] = smallsString[b+1]
   861  		tmp[5] = smallsString[b]
   862  		b = n % 100 * 2
   863  		n /= 100
   864  		tmp[4] = smallsString[b+1]
   865  		tmp[3] = smallsString[b]
   866  		b = n % 100 * 2
   867  		tmp[2] = smallsString[b+1]
   868  		tmp[1] = smallsString[b]
   869  		tmp[0] = '.'
   870  		e.buf = append(e.buf, tmp[:]...)
   871  	}
   872  	return e
   873  }
   874  
   875  // Durs adds the field key with val as a []time.Duration to the entry.
   876  func (e *Entry) Durs(key string, d []time.Duration) *Entry {
   877  	if e == nil {
   878  		return nil
   879  	}
   880  	e.buf = append(e.buf, ',', '"')
   881  	e.buf = append(e.buf, key...)
   882  	e.buf = append(e.buf, '"', ':', '[')
   883  	for i, a := range d {
   884  		if i != 0 {
   885  			e.buf = append(e.buf, ',')
   886  		}
   887  		if a < 0 {
   888  			a = -a
   889  			e.buf = append(e.buf, '-')
   890  		}
   891  		e.buf = strconv.AppendInt(e.buf, int64(a/time.Millisecond), 10)
   892  		if n := (a % time.Millisecond); n != 0 {
   893  			var tmp [7]byte
   894  			b := n % 100 * 2
   895  			n /= 100
   896  			tmp[6] = smallsString[b+1]
   897  			tmp[5] = smallsString[b]
   898  			b = n % 100 * 2
   899  			n /= 100
   900  			tmp[4] = smallsString[b+1]
   901  			tmp[3] = smallsString[b]
   902  			b = n % 100 * 2
   903  			tmp[2] = smallsString[b+1]
   904  			tmp[1] = smallsString[b]
   905  			tmp[0] = '.'
   906  			e.buf = append(e.buf, tmp[:]...)
   907  		}
   908  	}
   909  	e.buf = append(e.buf, ']')
   910  	return e
   911  }
   912  
   913  // Err adds the field "error" with serialized err to the entry.
   914  func (e *Entry) Err(err error) *Entry {
   915  	return e.AnErr("error", err)
   916  }
   917  
   918  // AnErr adds the field key with serialized err to the logger context.
   919  func (e *Entry) AnErr(key string, err error) *Entry {
   920  	if e == nil {
   921  		return nil
   922  	}
   923  
   924  	if err == nil {
   925  		e.buf = append(e.buf, ',', '"')
   926  		e.buf = append(e.buf, key...)
   927  		e.buf = append(e.buf, "\":null"...)
   928  		return e
   929  	}
   930  
   931  	e.buf = append(e.buf, ',', '"')
   932  	e.buf = append(e.buf, key...)
   933  	e.buf = append(e.buf, '"', ':')
   934  	if o, ok := err.(ObjectMarshaler); ok {
   935  		o.MarshalObject(e)
   936  	} else {
   937  		e.buf = append(e.buf, '"')
   938  		e.string(err.Error())
   939  		e.buf = append(e.buf, '"')
   940  	}
   941  	return e
   942  }
   943  
   944  // Errs adds the field key with errs as an array of serialized errors to the entry.
   945  func (e *Entry) Errs(key string, errs []error) *Entry {
   946  	if e == nil {
   947  		return nil
   948  	}
   949  
   950  	e.buf = append(e.buf, ',', '"')
   951  	e.buf = append(e.buf, key...)
   952  	e.buf = append(e.buf, '"', ':', '[')
   953  	for i, err := range errs {
   954  		if i != 0 {
   955  			e.buf = append(e.buf, ',')
   956  		}
   957  		if err == nil {
   958  			e.buf = append(e.buf, "null"...)
   959  		} else {
   960  			e.buf = append(e.buf, '"')
   961  			e.string(err.Error())
   962  			e.buf = append(e.buf, '"')
   963  		}
   964  	}
   965  	e.buf = append(e.buf, ']')
   966  	return e
   967  }
   968  
   969  // https://github.com/golang/go/blob/master/src/encoding/json/encode.go#L541
   970  func appendFloat(b []byte, f float64, bits int) []byte {
   971  	switch {
   972  	case math.IsNaN(f):
   973  		return append(b, `"NaN"`...)
   974  	case math.IsInf(f, 1):
   975  		return append(b, `"+Inf"`...)
   976  	case math.IsInf(f, -1):
   977  		return append(b, `"-Inf"`...)
   978  	}
   979  	abs := math.Abs(f)
   980  	fmt := byte('f')
   981  	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
   982  	if abs != 0 {
   983  		if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
   984  			fmt = 'e'
   985  		}
   986  	}
   987  	b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
   988  	if fmt == 'e' {
   989  		// clean up e-09 to e-9
   990  		n := len(b)
   991  		if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
   992  			b[n-2] = b[n-1]
   993  			b = b[:n-1]
   994  		}
   995  	}
   996  	return b
   997  }
   998  
   999  // Float64 adds the field key with f as a float64 to the entry.
  1000  func (e *Entry) Float64(key string, f float64) *Entry {
  1001  	if e == nil {
  1002  		return nil
  1003  	}
  1004  	e.buf = append(e.buf, ',', '"')
  1005  	e.buf = append(e.buf, key...)
  1006  	e.buf = append(e.buf, '"', ':')
  1007  	e.buf = appendFloat(e.buf, f, 64)
  1008  	return e
  1009  }
  1010  
  1011  // Float32 adds the field key with f as a float32 to the entry.
  1012  func (e *Entry) Float32(key string, f float32) *Entry {
  1013  	if e == nil {
  1014  		return nil
  1015  	}
  1016  	e.buf = append(e.buf, ',', '"')
  1017  	e.buf = append(e.buf, key...)
  1018  	e.buf = append(e.buf, '"', ':')
  1019  	e.buf = appendFloat(e.buf, float64(f), 32)
  1020  	return e
  1021  }
  1022  
  1023  // Floats64 adds the field key with f as a []float64 to the entry.
  1024  func (e *Entry) Floats64(key string, f []float64) *Entry {
  1025  	if e == nil {
  1026  		return nil
  1027  	}
  1028  	e.buf = append(e.buf, ',', '"')
  1029  	e.buf = append(e.buf, key...)
  1030  	e.buf = append(e.buf, '"', ':', '[')
  1031  	for i, a := range f {
  1032  		if i != 0 {
  1033  			e.buf = append(e.buf, ',')
  1034  		}
  1035  		e.buf = appendFloat(e.buf, a, 64)
  1036  	}
  1037  	e.buf = append(e.buf, ']')
  1038  	return e
  1039  }
  1040  
  1041  // Floats32 adds the field key with f as a []float32 to the entry.
  1042  func (e *Entry) Floats32(key string, f []float32) *Entry {
  1043  	if e == nil {
  1044  		return nil
  1045  	}
  1046  	e.buf = append(e.buf, ',', '"')
  1047  	e.buf = append(e.buf, key...)
  1048  	e.buf = append(e.buf, '"', ':', '[')
  1049  	for i, a := range f {
  1050  		if i != 0 {
  1051  			e.buf = append(e.buf, ',')
  1052  		}
  1053  		e.buf = appendFloat(e.buf, float64(a), 32)
  1054  	}
  1055  	e.buf = append(e.buf, ']')
  1056  	return e
  1057  }
  1058  
  1059  // Int64 adds the field key with i as a int64 to the entry.
  1060  func (e *Entry) Int64(key string, i int64) *Entry {
  1061  	if e == nil {
  1062  		return nil
  1063  	}
  1064  	e.buf = append(e.buf, ',', '"')
  1065  	e.buf = append(e.buf, key...)
  1066  	e.buf = append(e.buf, '"', ':')
  1067  	e.buf = strconv.AppendInt(e.buf, i, 10)
  1068  	return e
  1069  }
  1070  
  1071  // Uint adds the field key with i as a uint to the entry.
  1072  func (e *Entry) Uint(key string, i uint) *Entry {
  1073  	if e == nil {
  1074  		return nil
  1075  	}
  1076  	e.buf = append(e.buf, ',', '"')
  1077  	e.buf = append(e.buf, key...)
  1078  	e.buf = append(e.buf, '"', ':')
  1079  	e.buf = strconv.AppendUint(e.buf, uint64(i), 10)
  1080  	return e
  1081  }
  1082  
  1083  // Uint64 adds the field key with i as a uint64 to the entry.
  1084  func (e *Entry) Uint64(key string, i uint64) *Entry {
  1085  	if e == nil {
  1086  		return nil
  1087  	}
  1088  	e.buf = append(e.buf, ',', '"')
  1089  	e.buf = append(e.buf, key...)
  1090  	e.buf = append(e.buf, '"', ':')
  1091  	e.buf = strconv.AppendUint(e.buf, i, 10)
  1092  	return e
  1093  }
  1094  
  1095  // Int adds the field key with i as a int to the entry.
  1096  func (e *Entry) Int(key string, i int) *Entry {
  1097  	if e == nil {
  1098  		return nil
  1099  	}
  1100  	e.buf = append(e.buf, ',', '"')
  1101  	e.buf = append(e.buf, key...)
  1102  	e.buf = append(e.buf, '"', ':')
  1103  	e.buf = strconv.AppendInt(e.buf, int64(i), 10)
  1104  	return e
  1105  }
  1106  
  1107  // Int32 adds the field key with i as a int32 to the entry.
  1108  func (e *Entry) Int32(key string, i int32) *Entry {
  1109  	if e == nil {
  1110  		return nil
  1111  	}
  1112  	e.buf = append(e.buf, ',', '"')
  1113  	e.buf = append(e.buf, key...)
  1114  	e.buf = append(e.buf, '"', ':')
  1115  	e.buf = strconv.AppendInt(e.buf, int64(i), 10)
  1116  	return e
  1117  }
  1118  
  1119  // Int16 adds the field key with i as a int16 to the entry.
  1120  func (e *Entry) Int16(key string, i int16) *Entry {
  1121  	if e == nil {
  1122  		return nil
  1123  	}
  1124  	e.buf = append(e.buf, ',', '"')
  1125  	e.buf = append(e.buf, key...)
  1126  	e.buf = append(e.buf, '"', ':')
  1127  	e.buf = strconv.AppendInt(e.buf, int64(i), 10)
  1128  	return e
  1129  }
  1130  
  1131  // Int8 adds the field key with i as a int8 to the entry.
  1132  func (e *Entry) Int8(key string, i int8) *Entry {
  1133  	if e == nil {
  1134  		return nil
  1135  	}
  1136  	e.buf = append(e.buf, ',', '"')
  1137  	e.buf = append(e.buf, key...)
  1138  	e.buf = append(e.buf, '"', ':')
  1139  	e.buf = strconv.AppendInt(e.buf, int64(i), 10)
  1140  	return e
  1141  }
  1142  
  1143  // Uint32 adds the field key with i as a uint32 to the entry.
  1144  func (e *Entry) Uint32(key string, i uint32) *Entry {
  1145  	if e == nil {
  1146  		return nil
  1147  	}
  1148  	e.buf = append(e.buf, ',', '"')
  1149  	e.buf = append(e.buf, key...)
  1150  	e.buf = append(e.buf, '"', ':')
  1151  	e.buf = strconv.AppendUint(e.buf, uint64(i), 10)
  1152  	return e
  1153  }
  1154  
  1155  // Uint16 adds the field key with i as a uint16 to the entry.
  1156  func (e *Entry) Uint16(key string, i uint16) *Entry {
  1157  	if e == nil {
  1158  		return nil
  1159  	}
  1160  	e.buf = append(e.buf, ',', '"')
  1161  	e.buf = append(e.buf, key...)
  1162  	e.buf = append(e.buf, '"', ':')
  1163  	e.buf = strconv.AppendUint(e.buf, uint64(i), 10)
  1164  	return e
  1165  }
  1166  
  1167  // Uint8 adds the field key with i as a uint8 to the entry.
  1168  func (e *Entry) Uint8(key string, i uint8) *Entry {
  1169  	if e == nil {
  1170  		return nil
  1171  	}
  1172  	e.buf = append(e.buf, ',', '"')
  1173  	e.buf = append(e.buf, key...)
  1174  	e.buf = append(e.buf, '"', ':')
  1175  	e.buf = strconv.AppendUint(e.buf, uint64(i), 10)
  1176  	return e
  1177  }
  1178  
  1179  // Ints64 adds the field key with i as a []int64 to the entry.
  1180  func (e *Entry) Ints64(key string, a []int64) *Entry {
  1181  	if e == nil {
  1182  		return nil
  1183  	}
  1184  	e.buf = append(e.buf, ',', '"')
  1185  	e.buf = append(e.buf, key...)
  1186  	e.buf = append(e.buf, '"', ':', '[')
  1187  	for i, n := range a {
  1188  		if i != 0 {
  1189  			e.buf = append(e.buf, ',')
  1190  		}
  1191  		e.buf = strconv.AppendInt(e.buf, n, 10)
  1192  	}
  1193  	e.buf = append(e.buf, ']')
  1194  	return e
  1195  }
  1196  
  1197  // Ints32 adds the field key with i as a []int32 to the entry.
  1198  func (e *Entry) Ints32(key string, a []int32) *Entry {
  1199  	if e == nil {
  1200  		return nil
  1201  	}
  1202  	e.buf = append(e.buf, ',', '"')
  1203  	e.buf = append(e.buf, key...)
  1204  	e.buf = append(e.buf, '"', ':', '[')
  1205  	for i, n := range a {
  1206  		if i != 0 {
  1207  			e.buf = append(e.buf, ',')
  1208  		}
  1209  		e.buf = strconv.AppendInt(e.buf, int64(n), 10)
  1210  	}
  1211  	e.buf = append(e.buf, ']')
  1212  	return e
  1213  }
  1214  
  1215  // Ints16 adds the field key with i as a []int16 to the entry.
  1216  func (e *Entry) Ints16(key string, a []int16) *Entry {
  1217  	if e == nil {
  1218  		return nil
  1219  	}
  1220  	e.buf = append(e.buf, ',', '"')
  1221  	e.buf = append(e.buf, key...)
  1222  	e.buf = append(e.buf, '"', ':', '[')
  1223  	for i, n := range a {
  1224  		if i != 0 {
  1225  			e.buf = append(e.buf, ',')
  1226  		}
  1227  		e.buf = strconv.AppendInt(e.buf, int64(n), 10)
  1228  	}
  1229  	e.buf = append(e.buf, ']')
  1230  	return e
  1231  }
  1232  
  1233  // Ints8 adds the field key with i as a []int8 to the entry.
  1234  func (e *Entry) Ints8(key string, a []int8) *Entry {
  1235  	if e == nil {
  1236  		return nil
  1237  	}
  1238  	e.buf = append(e.buf, ',', '"')
  1239  	e.buf = append(e.buf, key...)
  1240  	e.buf = append(e.buf, '"', ':', '[')
  1241  	for i, n := range a {
  1242  		if i != 0 {
  1243  			e.buf = append(e.buf, ',')
  1244  		}
  1245  		e.buf = strconv.AppendInt(e.buf, int64(n), 10)
  1246  	}
  1247  	e.buf = append(e.buf, ']')
  1248  	return e
  1249  }
  1250  
  1251  // Ints adds the field key with i as a []int to the entry.
  1252  func (e *Entry) Ints(key string, a []int) *Entry {
  1253  	if e == nil {
  1254  		return nil
  1255  	}
  1256  	e.buf = append(e.buf, ',', '"')
  1257  	e.buf = append(e.buf, key...)
  1258  	e.buf = append(e.buf, '"', ':', '[')
  1259  	for i, n := range a {
  1260  		if i != 0 {
  1261  			e.buf = append(e.buf, ',')
  1262  		}
  1263  		e.buf = strconv.AppendInt(e.buf, int64(n), 10)
  1264  	}
  1265  	e.buf = append(e.buf, ']')
  1266  	return e
  1267  }
  1268  
  1269  // Uints64 adds the field key with i as a []uint64 to the entry.
  1270  func (e *Entry) Uints64(key string, a []uint64) *Entry {
  1271  	if e == nil {
  1272  		return nil
  1273  	}
  1274  	e.buf = append(e.buf, ',', '"')
  1275  	e.buf = append(e.buf, key...)
  1276  	e.buf = append(e.buf, '"', ':', '[')
  1277  	for i, n := range a {
  1278  		if i != 0 {
  1279  			e.buf = append(e.buf, ',')
  1280  		}
  1281  		e.buf = strconv.AppendUint(e.buf, n, 10)
  1282  	}
  1283  	e.buf = append(e.buf, ']')
  1284  	return e
  1285  }
  1286  
  1287  // Uints32 adds the field key with i as a []uint32 to the entry.
  1288  func (e *Entry) Uints32(key string, a []uint32) *Entry {
  1289  	if e == nil {
  1290  		return nil
  1291  	}
  1292  	e.buf = append(e.buf, ',', '"')
  1293  	e.buf = append(e.buf, key...)
  1294  	e.buf = append(e.buf, '"', ':', '[')
  1295  	for i, n := range a {
  1296  		if i != 0 {
  1297  			e.buf = append(e.buf, ',')
  1298  		}
  1299  		e.buf = strconv.AppendUint(e.buf, uint64(n), 10)
  1300  	}
  1301  	e.buf = append(e.buf, ']')
  1302  	return e
  1303  }
  1304  
  1305  // Uints16 adds the field key with i as a []uint16 to the entry.
  1306  func (e *Entry) Uints16(key string, a []uint16) *Entry {
  1307  	if e == nil {
  1308  		return nil
  1309  	}
  1310  	e.buf = append(e.buf, ',', '"')
  1311  	e.buf = append(e.buf, key...)
  1312  	e.buf = append(e.buf, '"', ':', '[')
  1313  	for i, n := range a {
  1314  		if i != 0 {
  1315  			e.buf = append(e.buf, ',')
  1316  		}
  1317  		e.buf = strconv.AppendUint(e.buf, uint64(n), 10)
  1318  	}
  1319  	e.buf = append(e.buf, ']')
  1320  	return e
  1321  }
  1322  
  1323  // Uints8 adds the field key with i as a []uint8 to the entry.
  1324  func (e *Entry) Uints8(key string, a []uint8) *Entry {
  1325  	if e == nil {
  1326  		return nil
  1327  	}
  1328  	e.buf = append(e.buf, ',', '"')
  1329  	e.buf = append(e.buf, key...)
  1330  	e.buf = append(e.buf, '"', ':', '[')
  1331  	for i, n := range a {
  1332  		if i != 0 {
  1333  			e.buf = append(e.buf, ',')
  1334  		}
  1335  		e.buf = strconv.AppendUint(e.buf, uint64(n), 10)
  1336  	}
  1337  	e.buf = append(e.buf, ']')
  1338  	return e
  1339  }
  1340  
  1341  // Uints adds the field key with i as a []uint to the entry.
  1342  func (e *Entry) Uints(key string, a []uint) *Entry {
  1343  	if e == nil {
  1344  		return nil
  1345  	}
  1346  	e.buf = append(e.buf, ',', '"')
  1347  	e.buf = append(e.buf, key...)
  1348  	e.buf = append(e.buf, '"', ':', '[')
  1349  	for i, n := range a {
  1350  		if i != 0 {
  1351  			e.buf = append(e.buf, ',')
  1352  		}
  1353  		e.buf = strconv.AppendUint(e.buf, uint64(n), 10)
  1354  	}
  1355  	e.buf = append(e.buf, ']')
  1356  	return e
  1357  }
  1358  
  1359  // RawJSON adds already encoded JSON to the log line under key.
  1360  func (e *Entry) RawJSON(key string, b []byte) *Entry {
  1361  	if e == nil {
  1362  		return nil
  1363  	}
  1364  	e.buf = append(e.buf, ',', '"')
  1365  	e.buf = append(e.buf, key...)
  1366  	e.buf = append(e.buf, '"', ':')
  1367  	e.buf = append(e.buf, b...)
  1368  	return e
  1369  }
  1370  
  1371  // RawJSONStr adds already encoded JSON String to the log line under key.
  1372  func (e *Entry) RawJSONStr(key string, s string) *Entry {
  1373  	if e == nil {
  1374  		return nil
  1375  	}
  1376  	e.buf = append(e.buf, ',', '"')
  1377  	e.buf = append(e.buf, key...)
  1378  	e.buf = append(e.buf, '"', ':')
  1379  	e.buf = append(e.buf, s...)
  1380  	return e
  1381  }
  1382  
  1383  // Str adds the field key with val as a string to the entry.
  1384  func (e *Entry) Str(key string, val string) *Entry {
  1385  	if e == nil {
  1386  		return nil
  1387  	}
  1388  	e.buf = append(e.buf, ',', '"')
  1389  	e.buf = append(e.buf, key...)
  1390  	e.buf = append(e.buf, '"', ':', '"')
  1391  	e.string(val)
  1392  	e.buf = append(e.buf, '"')
  1393  	return e
  1394  }
  1395  
  1396  // StrInt adds the field key with integer val as a string to the entry.
  1397  func (e *Entry) StrInt(key string, val int64) *Entry {
  1398  	if e == nil {
  1399  		return nil
  1400  	}
  1401  	e.buf = append(e.buf, ',', '"')
  1402  	e.buf = append(e.buf, key...)
  1403  	e.buf = append(e.buf, '"', ':', '"')
  1404  	e.buf = strconv.AppendInt(e.buf, val, 10)
  1405  	e.buf = append(e.buf, '"')
  1406  	return e
  1407  }
  1408  
  1409  // Stringer adds the field key with val.String() to the entry.
  1410  func (e *Entry) Stringer(key string, val fmt.Stringer) *Entry {
  1411  	if e == nil {
  1412  		return nil
  1413  	}
  1414  	e.buf = append(e.buf, ',', '"')
  1415  	e.buf = append(e.buf, key...)
  1416  	e.buf = append(e.buf, '"', ':')
  1417  	if val != nil {
  1418  		e.buf = append(e.buf, '"')
  1419  		e.string(val.String())
  1420  		e.buf = append(e.buf, '"')
  1421  	} else {
  1422  		e.buf = append(e.buf, "null"...)
  1423  	}
  1424  	return e
  1425  }
  1426  
  1427  // GoStringer adds the field key with val.GoStringer() to the entry.
  1428  func (e *Entry) GoStringer(key string, val fmt.GoStringer) *Entry {
  1429  	if e == nil {
  1430  		return nil
  1431  	}
  1432  	e.buf = append(e.buf, ',', '"')
  1433  	e.buf = append(e.buf, key...)
  1434  	e.buf = append(e.buf, '"', ':')
  1435  	if val != nil {
  1436  		e.buf = append(e.buf, '"')
  1437  		e.string(val.GoString())
  1438  		e.buf = append(e.buf, '"')
  1439  	} else {
  1440  		e.buf = append(e.buf, "null"...)
  1441  	}
  1442  	return e
  1443  }
  1444  
  1445  // Strs adds the field key with vals as a []string to the entry.
  1446  func (e *Entry) Strs(key string, vals []string) *Entry {
  1447  	if e == nil {
  1448  		return nil
  1449  	}
  1450  	e.buf = append(e.buf, ',', '"')
  1451  	e.buf = append(e.buf, key...)
  1452  	e.buf = append(e.buf, '"', ':', '[')
  1453  	for i, val := range vals {
  1454  		if i != 0 {
  1455  			e.buf = append(e.buf, ',')
  1456  		}
  1457  		e.buf = append(e.buf, '"')
  1458  		e.string(val)
  1459  		e.buf = append(e.buf, '"')
  1460  	}
  1461  	e.buf = append(e.buf, ']')
  1462  	return e
  1463  }
  1464  
  1465  // Byte adds the field key with val as a byte to the entry.
  1466  func (e *Entry) Byte(key string, val byte) *Entry {
  1467  	if e == nil {
  1468  		return nil
  1469  	}
  1470  	e.buf = append(e.buf, ',', '"')
  1471  	e.buf = append(e.buf, key...)
  1472  	e.buf = append(e.buf, '"', ':')
  1473  	switch val {
  1474  	case '"':
  1475  		e.buf = append(e.buf, "\"\\\"\""...)
  1476  	case '\\':
  1477  		e.buf = append(e.buf, "\"\\\\\""...)
  1478  	case '\n':
  1479  		e.buf = append(e.buf, "\"\\n\""...)
  1480  	case '\r':
  1481  		e.buf = append(e.buf, "\"\\r\""...)
  1482  	case '\t':
  1483  		e.buf = append(e.buf, "\"\\t\""...)
  1484  	case '\f':
  1485  		e.buf = append(e.buf, "\"\\u000c\""...)
  1486  	case '\b':
  1487  		e.buf = append(e.buf, "\"\\u0008\""...)
  1488  	case '<':
  1489  		e.buf = append(e.buf, "\"\\u003c\""...)
  1490  	case '\'':
  1491  		e.buf = append(e.buf, "\"\\u0027\""...)
  1492  	case 0:
  1493  		e.buf = append(e.buf, "\"\\u0000\""...)
  1494  	default:
  1495  		e.buf = append(e.buf, '"', val, '"')
  1496  	}
  1497  	return e
  1498  }
  1499  
  1500  // Bytes adds the field key with val as a string to the entry.
  1501  func (e *Entry) Bytes(key string, val []byte) *Entry {
  1502  	if e == nil {
  1503  		return nil
  1504  	}
  1505  	e.buf = append(e.buf, ',', '"')
  1506  	e.buf = append(e.buf, key...)
  1507  	e.buf = append(e.buf, '"', ':', '"')
  1508  	e.bytes(val)
  1509  	e.buf = append(e.buf, '"')
  1510  	return e
  1511  }
  1512  
  1513  // BytesOrNil adds the field key with val as a string or nil to the entry.
  1514  func (e *Entry) BytesOrNil(key string, val []byte) *Entry {
  1515  	if e == nil {
  1516  		return nil
  1517  	}
  1518  	e.buf = append(e.buf, ',', '"')
  1519  	e.buf = append(e.buf, key...)
  1520  	e.buf = append(e.buf, '"', ':')
  1521  	if val == nil {
  1522  		e.buf = append(e.buf, "null"...)
  1523  	} else {
  1524  		e.buf = append(e.buf, '"')
  1525  		e.bytes(val)
  1526  		e.buf = append(e.buf, '"')
  1527  	}
  1528  	return e
  1529  }
  1530  
  1531  const hex = "0123456789abcdef"
  1532  
  1533  // Hex adds the field key with val as a hex string to the entry.
  1534  func (e *Entry) Hex(key string, val []byte) *Entry {
  1535  	if e == nil {
  1536  		return nil
  1537  	}
  1538  	e.buf = append(e.buf, ',', '"')
  1539  	e.buf = append(e.buf, key...)
  1540  	e.buf = append(e.buf, '"', ':', '"')
  1541  	for _, v := range val {
  1542  		e.buf = append(e.buf, hex[v>>4], hex[v&0x0f])
  1543  	}
  1544  	e.buf = append(e.buf, '"')
  1545  	return e
  1546  }
  1547  
  1548  // Encode encodes bytes using enc.AppendEncode to the entry.
  1549  func (e *Entry) Encode(key string, val []byte, enc interface {
  1550  	AppendEncode(dst, src []byte) []byte
  1551  }) *Entry {
  1552  	if e == nil {
  1553  		return nil
  1554  	}
  1555  	e.buf = append(e.buf, ',', '"')
  1556  	e.buf = append(e.buf, key...)
  1557  	e.buf = append(e.buf, '"', ':', '"')
  1558  	e.buf = enc.AppendEncode(e.buf, val)
  1559  	e.buf = append(e.buf, '"')
  1560  	return e
  1561  }
  1562  
  1563  // Xid adds the field key with xid.ID as a base32 string to the entry.
  1564  func (e *Entry) Xid(key string, xid [12]byte) *Entry {
  1565  	if e == nil {
  1566  		return nil
  1567  	}
  1568  	e.buf = append(e.buf, ',', '"')
  1569  	e.buf = append(e.buf, key...)
  1570  	e.buf = append(e.buf, '"', ':', '"')
  1571  	e.buf = append(e.buf, (XID(xid)).String()...)
  1572  	e.buf = append(e.buf, '"')
  1573  
  1574  	return e
  1575  }
  1576  
  1577  // IPAddr adds IPv4 or IPv6 Address to the entry.
  1578  func (e *Entry) IPAddr(key string, ip net.IP) *Entry {
  1579  	if e == nil {
  1580  		return nil
  1581  	}
  1582  	e.buf = append(e.buf, ',', '"')
  1583  	e.buf = append(e.buf, key...)
  1584  	e.buf = append(e.buf, '"', ':', '"')
  1585  	if ip4 := ip.To4(); ip4 != nil {
  1586  		_ = ip4[3]
  1587  		e.buf = strconv.AppendInt(e.buf, int64(ip4[0]), 10)
  1588  		e.buf = append(e.buf, '.')
  1589  		e.buf = strconv.AppendInt(e.buf, int64(ip4[1]), 10)
  1590  		e.buf = append(e.buf, '.')
  1591  		e.buf = strconv.AppendInt(e.buf, int64(ip4[2]), 10)
  1592  		e.buf = append(e.buf, '.')
  1593  		e.buf = strconv.AppendInt(e.buf, int64(ip4[3]), 10)
  1594  	} else if a, ok := netip.AddrFromSlice(ip); ok {
  1595  		e.buf = a.AppendTo(e.buf)
  1596  	}
  1597  	e.buf = append(e.buf, '"')
  1598  	return e
  1599  }
  1600  
  1601  // IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the entry.
  1602  func (e *Entry) IPPrefix(key string, pfx net.IPNet) *Entry {
  1603  	if e == nil {
  1604  		return nil
  1605  	}
  1606  	e.buf = append(e.buf, ',', '"')
  1607  	e.buf = append(e.buf, key...)
  1608  	e.buf = append(e.buf, '"', ':', '"')
  1609  	e.buf = append(e.buf, pfx.String()...)
  1610  	e.buf = append(e.buf, '"')
  1611  	return e
  1612  }
  1613  
  1614  // MACAddr adds MAC address to the entry.
  1615  func (e *Entry) MACAddr(key string, ha net.HardwareAddr) *Entry {
  1616  	if e == nil {
  1617  		return nil
  1618  	}
  1619  	e.buf = append(e.buf, ',', '"')
  1620  	e.buf = append(e.buf, key...)
  1621  	e.buf = append(e.buf, '"', ':', '"')
  1622  	for i, c := range ha {
  1623  		if i > 0 {
  1624  			e.buf = append(e.buf, ':')
  1625  		}
  1626  		e.buf = append(e.buf, hex[c>>4])
  1627  		e.buf = append(e.buf, hex[c&0xF])
  1628  	}
  1629  	e.buf = append(e.buf, '"')
  1630  	return e
  1631  }
  1632  
  1633  // NetIPAddr adds IPv4 or IPv6 Address to the entry.
  1634  func (e *Entry) NetIPAddr(key string, ip netip.Addr) *Entry {
  1635  	if e == nil {
  1636  		return nil
  1637  	}
  1638  	e.buf = append(e.buf, ',', '"')
  1639  	e.buf = append(e.buf, key...)
  1640  	e.buf = append(e.buf, '"', ':', '"')
  1641  	e.buf = ip.AppendTo(e.buf)
  1642  	e.buf = append(e.buf, '"')
  1643  	return e
  1644  }
  1645  
  1646  // NetIPAddrPort adds IPv4 or IPv6 with Port Address to the entry.
  1647  func (e *Entry) NetIPAddrPort(key string, ipPort netip.AddrPort) *Entry {
  1648  	if e == nil {
  1649  		return nil
  1650  	}
  1651  	e.buf = append(e.buf, ',', '"')
  1652  	e.buf = append(e.buf, key...)
  1653  	e.buf = append(e.buf, '"', ':', '"')
  1654  	e.buf = ipPort.AppendTo(e.buf)
  1655  	e.buf = append(e.buf, '"')
  1656  	return e
  1657  }
  1658  
  1659  // NetIPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the entry.
  1660  func (e *Entry) NetIPPrefix(key string, pfx netip.Prefix) *Entry {
  1661  	if e == nil {
  1662  		return nil
  1663  	}
  1664  	e.buf = append(e.buf, ',', '"')
  1665  	e.buf = append(e.buf, key...)
  1666  	e.buf = append(e.buf, '"', ':', '"')
  1667  	e.buf = pfx.AppendTo(e.buf)
  1668  	e.buf = append(e.buf, '"')
  1669  	return e
  1670  }
  1671  
  1672  // Type adds type of the key using reflection to the entry.
  1673  func (e *Entry) Type(key string, v any) *Entry {
  1674  	if e == nil {
  1675  		return nil
  1676  	}
  1677  	e.buf = append(e.buf, ',', '"')
  1678  	e.buf = append(e.buf, key...)
  1679  	e.buf = append(e.buf, '"', ':', '"')
  1680  	e.buf = append(e.buf, reflect.TypeOf(v).String()...)
  1681  	e.buf = append(e.buf, '"')
  1682  	return e
  1683  }
  1684  
  1685  // Caller adds the file:line of the "caller" key.
  1686  // If depth is negative, adds the full /path/to/file:line of the "caller" key.
  1687  func (e *Entry) Caller(depth int) *Entry {
  1688  	if e != nil {
  1689  		var full bool
  1690  		var pc uintptr
  1691  		if depth < 0 {
  1692  			depth, full = -depth, true
  1693  		}
  1694  		e.caller(caller1(depth, &pc, 1, 1), pc, full)
  1695  	}
  1696  	return e
  1697  }
  1698  
  1699  // Stack enables stack trace printing for the error passed to Err().
  1700  func (e *Entry) Stack() *Entry {
  1701  	if e != nil {
  1702  		e.buf = append(e.buf, ",\"stack\":\""...)
  1703  		e.bytes(stacks(false))
  1704  		e.buf = append(e.buf, '"')
  1705  	}
  1706  	return e
  1707  }
  1708  
  1709  // Enabled return false if the entry is going to be filtered out by log level.
  1710  func (e *Entry) Enabled() bool {
  1711  	return e != nil
  1712  }
  1713  
  1714  // Discard disables the entry so Msg(f) won't print it.
  1715  func (e *Entry) Discard() *Entry {
  1716  	if e == nil {
  1717  		return e
  1718  	}
  1719  	if cap(e.buf) <= bbcap {
  1720  		epool.Put(e)
  1721  	}
  1722  	return nil
  1723  }
  1724  
  1725  var notTest = true
  1726  
  1727  // Msg sends the entry with msg added as the message field if not empty.
  1728  func (e *Entry) Msg(msg string) {
  1729  	if e == nil {
  1730  		return
  1731  	}
  1732  	if msg != "" {
  1733  		e.buf = append(e.buf, ",\"message\":\""...)
  1734  		e.string(msg)
  1735  		e.buf = append(e.buf, "\"}\n"...)
  1736  	} else {
  1737  		e.buf = append(e.buf, '}', '\n')
  1738  	}
  1739  	_, _ = e.w.WriteEntry(e)
  1740  	if (e.Level == FatalLevel) && notTest {
  1741  		os.Exit(255)
  1742  	}
  1743  	if (e.Level == PanicLevel) && notTest {
  1744  		panic(msg)
  1745  	}
  1746  	if cap(e.buf) <= bbcap {
  1747  		epool.Put(e)
  1748  	}
  1749  }
  1750  
  1751  type bb struct {
  1752  	B []byte
  1753  }
  1754  
  1755  func (b *bb) Write(p []byte) (int, error) {
  1756  	b.B = append(b.B, p...)
  1757  	return len(p), nil
  1758  }
  1759  
  1760  var bbpool = sync.Pool{
  1761  	New: func() any {
  1762  		return new(bb)
  1763  	},
  1764  }
  1765  
  1766  // Msgf sends the entry with formatted msg added as the message field if not empty.
  1767  func (e *Entry) Msgf(format string, v ...any) {
  1768  	if e == nil {
  1769  		return
  1770  	}
  1771  	b := bbpool.Get().(*bb)
  1772  	b.B = b.B[:0]
  1773  	e.buf = append(e.buf, ",\"message\":\""...)
  1774  	fmt.Fprintf(b, format, v...)
  1775  	e.bytes(b.B)
  1776  	e.buf = append(e.buf, '"')
  1777  	if cap(b.B) <= bbcap {
  1778  		bbpool.Put(b)
  1779  	}
  1780  	e.Msg("")
  1781  }
  1782  
  1783  // Msgs sends the entry with msgs added as the message field if not empty.
  1784  func (e *Entry) Msgs(args ...any) {
  1785  	if e == nil {
  1786  		return
  1787  	}
  1788  	b := bbpool.Get().(*bb)
  1789  	b.B = b.B[:0]
  1790  	e.buf = append(e.buf, ",\"message\":\""...)
  1791  	fmt.Fprint(b, args...)
  1792  	e.bytes(b.B)
  1793  	e.buf = append(e.buf, '"')
  1794  	if cap(b.B) <= bbcap {
  1795  		bbpool.Put(b)
  1796  	}
  1797  	e.Msg("")
  1798  }
  1799  
  1800  func (e *Entry) caller(n int, pc uintptr, fullpath bool) {
  1801  	if n < 1 {
  1802  		return
  1803  	}
  1804  
  1805  	file, line := pcFileLine(pc)
  1806  	if !fullpath {
  1807  		var i, j int
  1808  		for i = len(file) - 1; i >= 0; i-- {
  1809  			if file[i] == '/' {
  1810  				break
  1811  			}
  1812  		}
  1813  		if i > 0 {
  1814  			for j = i - 1; j >= 0; j-- {
  1815  				if file[j] == '/' {
  1816  					break
  1817  				}
  1818  			}
  1819  			if j > 0 {
  1820  				i = j
  1821  			}
  1822  			file = file[i+1:]
  1823  		}
  1824  	}
  1825  
  1826  	e.buf = append(e.buf, ",\"caller\":\""...)
  1827  	e.buf = append(e.buf, file...)
  1828  	e.buf = append(e.buf, ':')
  1829  	e.buf = strconv.AppendInt(e.buf, int64(line), 10)
  1830  	e.buf = append(e.buf, "\",\"goid\":"...)
  1831  	e.buf = strconv.AppendInt(e.buf, int64(goid()), 10)
  1832  }
  1833  
  1834  var escapes = [256]bool{
  1835  	'"':  true,
  1836  	'<':  true,
  1837  	'\'': true,
  1838  	'\\': true,
  1839  	'\b': true,
  1840  	'\f': true,
  1841  	'\n': true,
  1842  	'\r': true,
  1843  	'\t': true,
  1844  }
  1845  
  1846  func (e *Entry) escapeb(b []byte) {
  1847  	n := len(b)
  1848  	j := 0
  1849  	if n > 0 {
  1850  		// Hint the compiler to remove bounds checks in the loop below.
  1851  		_ = b[n-1]
  1852  	}
  1853  	for i := 0; i < n; i++ {
  1854  		switch b[i] {
  1855  		case '"':
  1856  			e.buf = append(e.buf, b[j:i]...)
  1857  			e.buf = append(e.buf, '\\', '"')
  1858  			j = i + 1
  1859  		case '\\':
  1860  			e.buf = append(e.buf, b[j:i]...)
  1861  			e.buf = append(e.buf, '\\', '\\')
  1862  			j = i + 1
  1863  		case '\n':
  1864  			e.buf = append(e.buf, b[j:i]...)
  1865  			e.buf = append(e.buf, '\\', 'n')
  1866  			j = i + 1
  1867  		case '\r':
  1868  			e.buf = append(e.buf, b[j:i]...)
  1869  			e.buf = append(e.buf, '\\', 'r')
  1870  			j = i + 1
  1871  		case '\t':
  1872  			e.buf = append(e.buf, b[j:i]...)
  1873  			e.buf = append(e.buf, '\\', 't')
  1874  			j = i + 1
  1875  		case '\f':
  1876  			e.buf = append(e.buf, b[j:i]...)
  1877  			e.buf = append(e.buf, '\\', 'u', '0', '0', '0', 'c')
  1878  			j = i + 1
  1879  		case '\b':
  1880  			e.buf = append(e.buf, b[j:i]...)
  1881  			e.buf = append(e.buf, '\\', 'u', '0', '0', '0', '8')
  1882  			j = i + 1
  1883  		case '<':
  1884  			e.buf = append(e.buf, b[j:i]...)
  1885  			e.buf = append(e.buf, '\\', 'u', '0', '0', '3', 'c')
  1886  			j = i + 1
  1887  		case '\'':
  1888  			e.buf = append(e.buf, b[j:i]...)
  1889  			e.buf = append(e.buf, '\\', 'u', '0', '0', '2', '7')
  1890  			j = i + 1
  1891  		case 0:
  1892  			e.buf = append(e.buf, b[j:i]...)
  1893  			e.buf = append(e.buf, '\\', 'u', '0', '0', '0', '0')
  1894  			j = i + 1
  1895  		}
  1896  	}
  1897  	e.buf = append(e.buf, b[j:]...)
  1898  }
  1899  
  1900  func (e *Entry) escapes(s string) {
  1901  	n := len(s)
  1902  	j := 0
  1903  	if n > 0 {
  1904  		// Hint the compiler to remove bounds checks in the loop below.
  1905  		_ = s[n-1]
  1906  	}
  1907  	for i := 0; i < n; i++ {
  1908  		switch s[i] {
  1909  		case '"':
  1910  			e.buf = append(e.buf, s[j:i]...)
  1911  			e.buf = append(e.buf, '\\', '"')
  1912  			j = i + 1
  1913  		case '\\':
  1914  			e.buf = append(e.buf, s[j:i]...)
  1915  			e.buf = append(e.buf, '\\', '\\')
  1916  			j = i + 1
  1917  		case '\n':
  1918  			e.buf = append(e.buf, s[j:i]...)
  1919  			e.buf = append(e.buf, '\\', 'n')
  1920  			j = i + 1
  1921  		case '\r':
  1922  			e.buf = append(e.buf, s[j:i]...)
  1923  			e.buf = append(e.buf, '\\', 'r')
  1924  			j = i + 1
  1925  		case '\t':
  1926  			e.buf = append(e.buf, s[j:i]...)
  1927  			e.buf = append(e.buf, '\\', 't')
  1928  			j = i + 1
  1929  		case '\f':
  1930  			e.buf = append(e.buf, s[j:i]...)
  1931  			e.buf = append(e.buf, '\\', 'u', '0', '0', '0', 'c')
  1932  			j = i + 1
  1933  		case '\b':
  1934  			e.buf = append(e.buf, s[j:i]...)
  1935  			e.buf = append(e.buf, '\\', 'u', '0', '0', '0', '8')
  1936  			j = i + 1
  1937  		case '<':
  1938  			e.buf = append(e.buf, s[j:i]...)
  1939  			e.buf = append(e.buf, '\\', 'u', '0', '0', '3', 'c')
  1940  			j = i + 1
  1941  		case '\'':
  1942  			e.buf = append(e.buf, s[j:i]...)
  1943  			e.buf = append(e.buf, '\\', 'u', '0', '0', '2', '7')
  1944  			j = i + 1
  1945  		case 0:
  1946  			e.buf = append(e.buf, s[j:i]...)
  1947  			e.buf = append(e.buf, '\\', 'u', '0', '0', '0', '0')
  1948  			j = i + 1
  1949  		}
  1950  	}
  1951  	e.buf = append(e.buf, s[j:]...)
  1952  }
  1953  
  1954  func (e *Entry) string(s string) {
  1955  	for _, c := range []byte(s) {
  1956  		if escapes[c] {
  1957  			e.escapes(s)
  1958  			return
  1959  		}
  1960  	}
  1961  	e.buf = append(e.buf, s...)
  1962  }
  1963  
  1964  func (e *Entry) bytes(b []byte) {
  1965  	for _, c := range b {
  1966  		if escapes[c] {
  1967  			e.escapeb(b)
  1968  			return
  1969  		}
  1970  	}
  1971  	e.buf = append(e.buf, b...)
  1972  }
  1973  
  1974  // Interface adds the field key with i marshaled using reflection.
  1975  func (e *Entry) Interface(key string, i any) *Entry {
  1976  	if e == nil {
  1977  		return nil
  1978  	}
  1979  
  1980  	if o, ok := i.(ObjectMarshaler); ok {
  1981  		return e.Object(key, o)
  1982  	}
  1983  
  1984  	e.buf = append(e.buf, ',', '"')
  1985  	e.buf = append(e.buf, key...)
  1986  	e.buf = append(e.buf, '"', ':')
  1987  	b := bbpool.Get().(*bb)
  1988  	b.B = b.B[:0]
  1989  	enc := json.NewEncoder(b)
  1990  	enc.SetEscapeHTML(false)
  1991  	err := enc.Encode(i)
  1992  	if err != nil {
  1993  		b.B = b.B[:0]
  1994  		fmt.Fprintf(b, `marshaling error: %+v`, err)
  1995  		e.buf = append(e.buf, '"')
  1996  		e.bytes(b.B)
  1997  		e.buf = append(e.buf, '"')
  1998  	} else {
  1999  		b.B = b.B[:len(b.B)-1]
  2000  		e.buf = append(e.buf, b.B...)
  2001  	}
  2002  
  2003  	return e
  2004  }
  2005  
  2006  // Object marshals an object that implement the ObjectMarshaler interface.
  2007  func (e *Entry) Object(key string, obj ObjectMarshaler) *Entry {
  2008  	if e == nil {
  2009  		return nil
  2010  	}
  2011  
  2012  	e.buf = append(e.buf, ',', '"')
  2013  	e.buf = append(e.buf, key...)
  2014  	e.buf = append(e.buf, '"', ':')
  2015  	if obj == nil || (*[2]uintptr)(unsafe.Pointer(&obj))[1] == 0 {
  2016  		e.buf = append(e.buf, "null"...)
  2017  		return e
  2018  	}
  2019  
  2020  	n := len(e.buf)
  2021  	obj.MarshalObject(e)
  2022  	if n < len(e.buf) {
  2023  		e.buf[n] = '{'
  2024  		e.buf = append(e.buf, '}')
  2025  	} else {
  2026  		e.buf = append(e.buf, "null"...)
  2027  	}
  2028  
  2029  	return e
  2030  }
  2031  
  2032  // Objects marshals a slice of objects that implement the ObjectMarshaler interface.
  2033  func (e *Entry) Objects(key string, objects any) *Entry {
  2034  	if e == nil {
  2035  		return nil
  2036  	}
  2037  	values := reflect.ValueOf(objects)
  2038  	if values.Kind() != reflect.Slice {
  2039  		e.buf = append(e.buf, ',', '"')
  2040  		e.buf = append(e.buf, key...)
  2041  		e.buf = append(e.buf, `":null`...)
  2042  		return e
  2043  	}
  2044  
  2045  	e.buf = append(e.buf, ',', '"')
  2046  	e.buf = append(e.buf, key...)
  2047  	e.buf = append(e.buf, '"', ':', '[')
  2048  	for i := 0; i < values.Len(); i++ {
  2049  		if i != 0 {
  2050  			e.buf = append(e.buf, ',')
  2051  		}
  2052  		value := values.Index(i)
  2053  		if value.Kind() == reflect.Ptr && value.IsNil() {
  2054  			e.buf = append(e.buf, "null"...)
  2055  		} else if obj, ok := value.Interface().(ObjectMarshaler); ok {
  2056  			i := len(e.buf)
  2057  			obj.MarshalObject(e)
  2058  			e.buf[i] = '{'
  2059  			e.buf = append(e.buf, '}')
  2060  		} else {
  2061  			e.buf = append(e.buf, `null`...)
  2062  		}
  2063  	}
  2064  	e.buf = append(e.buf, ']')
  2065  	return e
  2066  }
  2067  
  2068  // Func allows an anonymous func to run only if the entry is enabled.
  2069  func (e *Entry) Func(f func(e *Entry)) *Entry {
  2070  	if e != nil {
  2071  		f(e)
  2072  	}
  2073  	return e
  2074  }
  2075  
  2076  // EmbedObject marshals and Embeds an object that implement the ObjectMarshaler interface.
  2077  func (e *Entry) EmbedObject(obj ObjectMarshaler) *Entry {
  2078  	if e == nil {
  2079  		return nil
  2080  	}
  2081  
  2082  	if obj != nil && (*[2]uintptr)(unsafe.Pointer(&obj))[1] != 0 {
  2083  		obj.MarshalObject(e)
  2084  	}
  2085  	return e
  2086  }
  2087  
  2088  // Any adds the field key with f as an any value to the entry.
  2089  func (e *Entry) Any(key string, value any) *Entry {
  2090  	if value == nil || (*[2]uintptr)(unsafe.Pointer(&value))[1] == 0 {
  2091  		e.buf = append(e.buf, ',', '"')
  2092  		e.buf = append(e.buf, key...)
  2093  		e.buf = append(e.buf, '"', ':')
  2094  		e.buf = append(e.buf, "null"...)
  2095  		return e
  2096  	}
  2097  	switch value := value.(type) {
  2098  	case ObjectMarshaler:
  2099  		e.buf = append(e.buf, ',', '"')
  2100  		e.buf = append(e.buf, key...)
  2101  		e.buf = append(e.buf, '"', ':')
  2102  		value.MarshalObject(e)
  2103  	case Context:
  2104  		e.Dict(key, value)
  2105  	case []time.Duration:
  2106  		e.Durs(key, value)
  2107  	case time.Duration:
  2108  		e.Dur(key, value)
  2109  	case time.Time:
  2110  		e.Time(key, value)
  2111  	case net.HardwareAddr:
  2112  		e.MACAddr(key, value)
  2113  	case net.IP:
  2114  		e.IPAddr(key, value)
  2115  	case net.IPNet:
  2116  		e.IPPrefix(key, value)
  2117  	case json.RawMessage:
  2118  		e.buf = append(e.buf, ',', '"')
  2119  		e.buf = append(e.buf, key...)
  2120  		e.buf = append(e.buf, '"', ':')
  2121  		e.buf = append(e.buf, value...)
  2122  	case []bool:
  2123  		e.Bools(key, value)
  2124  	case []byte:
  2125  		e.Bytes(key, value)
  2126  	case []error:
  2127  		e.Errs(key, value)
  2128  	case []float32:
  2129  		e.Floats32(key, value)
  2130  	case []float64:
  2131  		e.Floats64(key, value)
  2132  	case []string:
  2133  		e.Strs(key, value)
  2134  	case string:
  2135  		e.Str(key, value)
  2136  	case bool:
  2137  		e.Bool(key, value)
  2138  	case error:
  2139  		e.AnErr(key, value)
  2140  	case float32:
  2141  		e.Float32(key, value)
  2142  	case float64:
  2143  		e.Float64(key, value)
  2144  	case int16:
  2145  		e.Int16(key, value)
  2146  	case int32:
  2147  		e.Int32(key, value)
  2148  	case int64:
  2149  		e.Int64(key, value)
  2150  	case int8:
  2151  		e.Int8(key, value)
  2152  	case int:
  2153  		e.Int(key, value)
  2154  	case uint16:
  2155  		e.Uint16(key, value)
  2156  	case uint32:
  2157  		e.Uint32(key, value)
  2158  	case uint64:
  2159  		e.Uint64(key, value)
  2160  	case uint8:
  2161  		e.Uint8(key, value)
  2162  	case fmt.GoStringer:
  2163  		e.GoStringer(key, value)
  2164  	case fmt.Stringer:
  2165  		e.Stringer(key, value)
  2166  	default:
  2167  		e.buf = append(e.buf, ',', '"')
  2168  		e.buf = append(e.buf, key...)
  2169  		e.buf = append(e.buf, '"', ':')
  2170  		b := bbpool.Get().(*bb)
  2171  		b.B = b.B[:0]
  2172  		enc := json.NewEncoder(b)
  2173  		enc.SetEscapeHTML(false)
  2174  		err := enc.Encode(value)
  2175  		if err != nil {
  2176  			b.B = b.B[:0]
  2177  			fmt.Fprintf(b, `marshaling error: %+v`, err)
  2178  			e.buf = append(e.buf, '"')
  2179  			e.bytes(b.B)
  2180  			e.buf = append(e.buf, '"')
  2181  		} else {
  2182  			b.B = b.B[:len(b.B)-1]
  2183  			e.buf = append(e.buf, b.B...)
  2184  		}
  2185  		if cap(b.B) <= bbcap {
  2186  			bbpool.Put(b)
  2187  		}
  2188  	}
  2189  	return e
  2190  }
  2191  
  2192  // KeysAndValues sends keysAndValues to Entry
  2193  func (e *Entry) KeysAndValues(keysAndValues ...any) *Entry {
  2194  	if e == nil {
  2195  		return nil
  2196  	}
  2197  	var key string
  2198  	for i, v := range keysAndValues {
  2199  		if i%2 == 0 {
  2200  			key, _ = v.(string)
  2201  			continue
  2202  		}
  2203  		e.Any(key, v)
  2204  	}
  2205  	return e
  2206  }
  2207  
  2208  // Fields type, used to pass to `Fields`.
  2209  type Fields map[string]any
  2210  
  2211  // Fields is a helper function to use a map to set fields using type assertion.
  2212  func (e *Entry) Fields(fields Fields) *Entry {
  2213  	if e == nil {
  2214  		return nil
  2215  	}
  2216  	for key, value := range fields {
  2217  		e.Any(key, value)
  2218  	}
  2219  	return e
  2220  }
  2221  
  2222  // Context represents contextual fields.
  2223  type Context []byte
  2224  
  2225  // NewContext starts a new contextual entry.
  2226  func NewContext(dst []byte) (e *Entry) {
  2227  	e = new(Entry)
  2228  	e.buf = dst
  2229  	return
  2230  }
  2231  
  2232  // Value builds the contextual fields.
  2233  func (e *Entry) Value() Context {
  2234  	if e == nil {
  2235  		return nil
  2236  	}
  2237  	return e.buf
  2238  }
  2239  
  2240  // Context sends the contextual fields to entry.
  2241  func (e *Entry) Context(ctx Context) *Entry {
  2242  	if e == nil {
  2243  		return nil
  2244  	}
  2245  	if len(ctx) != 0 {
  2246  		e.buf = append(e.buf, ctx...)
  2247  	}
  2248  	return e
  2249  }
  2250  
  2251  // Dict sends the contextual fields with key to entry.
  2252  func (e *Entry) Dict(key string, ctx Context) *Entry {
  2253  	if e == nil {
  2254  		return nil
  2255  	}
  2256  	e.buf = append(e.buf, ',', '"')
  2257  	e.buf = append(e.buf, key...)
  2258  	e.buf = append(e.buf, '"', ':', '{')
  2259  	if len(ctx) > 0 {
  2260  		e.buf = append(e.buf, ctx[1:]...)
  2261  	}
  2262  	e.buf = append(e.buf, '}')
  2263  	return e
  2264  }
  2265  
  2266  // stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
  2267  func stacks(all bool) (trace []byte) {
  2268  	// We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
  2269  	n := 10000
  2270  	if all {
  2271  		n = 100000
  2272  	}
  2273  	for i := 0; i < 5; i++ {
  2274  		trace = make([]byte, n)
  2275  		nbytes := runtime.Stack(trace, all)
  2276  		if nbytes < len(trace) {
  2277  			trace = trace[:nbytes]
  2278  			break
  2279  		}
  2280  		n *= 2
  2281  	}
  2282  	return
  2283  }
  2284  
  2285  // wlprintf is a helper function for tests
  2286  func wlprintf(w Writer, level Level, format string, args ...any) (int, error) {
  2287  	return w.WriteEntry(&Entry{
  2288  		Level: level,
  2289  		buf:   []byte(fmt.Sprintf(format, args...)),
  2290  	})
  2291  }
  2292  
  2293  func b2s(b []byte) string { return *(*string)(unsafe.Pointer(&b)) }
  2294  
  2295  //go:noescape
  2296  //go:linkname now time.now
  2297  func now() (sec int64, nsec int32, mono int64)
  2298  
  2299  //go:noescape
  2300  //go:linkname absDate time.absDate
  2301  func absDate(abs uint64, full bool) (year int, month time.Month, day int, yday int)
  2302  
  2303  //go:noescape
  2304  //go:linkname absClock time.absClock
  2305  func absClock(abs uint64) (hour, min, sec int)
  2306  
  2307  //go:noescape
  2308  //go:linkname caller1 runtime.callers
  2309  func caller1(skip int, pc *uintptr, len, cap int) int