encoder.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package core
  2. import (
  3. "time"
  4. )
  5. // DefaultLineEnding defines the default line ending when writing logs.
  6. // Alternate line endings specified in EncoderConfig can override this
  7. // behavior.
  8. const DefaultLineEnding = "\n"
  9. // ObjectEncoder is a strongly-typed, encoding-agnostic interface for adding a
  10. // map- or struct-like object to the logging context. Like maps, ObjectEncoders
  11. // aren't safe for concurrent use (though typical use shouldn't require locks).
  12. type ObjectEncoder interface {
  13. // Logging-specific marshalers.
  14. AddArray(key string, marshaler ArrayMarshaler) error
  15. AddObject(key string, marshaler ObjectMarshaler) error
  16. // Built-in types.
  17. AddBinary(key string, value []byte) // for arbitrary bytes
  18. AddByteString(key string, value []byte) // for UTF-8 encoded bytes
  19. AddBool(key string, value bool)
  20. AddComplex128(key string, value complex128)
  21. AddComplex64(key string, value complex64)
  22. AddDuration(key string, value time.Duration)
  23. AddFloat64(key string, value float64)
  24. AddFloat32(key string, value float32)
  25. AddInt(key string, value int)
  26. AddInt64(key string, value int64)
  27. AddInt32(key string, value int32)
  28. AddInt16(key string, value int16)
  29. AddInt8(key string, value int8)
  30. AddString(key, value string)
  31. AddTime(key string, value time.Time)
  32. AddUint(key string, value uint)
  33. AddUint64(key string, value uint64)
  34. AddUint32(key string, value uint32)
  35. AddUint16(key string, value uint16)
  36. AddUint8(key string, value uint8)
  37. AddUintptr(key string, value uintptr)
  38. // AddReflected uses reflection to serialize arbitrary objects, so it's slow
  39. // and allocation-heavy.
  40. AddReflected(key string, value interface{}) error
  41. // OpenNamespace opens an isolated namespace where all subsequent fields will
  42. // be added. Applications can use namespaces to prevent key collisions when
  43. // injecting loggers into sub-components or third-party libraries.
  44. OpenNamespace(key string)
  45. }
  46. // ObjectMarshaler allows user-defined types to efficiently add themselves to the
  47. // logging context, and to selectively omit information which shouldn't be
  48. // included in logs (e.g., passwords).
  49. type ObjectMarshaler interface {
  50. MarshalLogObject(ObjectEncoder) error
  51. }
  52. // ObjectMarshalerFunc is a type adapter that turns a function into an
  53. // ObjectMarshaler.
  54. type ObjectMarshalerFunc func(ObjectEncoder) error
  55. // MarshalLogObject calls the underlying function.
  56. func (f ObjectMarshalerFunc) MarshalLogObject(enc ObjectEncoder) error {
  57. return f(enc)
  58. }
  59. // ArrayMarshaler allows user-defined types to efficiently add themselves to the
  60. // logging context, and to selectively omit information which shouldn't be
  61. // included in logs (e.g., passwords).
  62. type ArrayMarshaler interface {
  63. MarshalLogArray(ArrayEncoder) error
  64. }
  65. // ArrayMarshalerFunc is a type adapter that turns a function into an
  66. // ArrayMarshaler.
  67. type ArrayMarshalerFunc func(ArrayEncoder) error
  68. // MarshalLogArray calls the underlying function.
  69. func (f ArrayMarshalerFunc) MarshalLogArray(enc ArrayEncoder) error {
  70. return f(enc)
  71. }
  72. // ArrayEncoder is a strongly-typed, encoding-agnostic interface for adding
  73. // array-like objects to the logging context. Of note, it supports mixed-type
  74. // arrays even though they aren't typical in Go. Like slices, ArrayEncoders
  75. // aren't safe for concurrent use (though typical use shouldn't require locks).
  76. type ArrayEncoder interface {
  77. // Built-in types.
  78. PrimitiveArrayEncoder
  79. // Time-related types.
  80. AppendDuration(time.Duration)
  81. AppendTime(time.Time)
  82. // Logging-specific marshalers.
  83. AppendArray(ArrayMarshaler) error
  84. AppendObject(ObjectMarshaler) error
  85. // AppendReflected uses reflection to serialize arbitrary objects, so it's
  86. // slow and allocation-heavy.
  87. AppendReflected(value interface{}) error
  88. }
  89. // PrimitiveArrayEncoder is the subset of the ArrayEncoder interface that deals
  90. // only in Go's built-in types. It's included only so that Duration- and
  91. // TimeEncoders cannot trigger infinite recursion.
  92. type PrimitiveArrayEncoder interface {
  93. // Built-in types.
  94. AppendBool(bool)
  95. AppendByteString([]byte) // for UTF-8 encoded bytes
  96. AppendComplex128(complex128)
  97. AppendComplex64(complex64)
  98. AppendFloat64(float64)
  99. AppendFloat32(float32)
  100. AppendInt(int)
  101. AppendInt64(int64)
  102. AppendInt32(int32)
  103. AppendInt16(int16)
  104. AppendInt8(int8)
  105. AppendString(string)
  106. AppendUint(uint)
  107. AppendUint64(uint64)
  108. AppendUint32(uint32)
  109. AppendUint16(uint16)
  110. AppendUint8(uint8)
  111. AppendUintptr(uintptr)
  112. }
  113. // An EncoderConfig allows users to configure the concrete encoders supplied by
  114. // zapcore.
  115. type EncoderConfig struct {
  116. EncodeTime TimeEncoder `json:"timeEncoder" yaml:"timeEncoder"`
  117. EncodeDuration DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
  118. // Configure the primitive representations of common complex types. For
  119. // example, some users may want all time.Times serialized as floating-point
  120. // seconds since epoch, while others may prefer ISO8601 strings.
  121. /*EncodeLevel LevelEncoder `json:"levelEncoder" yaml:"levelEncoder"`
  122. EncodeTime TimeEncoder `json:"timeEncoder" yaml:"timeEncoder"`
  123. EncodeDuration DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
  124. EncodeCaller CallerEncoder `json:"callerEncoder" yaml:"callerEncoder"`
  125. // Unlike the other primitive type encoders, EncodeName is optional. The
  126. // zero value falls back to FullNameEncoder.
  127. EncodeName NameEncoder `json:"nameEncoder" yaml:"nameEncoder"`*/
  128. }
  129. // Encoder is a format-agnostic interface for all log entry marshalers. Since
  130. // log encoders don't need to support the same wide range of use cases as
  131. // general-purpose marshalers, it's possible to make them faster and
  132. // lower-allocation.
  133. //
  134. // Implementations of the ObjectEncoder interface's methods can, of course,
  135. // freely modify the receiver. However, the Clone and EncodeEntry methods will
  136. // be called concurrently and shouldn't modify the receiver.
  137. type Encoder interface {
  138. ObjectEncoder
  139. // Clone copies the encoder, ensuring that adding fields to the copy doesn't
  140. // affect the original.
  141. Clone() Encoder
  142. // EncodeEntry encodes an entry and fields, along with any accumulated
  143. // context, into a byte buffer and returns it.
  144. Encode(*Buffer, ...Field) error
  145. }
  146. // A TimeEncoder serializes a time.Time to a primitive type.
  147. type TimeEncoder func(time.Time, PrimitiveArrayEncoder)
  148. // A DurationEncoder serializes a time.Duration to a primitive type.
  149. type DurationEncoder func(time.Duration, PrimitiveArrayEncoder)
  150. // EpochTimeEncoder serializes a time.Time to a floating-point number of seconds
  151. // since the Unix epoch.
  152. func EpochTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
  153. //var d []byte
  154. enc.AppendString(t.Format("2006-01-02T15:04:05.999999"))
  155. //enc.AppendByteString(t.AppendFormat(d, "2006-01-02T15:04:05.999999"))
  156. /*nanos := t.UnixNano()
  157. sec := float64(nanos) / float64(time.Second)
  158. enc.AppendFloat64(sec)*/
  159. }
  160. // SecondsDurationEncoder serializes a time.Duration to a floating-point number of seconds elapsed.
  161. func SecondsDurationEncoder(d time.Duration, enc PrimitiveArrayEncoder) {
  162. enc.AppendFloat64(float64(d) / float64(time.Second))
  163. }