...

Source file src/github.com/rs/zerolog/context.go

Documentation: github.com/rs/zerolog

     1  package zerolog
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"math"
     7  	"net"
     8  	"time"
     9  )
    10  
    11  // Context configures a new sub-logger with contextual fields.
    12  type Context struct {
    13  	l Logger
    14  }
    15  
    16  // Logger returns the logger with the context previously set.
    17  func (c Context) Logger() Logger {
    18  	return c.l
    19  }
    20  
    21  // Fields is a helper function to use a map or slice to set fields using type assertion.
    22  // Only map[string]interface{} and []interface{} are accepted. []interface{} must
    23  // alternate string keys and arbitrary values, and extraneous ones are ignored.
    24  func (c Context) Fields(fields interface{}) Context {
    25  	c.l.context = appendFields(c.l.context, fields)
    26  	return c
    27  }
    28  
    29  // Dict adds the field key with the dict to the logger context.
    30  func (c Context) Dict(key string, dict *Event) Context {
    31  	dict.buf = enc.AppendEndMarker(dict.buf)
    32  	c.l.context = append(enc.AppendKey(c.l.context, key), dict.buf...)
    33  	putEvent(dict)
    34  	return c
    35  }
    36  
    37  // Array adds the field key with an array to the event context.
    38  // Use zerolog.Arr() to create the array or pass a type that
    39  // implement the LogArrayMarshaler interface.
    40  func (c Context) Array(key string, arr LogArrayMarshaler) Context {
    41  	c.l.context = enc.AppendKey(c.l.context, key)
    42  	if arr, ok := arr.(*Array); ok {
    43  		c.l.context = arr.write(c.l.context)
    44  		return c
    45  	}
    46  	var a *Array
    47  	if aa, ok := arr.(*Array); ok {
    48  		a = aa
    49  	} else {
    50  		a = Arr()
    51  		arr.MarshalZerologArray(a)
    52  	}
    53  	c.l.context = a.write(c.l.context)
    54  	return c
    55  }
    56  
    57  // Object marshals an object that implement the LogObjectMarshaler interface.
    58  func (c Context) Object(key string, obj LogObjectMarshaler) Context {
    59  	e := newEvent(levelWriterAdapter{ioutil.Discard}, 0)
    60  	e.Object(key, obj)
    61  	c.l.context = enc.AppendObjectData(c.l.context, e.buf)
    62  	putEvent(e)
    63  	return c
    64  }
    65  
    66  // EmbedObject marshals and Embeds an object that implement the LogObjectMarshaler interface.
    67  func (c Context) EmbedObject(obj LogObjectMarshaler) Context {
    68  	e := newEvent(levelWriterAdapter{ioutil.Discard}, 0)
    69  	e.EmbedObject(obj)
    70  	c.l.context = enc.AppendObjectData(c.l.context, e.buf)
    71  	putEvent(e)
    72  	return c
    73  }
    74  
    75  // Str adds the field key with val as a string to the logger context.
    76  func (c Context) Str(key, val string) Context {
    77  	c.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val)
    78  	return c
    79  }
    80  
    81  // Strs adds the field key with val as a string to the logger context.
    82  func (c Context) Strs(key string, vals []string) Context {
    83  	c.l.context = enc.AppendStrings(enc.AppendKey(c.l.context, key), vals)
    84  	return c
    85  }
    86  
    87  // Stringer adds the field key with val.String() (or null if val is nil) to the logger context.
    88  func (c Context) Stringer(key string, val fmt.Stringer) Context {
    89  	if val != nil {
    90  		c.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val.String())
    91  		return c
    92  	}
    93  
    94  	c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), nil)
    95  	return c
    96  }
    97  
    98  // Bytes adds the field key with val as a []byte to the logger context.
    99  func (c Context) Bytes(key string, val []byte) Context {
   100  	c.l.context = enc.AppendBytes(enc.AppendKey(c.l.context, key), val)
   101  	return c
   102  }
   103  
   104  // Hex adds the field key with val as a hex string to the logger context.
   105  func (c Context) Hex(key string, val []byte) Context {
   106  	c.l.context = enc.AppendHex(enc.AppendKey(c.l.context, key), val)
   107  	return c
   108  }
   109  
   110  // RawJSON adds already encoded JSON to context.
   111  //
   112  // No sanity check is performed on b; it must not contain carriage returns and
   113  // be valid JSON.
   114  func (c Context) RawJSON(key string, b []byte) Context {
   115  	c.l.context = appendJSON(enc.AppendKey(c.l.context, key), b)
   116  	return c
   117  }
   118  
   119  // AnErr adds the field key with serialized err to the logger context.
   120  func (c Context) AnErr(key string, err error) Context {
   121  	switch m := ErrorMarshalFunc(err).(type) {
   122  	case nil:
   123  		return c
   124  	case LogObjectMarshaler:
   125  		return c.Object(key, m)
   126  	case error:
   127  		if m == nil || isNilValue(m) {
   128  			return c
   129  		} else {
   130  			return c.Str(key, m.Error())
   131  		}
   132  	case string:
   133  		return c.Str(key, m)
   134  	default:
   135  		return c.Interface(key, m)
   136  	}
   137  }
   138  
   139  // Errs adds the field key with errs as an array of serialized errors to the
   140  // logger context.
   141  func (c Context) Errs(key string, errs []error) Context {
   142  	arr := Arr()
   143  	for _, err := range errs {
   144  		switch m := ErrorMarshalFunc(err).(type) {
   145  		case LogObjectMarshaler:
   146  			arr = arr.Object(m)
   147  		case error:
   148  			if m == nil || isNilValue(m) {
   149  				arr = arr.Interface(nil)
   150  			} else {
   151  				arr = arr.Str(m.Error())
   152  			}
   153  		case string:
   154  			arr = arr.Str(m)
   155  		default:
   156  			arr = arr.Interface(m)
   157  		}
   158  	}
   159  
   160  	return c.Array(key, arr)
   161  }
   162  
   163  // Err adds the field "error" with serialized err to the logger context.
   164  func (c Context) Err(err error) Context {
   165  	return c.AnErr(ErrorFieldName, err)
   166  }
   167  
   168  // Bool adds the field key with val as a bool to the logger context.
   169  func (c Context) Bool(key string, b bool) Context {
   170  	c.l.context = enc.AppendBool(enc.AppendKey(c.l.context, key), b)
   171  	return c
   172  }
   173  
   174  // Bools adds the field key with val as a []bool to the logger context.
   175  func (c Context) Bools(key string, b []bool) Context {
   176  	c.l.context = enc.AppendBools(enc.AppendKey(c.l.context, key), b)
   177  	return c
   178  }
   179  
   180  // Int adds the field key with i as a int to the logger context.
   181  func (c Context) Int(key string, i int) Context {
   182  	c.l.context = enc.AppendInt(enc.AppendKey(c.l.context, key), i)
   183  	return c
   184  }
   185  
   186  // Ints adds the field key with i as a []int to the logger context.
   187  func (c Context) Ints(key string, i []int) Context {
   188  	c.l.context = enc.AppendInts(enc.AppendKey(c.l.context, key), i)
   189  	return c
   190  }
   191  
   192  // Int8 adds the field key with i as a int8 to the logger context.
   193  func (c Context) Int8(key string, i int8) Context {
   194  	c.l.context = enc.AppendInt8(enc.AppendKey(c.l.context, key), i)
   195  	return c
   196  }
   197  
   198  // Ints8 adds the field key with i as a []int8 to the logger context.
   199  func (c Context) Ints8(key string, i []int8) Context {
   200  	c.l.context = enc.AppendInts8(enc.AppendKey(c.l.context, key), i)
   201  	return c
   202  }
   203  
   204  // Int16 adds the field key with i as a int16 to the logger context.
   205  func (c Context) Int16(key string, i int16) Context {
   206  	c.l.context = enc.AppendInt16(enc.AppendKey(c.l.context, key), i)
   207  	return c
   208  }
   209  
   210  // Ints16 adds the field key with i as a []int16 to the logger context.
   211  func (c Context) Ints16(key string, i []int16) Context {
   212  	c.l.context = enc.AppendInts16(enc.AppendKey(c.l.context, key), i)
   213  	return c
   214  }
   215  
   216  // Int32 adds the field key with i as a int32 to the logger context.
   217  func (c Context) Int32(key string, i int32) Context {
   218  	c.l.context = enc.AppendInt32(enc.AppendKey(c.l.context, key), i)
   219  	return c
   220  }
   221  
   222  // Ints32 adds the field key with i as a []int32 to the logger context.
   223  func (c Context) Ints32(key string, i []int32) Context {
   224  	c.l.context = enc.AppendInts32(enc.AppendKey(c.l.context, key), i)
   225  	return c
   226  }
   227  
   228  // Int64 adds the field key with i as a int64 to the logger context.
   229  func (c Context) Int64(key string, i int64) Context {
   230  	c.l.context = enc.AppendInt64(enc.AppendKey(c.l.context, key), i)
   231  	return c
   232  }
   233  
   234  // Ints64 adds the field key with i as a []int64 to the logger context.
   235  func (c Context) Ints64(key string, i []int64) Context {
   236  	c.l.context = enc.AppendInts64(enc.AppendKey(c.l.context, key), i)
   237  	return c
   238  }
   239  
   240  // Uint adds the field key with i as a uint to the logger context.
   241  func (c Context) Uint(key string, i uint) Context {
   242  	c.l.context = enc.AppendUint(enc.AppendKey(c.l.context, key), i)
   243  	return c
   244  }
   245  
   246  // Uints adds the field key with i as a []uint to the logger context.
   247  func (c Context) Uints(key string, i []uint) Context {
   248  	c.l.context = enc.AppendUints(enc.AppendKey(c.l.context, key), i)
   249  	return c
   250  }
   251  
   252  // Uint8 adds the field key with i as a uint8 to the logger context.
   253  func (c Context) Uint8(key string, i uint8) Context {
   254  	c.l.context = enc.AppendUint8(enc.AppendKey(c.l.context, key), i)
   255  	return c
   256  }
   257  
   258  // Uints8 adds the field key with i as a []uint8 to the logger context.
   259  func (c Context) Uints8(key string, i []uint8) Context {
   260  	c.l.context = enc.AppendUints8(enc.AppendKey(c.l.context, key), i)
   261  	return c
   262  }
   263  
   264  // Uint16 adds the field key with i as a uint16 to the logger context.
   265  func (c Context) Uint16(key string, i uint16) Context {
   266  	c.l.context = enc.AppendUint16(enc.AppendKey(c.l.context, key), i)
   267  	return c
   268  }
   269  
   270  // Uints16 adds the field key with i as a []uint16 to the logger context.
   271  func (c Context) Uints16(key string, i []uint16) Context {
   272  	c.l.context = enc.AppendUints16(enc.AppendKey(c.l.context, key), i)
   273  	return c
   274  }
   275  
   276  // Uint32 adds the field key with i as a uint32 to the logger context.
   277  func (c Context) Uint32(key string, i uint32) Context {
   278  	c.l.context = enc.AppendUint32(enc.AppendKey(c.l.context, key), i)
   279  	return c
   280  }
   281  
   282  // Uints32 adds the field key with i as a []uint32 to the logger context.
   283  func (c Context) Uints32(key string, i []uint32) Context {
   284  	c.l.context = enc.AppendUints32(enc.AppendKey(c.l.context, key), i)
   285  	return c
   286  }
   287  
   288  // Uint64 adds the field key with i as a uint64 to the logger context.
   289  func (c Context) Uint64(key string, i uint64) Context {
   290  	c.l.context = enc.AppendUint64(enc.AppendKey(c.l.context, key), i)
   291  	return c
   292  }
   293  
   294  // Uints64 adds the field key with i as a []uint64 to the logger context.
   295  func (c Context) Uints64(key string, i []uint64) Context {
   296  	c.l.context = enc.AppendUints64(enc.AppendKey(c.l.context, key), i)
   297  	return c
   298  }
   299  
   300  // Float32 adds the field key with f as a float32 to the logger context.
   301  func (c Context) Float32(key string, f float32) Context {
   302  	c.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f)
   303  	return c
   304  }
   305  
   306  // Floats32 adds the field key with f as a []float32 to the logger context.
   307  func (c Context) Floats32(key string, f []float32) Context {
   308  	c.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f)
   309  	return c
   310  }
   311  
   312  // Float64 adds the field key with f as a float64 to the logger context.
   313  func (c Context) Float64(key string, f float64) Context {
   314  	c.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f)
   315  	return c
   316  }
   317  
   318  // Floats64 adds the field key with f as a []float64 to the logger context.
   319  func (c Context) Floats64(key string, f []float64) Context {
   320  	c.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f)
   321  	return c
   322  }
   323  
   324  type timestampHook struct{}
   325  
   326  func (ts timestampHook) Run(e *Event, level Level, msg string) {
   327  	e.Timestamp()
   328  }
   329  
   330  var th = timestampHook{}
   331  
   332  // Timestamp adds the current local time as UNIX timestamp to the logger context with the "time" key.
   333  // To customize the key name, change zerolog.TimestampFieldName.
   334  //
   335  // NOTE: It won't dedupe the "time" key if the *Context has one already.
   336  func (c Context) Timestamp() Context {
   337  	c.l = c.l.Hook(th)
   338  	return c
   339  }
   340  
   341  // Time adds the field key with t formated as string using zerolog.TimeFieldFormat.
   342  func (c Context) Time(key string, t time.Time) Context {
   343  	c.l.context = enc.AppendTime(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
   344  	return c
   345  }
   346  
   347  // Times adds the field key with t formated as string using zerolog.TimeFieldFormat.
   348  func (c Context) Times(key string, t []time.Time) Context {
   349  	c.l.context = enc.AppendTimes(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
   350  	return c
   351  }
   352  
   353  // Dur adds the fields key with d divided by unit and stored as a float.
   354  func (c Context) Dur(key string, d time.Duration) Context {
   355  	c.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
   356  	return c
   357  }
   358  
   359  // Durs adds the fields key with d divided by unit and stored as a float.
   360  func (c Context) Durs(key string, d []time.Duration) Context {
   361  	c.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
   362  	return c
   363  }
   364  
   365  // Interface adds the field key with obj marshaled using reflection.
   366  func (c Context) Interface(key string, i interface{}) Context {
   367  	c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), i)
   368  	return c
   369  }
   370  
   371  type callerHook struct {
   372  	callerSkipFrameCount int
   373  }
   374  
   375  func newCallerHook(skipFrameCount int) callerHook {
   376  	return callerHook{callerSkipFrameCount: skipFrameCount}
   377  }
   378  
   379  func (ch callerHook) Run(e *Event, level Level, msg string) {
   380  	switch ch.callerSkipFrameCount {
   381  	case useGlobalSkipFrameCount:
   382  		// Extra frames to skip (added by hook infra).
   383  		e.caller(CallerSkipFrameCount + contextCallerSkipFrameCount)
   384  	default:
   385  		// Extra frames to skip (added by hook infra).
   386  		e.caller(ch.callerSkipFrameCount + contextCallerSkipFrameCount)
   387  	}
   388  }
   389  
   390  // useGlobalSkipFrameCount acts as a flag to informat callerHook.Run
   391  // to use the global CallerSkipFrameCount.
   392  const useGlobalSkipFrameCount = math.MinInt32
   393  
   394  // ch is the default caller hook using the global CallerSkipFrameCount.
   395  var ch = newCallerHook(useGlobalSkipFrameCount)
   396  
   397  // Caller adds the file:line of the caller with the zerolog.CallerFieldName key.
   398  func (c Context) Caller() Context {
   399  	c.l = c.l.Hook(ch)
   400  	return c
   401  }
   402  
   403  // CallerWithSkipFrameCount adds the file:line of the caller with the zerolog.CallerFieldName key.
   404  // The specified skipFrameCount int will override the global CallerSkipFrameCount for this context's respective logger.
   405  // If set to -1 the global CallerSkipFrameCount will be used.
   406  func (c Context) CallerWithSkipFrameCount(skipFrameCount int) Context {
   407  	c.l = c.l.Hook(newCallerHook(skipFrameCount))
   408  	return c
   409  }
   410  
   411  // Stack enables stack trace printing for the error passed to Err().
   412  func (c Context) Stack() Context {
   413  	c.l.stack = true
   414  	return c
   415  }
   416  
   417  // IPAddr adds IPv4 or IPv6 Address to the context
   418  func (c Context) IPAddr(key string, ip net.IP) Context {
   419  	c.l.context = enc.AppendIPAddr(enc.AppendKey(c.l.context, key), ip)
   420  	return c
   421  }
   422  
   423  // IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the context
   424  func (c Context) IPPrefix(key string, pfx net.IPNet) Context {
   425  	c.l.context = enc.AppendIPPrefix(enc.AppendKey(c.l.context, key), pfx)
   426  	return c
   427  }
   428  
   429  // MACAddr adds MAC address to the context
   430  func (c Context) MACAddr(key string, ha net.HardwareAddr) Context {
   431  	c.l.context = enc.AppendMACAddr(enc.AppendKey(c.l.context, key), ha)
   432  	return c
   433  }
   434  

View as plain text