Guest User

Untitled

a guest
May 23rd, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.43 KB | None | 0 0
  1. package gelf
  2.  
  3. import (
  4. "encoding/base64"
  5. "encoding/json"
  6. "math"
  7. "sync"
  8. "time"
  9. "unicode/utf8"
  10.  
  11. "go.uber.org/zap/buffer"
  12. "go.uber.org/zap/zapcore"
  13. )
  14.  
  15. // For JSON-escaping; see jsonEncoder.safeAddString below.
  16. const _hex = "0123456789abcdef"
  17.  
  18. var _jsonPool = sync.Pool{New: func() interface{} {
  19. return &jsonEncoder{}
  20. }}
  21.  
  22. func getJSONEncoder() *jsonEncoder {
  23. return _jsonPool.Get().(*jsonEncoder)
  24. }
  25.  
  26. func putJSONEncoder(enc *jsonEncoder) {
  27. enc.EncoderConfig = nil
  28. enc.buf = nil
  29. enc.spaced = false
  30. enc.openNamespaces = 0
  31. _jsonPool.Put(enc)
  32. }
  33.  
  34. type jsonEncoder struct {
  35. *zapcore.EncoderConfig
  36. buf *buffer.Buffer
  37. spaced bool // include spaces after colons and commas
  38. openNamespaces int
  39. }
  40.  
  41. // NewJSONEncoder creates a fast, low-allocation JSON encoder. The encoder
  42. // appropriately escapes all field keys and values.
  43. //
  44. // Note that the encoder doesn't deduplicate keys, so it's possible to produce
  45. // a message like
  46. // {"foo":"bar","foo":"baz"}
  47. // This is permitted by the JSON specification, but not encouraged. Many
  48. // libraries will ignore duplicate key-value pairs (typically keeping the last
  49. // pair) when unmarshaling, but users should attempt to avoid adding duplicate
  50. // keys.
  51. func NewJSONEncoder(cfg zapcore.EncoderConfig) zapcore.Encoder {
  52. return newJSONEncoder(cfg, false)
  53. }
  54.  
  55. func newJSONEncoder(cfg zapcore.EncoderConfig, spaced bool) *jsonEncoder {
  56. return &jsonEncoder{
  57. EncoderConfig: &cfg,
  58. buf: Get(),
  59. spaced: spaced,
  60. }
  61. }
  62.  
  63. func (enc *jsonEncoder) AddArray(key string, arr zapcore.ArrayMarshaler) error {
  64. enc.addKey(key)
  65. return enc.AppendArray(arr)
  66. }
  67.  
  68. func (enc *jsonEncoder) AddObject(key string, obj zapcore.ObjectMarshaler) error {
  69. enc.addKey(key)
  70. return enc.AppendObject(obj)
  71. }
  72.  
  73. func (enc *jsonEncoder) AddBinary(key string, val []byte) {
  74. enc.AddString(key, base64.StdEncoding.EncodeToString(val))
  75. }
  76.  
  77. func (enc *jsonEncoder) AddByteString(key string, val []byte) {
  78. enc.addKey(key)
  79. enc.AppendByteString(val)
  80. }
  81.  
  82. func (enc *jsonEncoder) AddBool(key string, val bool) {
  83. enc.addKey(key)
  84. enc.AppendBool(val)
  85. }
  86.  
  87. func (enc *jsonEncoder) AddComplex128(key string, val complex128) {
  88. enc.addKey(key)
  89. enc.AppendComplex128(val)
  90. }
  91.  
  92. func (enc *jsonEncoder) AddDuration(key string, val time.Duration) {
  93. enc.addKey(key)
  94. enc.AppendDuration(val)
  95. }
  96.  
  97. func (enc *jsonEncoder) AddFloat64(key string, val float64) {
  98. enc.addKey(key)
  99. enc.AppendFloat64(val)
  100. }
  101.  
  102. func (enc *jsonEncoder) AddInt64(key string, val int64) {
  103. enc.addKey(key)
  104. enc.AppendInt64(val)
  105. }
  106.  
  107. func (enc *jsonEncoder) AddReflected(key string, obj interface{}) error {
  108. marshaled, err := json.Marshal(obj)
  109. if err != nil {
  110. return err
  111. }
  112. enc.addKey(key)
  113. _, err = enc.buf.Write(marshaled)
  114. return err
  115. }
  116.  
  117. func (enc *jsonEncoder) OpenNamespace(key string) {
  118. enc.addKey(key)
  119. enc.buf.AppendByte('{')
  120. enc.openNamespaces++
  121. }
  122.  
  123. func (enc *jsonEncoder) AddString(key, val string) {
  124. enc.addKey(key)
  125. enc.AppendString(val)
  126. }
  127.  
  128. func (enc *jsonEncoder) AddTime(key string, val time.Time) {
  129. enc.addKey(key)
  130. enc.AppendTime(val)
  131. }
  132.  
  133. func (enc *jsonEncoder) AddUint64(key string, val uint64) {
  134. enc.addKey(key)
  135. enc.AppendUint64(val)
  136. }
  137.  
  138. func (enc *jsonEncoder) AppendArray(arr zapcore.ArrayMarshaler) error {
  139. enc.addElementSeparator()
  140. enc.buf.AppendByte('[')
  141. err := arr.MarshalLogArray(enc)
  142. enc.buf.AppendByte(']')
  143. return err
  144. }
  145.  
  146. func (enc *jsonEncoder) AppendObject(obj zapcore.ObjectMarshaler) error {
  147. enc.addElementSeparator()
  148. enc.buf.AppendByte('{')
  149. err := obj.MarshalLogObject(enc)
  150. enc.buf.AppendByte('}')
  151. return err
  152. }
  153.  
  154. func (enc *jsonEncoder) AppendBool(val bool) {
  155. enc.addElementSeparator()
  156. enc.buf.AppendBool(val)
  157. }
  158.  
  159. func (enc *jsonEncoder) AppendByteString(val []byte) {
  160. enc.addElementSeparator()
  161. enc.buf.AppendByte('"')
  162. enc.safeAddByteString(val)
  163. enc.buf.AppendByte('"')
  164. }
  165.  
  166. func (enc *jsonEncoder) AppendComplex128(val complex128) {
  167. enc.addElementSeparator()
  168. // Cast to a platform-independent, fixed-size type.
  169. r, i := float64(real(val)), float64(imag(val))
  170. enc.buf.AppendByte('"')
  171. // Because we're always in a quoted string, we can use strconv without
  172. // special-casing NaN and +/-Inf.
  173. enc.buf.AppendFloat(r, 64)
  174. enc.buf.AppendByte('+')
  175. enc.buf.AppendFloat(i, 64)
  176. enc.buf.AppendByte('i')
  177. enc.buf.AppendByte('"')
  178. }
  179.  
  180. func (enc *jsonEncoder) AppendDuration(val time.Duration) {
  181. cur := enc.buf.Len()
  182. enc.EncodeDuration(val, enc)
  183. if cur == enc.buf.Len() {
  184. // User-supplied EncodeDuration is a no-op. Fall back to nanoseconds to keep
  185. // JSON valid.
  186. enc.AppendInt64(int64(val))
  187. }
  188. }
  189.  
  190. func (enc *jsonEncoder) AppendInt64(val int64) {
  191. enc.addElementSeparator()
  192. enc.buf.AppendInt(val)
  193. }
  194.  
  195. func (enc *jsonEncoder) AppendReflected(val interface{}) error {
  196. marshaled, err := json.Marshal(val)
  197. if err != nil {
  198. return err
  199. }
  200. enc.addElementSeparator()
  201. _, err = enc.buf.Write(marshaled)
  202. return err
  203. }
  204.  
  205. func (enc *jsonEncoder) AppendString(val string) {
  206. enc.addElementSeparator()
  207. enc.buf.AppendByte('"')
  208. enc.safeAddString(val)
  209. enc.buf.AppendByte('"')
  210. }
  211.  
  212. func (enc *jsonEncoder) AppendTime(val time.Time) {
  213. cur := enc.buf.Len()
  214. enc.EncodeTime(val, enc)
  215. if cur == enc.buf.Len() {
  216. // User-supplied EncodeTime is a no-op. Fall back to nanos since epoch to keep
  217. // output JSON valid.
  218. enc.AppendInt64(val.UnixNano())
  219. }
  220. }
  221.  
  222. func (enc *jsonEncoder) AppendUint64(val uint64) {
  223. enc.addElementSeparator()
  224. enc.buf.AppendUint(val)
  225. }
  226.  
  227. func (enc *jsonEncoder) AddComplex64(k string, v complex64) { enc.AddComplex128(k, complex128(v)) }
  228. func (enc *jsonEncoder) AddFloat32(k string, v float32) { enc.AddFloat64(k, float64(v)) }
  229. func (enc *jsonEncoder) AddInt(k string, v int) { enc.AddInt64(k, int64(v)) }
  230. func (enc *jsonEncoder) AddInt32(k string, v int32) { enc.AddInt64(k, int64(v)) }
  231. func (enc *jsonEncoder) AddInt16(k string, v int16) { enc.AddInt64(k, int64(v)) }
  232. func (enc *jsonEncoder) AddInt8(k string, v int8) { enc.AddInt64(k, int64(v)) }
  233. func (enc *jsonEncoder) AddUint(k string, v uint) { enc.AddUint64(k, uint64(v)) }
  234. func (enc *jsonEncoder) AddUint32(k string, v uint32) { enc.AddUint64(k, uint64(v)) }
  235. func (enc *jsonEncoder) AddUint16(k string, v uint16) { enc.AddUint64(k, uint64(v)) }
  236. func (enc *jsonEncoder) AddUint8(k string, v uint8) { enc.AddUint64(k, uint64(v)) }
  237. func (enc *jsonEncoder) AddUintptr(k string, v uintptr) { enc.AddUint64(k, uint64(v)) }
  238. func (enc *jsonEncoder) AppendComplex64(v complex64) { enc.AppendComplex128(complex128(v)) }
  239. func (enc *jsonEncoder) AppendFloat64(v float64) { enc.appendFloat(v, 64) }
  240. func (enc *jsonEncoder) AppendFloat32(v float32) { enc.appendFloat(float64(v), 32) }
  241. func (enc *jsonEncoder) AppendInt(v int) { enc.AppendInt64(int64(v)) }
  242. func (enc *jsonEncoder) AppendInt32(v int32) { enc.AppendInt64(int64(v)) }
  243. func (enc *jsonEncoder) AppendInt16(v int16) { enc.AppendInt64(int64(v)) }
  244. func (enc *jsonEncoder) AppendInt8(v int8) { enc.AppendInt64(int64(v)) }
  245. func (enc *jsonEncoder) AppendUint(v uint) { enc.AppendUint64(uint64(v)) }
  246. func (enc *jsonEncoder) AppendUint32(v uint32) { enc.AppendUint64(uint64(v)) }
  247. func (enc *jsonEncoder) AppendUint16(v uint16) { enc.AppendUint64(uint64(v)) }
  248. func (enc *jsonEncoder) AppendUint8(v uint8) { enc.AppendUint64(uint64(v)) }
  249. func (enc *jsonEncoder) AppendUintptr(v uintptr) { enc.AppendUint64(uint64(v)) }
  250.  
  251. func (enc *jsonEncoder) Clone() zapcore.Encoder {
  252. clone := enc.clone()
  253. clone.buf.Write(enc.buf.Bytes())
  254. return clone
  255. }
  256.  
  257. func (enc *jsonEncoder) clone() *jsonEncoder {
  258. clone := getJSONEncoder()
  259. clone.EncoderConfig = enc.EncoderConfig
  260. clone.spaced = enc.spaced
  261. clone.openNamespaces = enc.openNamespaces
  262. clone.buf = Get()
  263. return clone
  264. }
  265.  
  266. func (enc *jsonEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
  267. final := enc.clone()
  268. final.buf.AppendByte('{')
  269.  
  270. if final.LevelKey != "" {
  271. final.addKey(final.LevelKey)
  272. cur := final.buf.Len()
  273. final.EncodeLevel(ent.Level, final)
  274. if cur == final.buf.Len() {
  275. // User-supplied EncodeLevel was a no-op. Fall back to strings to keep
  276. // output JSON valid.
  277. final.AppendString(ent.Level.String())
  278. }
  279. }
  280.  
  281. final.AddString("full_message", "")
  282.  
  283. if final.TimeKey != "" {
  284. final.AddTime(final.TimeKey, ent.Time)
  285. }
  286.  
  287. if ent.LoggerName != "" && final.NameKey != "" {
  288. final.addKey(final.NameKey)
  289. cur := final.buf.Len()
  290. nameEncoder := final.EncodeName
  291.  
  292. // if no name encoder provided, fall back to FullNameEncoder for backwards
  293. // compatibility
  294. if nameEncoder == nil {
  295. nameEncoder = zapcore.FullNameEncoder
  296. }
  297.  
  298. nameEncoder(ent.LoggerName, final)
  299. if cur == final.buf.Len() {
  300. // User-supplied EncodeName was a no-op. Fall back to strings to
  301. // keep output JSON valid.
  302. final.AppendString(ent.LoggerName)
  303. }
  304. }
  305. if ent.Caller.Defined && final.CallerKey != "" {
  306. final.addKey(final.CallerKey)
  307. cur := final.buf.Len()
  308. final.EncodeCaller(ent.Caller, final)
  309. if cur == final.buf.Len() {
  310. // User-supplied EncodeCaller was a no-op. Fall back to strings to
  311. // keep output JSON valid.
  312. final.AppendString(ent.Caller.String())
  313. }
  314. }
  315. if final.MessageKey != "" {
  316. final.addKey(enc.MessageKey)
  317. final.AppendString(ent.Message)
  318. }
  319. if enc.buf.Len() > 0 {
  320. final.addElementSeparator()
  321. final.buf.Write(enc.buf.Bytes())
  322. }
  323. addFields(final, fields)
  324. final.closeOpenNamespaces()
  325. if ent.Stack != "" && final.StacktraceKey != "" {
  326. final.AddString(final.StacktraceKey, ent.Stack)
  327. }
  328. final.buf.AppendByte('}')
  329. if final.LineEnding != "" {
  330. final.buf.AppendString(final.LineEnding)
  331. } else {
  332. final.buf.AppendString(zapcore.DefaultLineEnding)
  333. }
  334.  
  335. ret := final.buf
  336. putJSONEncoder(final)
  337. return ret, nil
  338. }
  339.  
  340. func (enc *jsonEncoder) truncate() {
  341. enc.buf.Reset()
  342. }
  343.  
  344. func (enc *jsonEncoder) closeOpenNamespaces() {
  345. for i := 0; i < enc.openNamespaces; i++ {
  346. enc.buf.AppendByte('}')
  347. }
  348. }
  349.  
  350. func (enc *jsonEncoder) addKey(key string) {
  351. enc.addElementSeparator()
  352. enc.buf.AppendByte('"')
  353. enc.safeAddString(key)
  354. enc.buf.AppendByte('"')
  355. enc.buf.AppendByte(':')
  356. if enc.spaced {
  357. enc.buf.AppendByte(' ')
  358. }
  359. }
  360.  
  361. func (enc *jsonEncoder) addElementSeparator() {
  362. last := enc.buf.Len() - 1
  363. if last < 0 {
  364. return
  365. }
  366. switch enc.buf.Bytes()[last] {
  367. case '{', '[', ':', ',', ' ':
  368. return
  369. default:
  370. enc.buf.AppendByte(',')
  371. if enc.spaced {
  372. enc.buf.AppendByte(' ')
  373. }
  374. }
  375. }
  376.  
  377. func (enc *jsonEncoder) appendFloat(val float64, bitSize int) {
  378. enc.addElementSeparator()
  379. switch {
  380. case math.IsNaN(val):
  381. enc.buf.AppendString(`"NaN"`)
  382. case math.IsInf(val, 1):
  383. enc.buf.AppendString(`"+Inf"`)
  384. case math.IsInf(val, -1):
  385. enc.buf.AppendString(`"-Inf"`)
  386. default:
  387. enc.buf.AppendFloat(val, bitSize)
  388. }
  389. }
  390.  
  391. // safeAddString JSON-escapes a string and appends it to the internal buffer.
  392. // Unlike the standard library's encoder, it doesn't attempt to protect the
  393. // user from browser vulnerabilities or JSONP-related problems.
  394. func (enc *jsonEncoder) safeAddString(s string) {
  395. for i := 0; i < len(s); {
  396. if enc.tryAddRuneSelf(s[i]) {
  397. i++
  398. continue
  399. }
  400. r, size := utf8.DecodeRuneInString(s[i:])
  401. if enc.tryAddRuneError(r, size) {
  402. i++
  403. continue
  404. }
  405. enc.buf.AppendString(s[i : i+size])
  406. i += size
  407. }
  408. }
  409.  
  410. // safeAddByteString is no-alloc equivalent of safeAddString(string(s)) for s []byte.
  411. func (enc *jsonEncoder) safeAddByteString(s []byte) {
  412. for i := 0; i < len(s); {
  413. if enc.tryAddRuneSelf(s[i]) {
  414. i++
  415. continue
  416. }
  417. r, size := utf8.DecodeRune(s[i:])
  418. if enc.tryAddRuneError(r, size) {
  419. i++
  420. continue
  421. }
  422. enc.buf.Write(s[i : i+size])
  423. i += size
  424. }
  425. }
  426.  
  427. // tryAddRuneSelf appends b if it is valid UTF-8 character represented in a single byte.
  428. func (enc *jsonEncoder) tryAddRuneSelf(b byte) bool {
  429. if b >= utf8.RuneSelf {
  430. return false
  431. }
  432. if 0x20 <= b && b != '\\' && b != '"' {
  433. enc.buf.AppendByte(b)
  434. return true
  435. }
  436. switch b {
  437. case '\\', '"':
  438. enc.buf.AppendByte('\\')
  439. enc.buf.AppendByte(b)
  440. case '\n':
  441. enc.buf.AppendByte('\\')
  442. enc.buf.AppendByte('n')
  443. case '\r':
  444. enc.buf.AppendByte('\\')
  445. enc.buf.AppendByte('r')
  446. case '\t':
  447. enc.buf.AppendByte('\\')
  448. enc.buf.AppendByte('t')
  449. default:
  450. // Encode bytes < 0x20, except for the escape sequences above.
  451. enc.buf.AppendString(`\u00`)
  452. enc.buf.AppendByte(_hex[b>>4])
  453. enc.buf.AppendByte(_hex[b&0xF])
  454. }
  455. return true
  456. }
  457.  
  458. func (enc *jsonEncoder) tryAddRuneError(r rune, size int) bool {
  459. if r == utf8.RuneError && size == 1 {
  460. enc.buf.AppendString(`\ufffd`)
  461. return true
  462. }
  463. return false
  464. }
  465.  
  466. func addFields(enc zapcore.ObjectEncoder, fields []zapcore.Field) {
  467. for i := range fields {
  468. fields[i].AddTo(enc)
  469. }
  470. }
Add Comment
Please, Sign In to add comment