github.com/ssgreg/logf@v1.4.1/json_encoder.go (about) 1 package logf 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "time" 7 "unicode/utf8" 8 "unsafe" 9 ) 10 11 // NewJSONEncoder creates the new instance of the JSON Encoder with the 12 // given JSONEncoderConfig. 13 var NewJSONEncoder = jsonEncoderGetter( 14 func(cfg JSONEncoderConfig) Encoder { 15 return &jsonEncoder{cfg.WithDefaults(), NewCache(100), nil, 0} 16 }, 17 ) 18 19 // NewJSONTypeEncoderFactory creates the new instance of the JSON 20 // TypeEncoderFactory with the given JSONEncoderConfig. 21 var NewJSONTypeEncoderFactory = jsonTypeEncoderFactoryGetter( 22 func(c JSONEncoderConfig) TypeEncoderFactory { 23 return &jsonEncoder{c.WithDefaults(), nil, nil, 0} 24 }, 25 ) 26 27 type jsonEncoderGetter func(cfg JSONEncoderConfig) Encoder 28 29 func (c jsonEncoderGetter) Default() Encoder { 30 return c(JSONEncoderConfig{}) 31 } 32 33 type jsonTypeEncoderFactoryGetter func(cfg JSONEncoderConfig) TypeEncoderFactory 34 35 func (c jsonTypeEncoderFactoryGetter) Default() TypeEncoderFactory { 36 return c(JSONEncoderConfig{}) 37 } 38 39 type jsonEncoder struct { 40 JSONEncoderConfig 41 cache *Cache 42 43 buf *Buffer 44 startBufLen int 45 } 46 47 func (f *jsonEncoder) TypeEncoder(buf *Buffer) TypeEncoder { 48 f.buf = buf 49 f.startBufLen = f.buf.Len() 50 51 return f 52 } 53 54 func (f *jsonEncoder) Encode(buf *Buffer, e Entry) error { 55 f.buf = buf 56 f.startBufLen = f.buf.Len() 57 58 buf.AppendByte('{') 59 60 // Level. 61 if !f.DisableFieldLevel { 62 f.addKey(f.FieldKeyLevel) 63 f.EncodeLevel(e.Level, f) 64 } 65 66 // Time. 67 if !f.DisableFieldTime { 68 f.EncodeFieldTime(f.FieldKeyTime, e.Time) 69 } 70 71 // Logger name. 72 if !f.DisableFieldName && e.LoggerName != "" { 73 f.EncodeFieldString(f.FieldKeyName, e.LoggerName) 74 } 75 76 // Message. 77 if !f.DisableFieldMsg { 78 f.EncodeFieldString(f.FieldKeyMsg, e.Text) 79 } 80 81 // Caller. 82 if !f.DisableFieldCaller && e.Caller.Specified { 83 f.addKey(f.FieldKeyCaller) 84 f.EncodeCaller(e.Caller, f) 85 } 86 87 // Logger's fields. 88 if bytes, ok := f.cache.Get(e.LoggerID); ok { 89 buf.AppendBytes(bytes) 90 } else { 91 le := buf.Len() 92 for _, field := range e.DerivedFields { 93 field.Accept(f) 94 } 95 96 bf := make([]byte, buf.Len()-le) 97 copy(bf, buf.Data[le:]) 98 f.cache.Set(e.LoggerID, bf) 99 } 100 101 // Entry's fields. 102 for _, field := range e.Fields { 103 field.Accept(f) 104 } 105 106 buf.AppendByte('}') 107 buf.AppendByte('\n') 108 109 return nil 110 } 111 112 func (f *jsonEncoder) EncodeFieldAny(k string, v interface{}) { 113 f.addKey(k) 114 f.EncodeTypeAny(v) 115 } 116 117 func (f *jsonEncoder) EncodeFieldBool(k string, v bool) { 118 f.addKey(k) 119 f.EncodeTypeBool(v) 120 } 121 122 func (f *jsonEncoder) EncodeFieldInt64(k string, v int64) { 123 f.addKey(k) 124 f.EncodeTypeInt64(v) 125 } 126 127 func (f *jsonEncoder) EncodeFieldInt32(k string, v int32) { 128 f.addKey(k) 129 f.EncodeTypeInt32(v) 130 } 131 132 func (f *jsonEncoder) EncodeFieldInt16(k string, v int16) { 133 f.addKey(k) 134 f.EncodeTypeInt16(v) 135 } 136 137 func (f *jsonEncoder) EncodeFieldInt8(k string, v int8) { 138 f.addKey(k) 139 f.EncodeTypeInt8(v) 140 } 141 142 func (f *jsonEncoder) EncodeFieldUint64(k string, v uint64) { 143 f.addKey(k) 144 f.EncodeTypeUint64(v) 145 } 146 147 func (f *jsonEncoder) EncodeFieldUint32(k string, v uint32) { 148 f.addKey(k) 149 f.EncodeTypeUint32(v) 150 } 151 152 func (f *jsonEncoder) EncodeFieldUint16(k string, v uint16) { 153 f.addKey(k) 154 f.EncodeTypeUint16(v) 155 } 156 157 func (f *jsonEncoder) EncodeFieldUint8(k string, v uint8) { 158 f.addKey(k) 159 f.EncodeTypeUint8(v) 160 } 161 162 func (f *jsonEncoder) EncodeFieldFloat64(k string, v float64) { 163 f.addKey(k) 164 f.EncodeTypeFloat64(v) 165 } 166 167 func (f *jsonEncoder) EncodeFieldFloat32(k string, v float32) { 168 f.addKey(k) 169 f.EncodeTypeFloat32(v) 170 } 171 172 func (f *jsonEncoder) EncodeFieldString(k string, v string) { 173 f.addKey(k) 174 f.EncodeTypeString(v) 175 } 176 177 func (f *jsonEncoder) EncodeFieldStrings(k string, v []string) { 178 f.addKey(k) 179 f.EncodeTypeStrings(v) 180 } 181 182 func (f *jsonEncoder) EncodeFieldDuration(k string, v time.Duration) { 183 f.addKey(k) 184 f.EncodeTypeDuration(v) 185 } 186 187 func (f *jsonEncoder) EncodeFieldError(k string, v error) { 188 // The only exception that has no EncodeX function. EncodeError can add 189 // new fields by itself. 190 f.EncodeError(k, v, f) 191 } 192 193 func (f *jsonEncoder) EncodeFieldTime(k string, v time.Time) { 194 f.addKey(k) 195 f.EncodeTypeTime(v) 196 } 197 198 func (f *jsonEncoder) EncodeFieldArray(k string, v ArrayEncoder) { 199 f.addKey(k) 200 f.EncodeTypeArray(v) 201 } 202 203 func (f *jsonEncoder) EncodeFieldObject(k string, v ObjectEncoder) { 204 f.addKey(k) 205 f.EncodeTypeObject(v) 206 } 207 208 func (f *jsonEncoder) EncodeFieldBytes(k string, v []byte) { 209 f.addKey(k) 210 f.EncodeTypeBytes(v) 211 } 212 213 func (f *jsonEncoder) EncodeFieldBools(k string, v []bool) { 214 f.addKey(k) 215 f.EncodeTypeBools(v) 216 } 217 218 func (f *jsonEncoder) EncodeFieldInts64(k string, v []int64) { 219 f.addKey(k) 220 f.EncodeTypeInts64(v) 221 } 222 223 func (f *jsonEncoder) EncodeFieldInts32(k string, v []int32) { 224 f.addKey(k) 225 f.EncodeTypeInts32(v) 226 } 227 228 func (f *jsonEncoder) EncodeFieldInts16(k string, v []int16) { 229 f.addKey(k) 230 f.EncodeTypeInts16(v) 231 } 232 233 func (f *jsonEncoder) EncodeFieldInts8(k string, v []int8) { 234 f.addKey(k) 235 f.EncodeTypeInts8(v) 236 } 237 238 func (f *jsonEncoder) EncodeFieldUints64(k string, v []uint64) { 239 f.addKey(k) 240 f.EncodeTypeUints64(v) 241 } 242 243 func (f *jsonEncoder) EncodeFieldUints32(k string, v []uint32) { 244 f.addKey(k) 245 f.EncodeTypeUints32(v) 246 } 247 248 func (f *jsonEncoder) EncodeFieldUints16(k string, v []uint16) { 249 f.addKey(k) 250 f.EncodeTypeUints16(v) 251 } 252 253 func (f *jsonEncoder) EncodeFieldUints8(k string, v []uint8) { 254 f.addKey(k) 255 f.EncodeTypeUints8(v) 256 } 257 258 func (f *jsonEncoder) EncodeFieldFloats64(k string, v []float64) { 259 f.addKey(k) 260 f.EncodeTypeFloats64(v) 261 } 262 263 func (f *jsonEncoder) EncodeFieldFloats32(k string, v []float32) { 264 f.addKey(k) 265 f.EncodeTypeFloats32(v) 266 } 267 268 func (f *jsonEncoder) EncodeFieldDurations(k string, v []time.Duration) { 269 f.addKey(k) 270 f.EncodeTypeDurations(v) 271 } 272 273 func (f *jsonEncoder) EncodeTypeAny(v interface{}) { 274 e := json.NewEncoder(f.buf) 275 e.Encode(v) 276 277 if !f.empty() && f.buf.Back() == '\n' { 278 f.buf.Data = f.buf.Data[0 : f.buf.Len()-1] 279 } 280 } 281 282 func (f *jsonEncoder) EncodeTypeUnsafeBytes(v unsafe.Pointer) { 283 f.appendSeparator() 284 f.buf.AppendByte('"') 285 EscapeByteString(f.buf, *(*[]byte)(v)) 286 f.buf.AppendByte('"') 287 } 288 289 func (f *jsonEncoder) EncodeTypeBool(v bool) { 290 f.appendSeparator() 291 AppendBool(f.buf, v) 292 } 293 294 func (f *jsonEncoder) EncodeTypeString(v string) { 295 f.appendSeparator() 296 f.buf.AppendByte('"') 297 EscapeString(f.buf, v) 298 f.buf.AppendByte('"') 299 } 300 301 func (f *jsonEncoder) EncodeTypeInt64(v int64) { 302 f.appendSeparator() 303 AppendInt(f.buf, v) 304 } 305 306 func (f *jsonEncoder) EncodeTypeInt32(v int32) { 307 f.appendSeparator() 308 AppendInt(f.buf, int64(v)) 309 } 310 311 func (f *jsonEncoder) EncodeTypeInt16(v int16) { 312 f.appendSeparator() 313 AppendInt(f.buf, int64(v)) 314 } 315 316 func (f *jsonEncoder) EncodeTypeInt8(v int8) { 317 f.appendSeparator() 318 AppendInt(f.buf, int64(v)) 319 } 320 321 func (f *jsonEncoder) EncodeTypeUint64(v uint64) { 322 f.appendSeparator() 323 AppendUint(f.buf, uint64(v)) 324 } 325 326 func (f *jsonEncoder) EncodeTypeUint32(v uint32) { 327 f.appendSeparator() 328 AppendUint(f.buf, uint64(v)) 329 } 330 331 func (f *jsonEncoder) EncodeTypeUint16(v uint16) { 332 f.appendSeparator() 333 AppendUint(f.buf, uint64(v)) 334 } 335 336 func (f *jsonEncoder) EncodeTypeUint8(v uint8) { 337 f.appendSeparator() 338 AppendUint(f.buf, uint64(v)) 339 } 340 341 func (f *jsonEncoder) EncodeTypeFloat64(v float64) { 342 f.appendSeparator() 343 AppendFloat64(f.buf, v) 344 } 345 346 func (f *jsonEncoder) EncodeTypeFloat32(v float32) { 347 f.appendSeparator() 348 AppendFloat32(f.buf, v) 349 } 350 351 func (f *jsonEncoder) EncodeTypeDuration(v time.Duration) { 352 f.appendSeparator() 353 f.EncodeDuration(v, f) 354 } 355 356 func (f *jsonEncoder) EncodeTypeTime(v time.Time) { 357 f.appendSeparator() 358 f.EncodeTime(v, f) 359 } 360 361 func (f *jsonEncoder) EncodeTypeBytes(v []byte) { 362 f.appendSeparator() 363 f.buf.AppendByte('"') 364 base64.StdEncoding.Encode(f.buf.ExtendBytes(base64.StdEncoding.EncodedLen(len(v))), v) 365 f.buf.AppendByte('"') 366 } 367 368 func (f *jsonEncoder) EncodeTypeBools(v []bool) { 369 f.appendSeparator() 370 f.buf.AppendByte('[') 371 for i := range v { 372 f.EncodeTypeBool(v[i]) 373 } 374 f.buf.AppendByte(']') 375 } 376 377 func (f *jsonEncoder) EncodeTypeStrings(v []string) { 378 f.appendSeparator() 379 f.buf.AppendByte('[') 380 for i := range v { 381 f.EncodeTypeString(v[i]) 382 } 383 f.buf.AppendByte(']') 384 } 385 386 func (f *jsonEncoder) EncodeTypeInts64(v []int64) { 387 f.appendSeparator() 388 f.buf.AppendByte('[') 389 for i := range v { 390 f.EncodeTypeInt64(v[i]) 391 } 392 f.buf.AppendByte(']') 393 } 394 395 func (f *jsonEncoder) EncodeTypeInts32(v []int32) { 396 f.appendSeparator() 397 f.buf.AppendByte('[') 398 for i := range v { 399 f.EncodeTypeInt32(v[i]) 400 } 401 f.buf.AppendByte(']') 402 } 403 404 func (f *jsonEncoder) EncodeTypeInts16(v []int16) { 405 f.appendSeparator() 406 f.buf.AppendByte('[') 407 for i := range v { 408 f.EncodeTypeInt16(v[i]) 409 } 410 f.buf.AppendByte(']') 411 } 412 413 func (f *jsonEncoder) EncodeTypeInts8(v []int8) { 414 f.appendSeparator() 415 f.buf.AppendByte('[') 416 for i := range v { 417 f.EncodeTypeInt8(v[i]) 418 } 419 f.buf.AppendByte(']') 420 } 421 422 func (f *jsonEncoder) EncodeTypeUints64(v []uint64) { 423 f.appendSeparator() 424 f.buf.AppendByte('[') 425 for i := range v { 426 f.EncodeTypeUint64(v[i]) 427 } 428 f.buf.AppendByte(']') 429 } 430 431 func (f *jsonEncoder) EncodeTypeUints32(v []uint32) { 432 f.appendSeparator() 433 f.buf.AppendByte('[') 434 for i := range v { 435 f.EncodeTypeUint32(v[i]) 436 } 437 f.buf.AppendByte(']') 438 } 439 440 func (f *jsonEncoder) EncodeTypeUints16(v []uint16) { 441 f.appendSeparator() 442 f.buf.AppendByte('[') 443 for i := range v { 444 f.EncodeTypeUint16(v[i]) 445 } 446 f.buf.AppendByte(']') 447 } 448 449 func (f *jsonEncoder) EncodeTypeUints8(v []uint8) { 450 f.appendSeparator() 451 f.buf.AppendByte('[') 452 for i := range v { 453 f.EncodeTypeUint8(v[i]) 454 } 455 f.buf.AppendByte(']') 456 } 457 458 func (f *jsonEncoder) EncodeTypeFloats64(v []float64) { 459 f.appendSeparator() 460 f.buf.AppendByte('[') 461 for i := range v { 462 f.EncodeTypeFloat64(v[i]) 463 } 464 f.buf.AppendByte(']') 465 } 466 467 func (f *jsonEncoder) EncodeTypeFloats32(v []float32) { 468 f.appendSeparator() 469 f.buf.AppendByte('[') 470 for i := range v { 471 f.EncodeTypeFloat32(v[i]) 472 } 473 f.buf.AppendByte(']') 474 } 475 476 func (f *jsonEncoder) EncodeTypeDurations(v []time.Duration) { 477 f.appendSeparator() 478 f.buf.AppendByte('[') 479 for i := range v { 480 f.EncodeTypeDuration(v[i]) 481 } 482 f.buf.AppendByte(']') 483 } 484 485 func (f *jsonEncoder) EncodeTypeArray(v ArrayEncoder) { 486 f.appendSeparator() 487 f.buf.AppendByte('[') 488 v.EncodeLogfArray(f) 489 f.buf.AppendByte(']') 490 } 491 492 func (f *jsonEncoder) EncodeTypeObject(v ObjectEncoder) { 493 f.appendSeparator() 494 f.buf.AppendByte('{') 495 v.EncodeLogfObject(f) 496 f.buf.AppendByte('}') 497 } 498 499 func (f *jsonEncoder) appendSeparator() { 500 if f.empty() { 501 return 502 } 503 504 switch f.buf.Back() { 505 case '{', '[', ':', ',': 506 return 507 } 508 f.buf.AppendByte(',') 509 } 510 511 func (f *jsonEncoder) empty() bool { 512 return f.buf.Len() == f.startBufLen 513 } 514 515 func (f *jsonEncoder) addKey(k string) { 516 f.appendSeparator() 517 f.buf.AppendByte('"') 518 EscapeString(f.buf, k) 519 f.buf.AppendByte('"') 520 f.buf.AppendByte(':') 521 } 522 523 const hex = "0123456789abcdef" 524 525 // EscapeString processes a single escape sequence to the given Buffer. 526 func EscapeString(buf *Buffer, s string) error { 527 p := 0 528 for i := 0; i < len(s); { 529 c := s[i] 530 switch { 531 case c < utf8.RuneSelf && c >= 0x20 && c != '\\' && c != '"': 532 i++ 533 534 continue 535 536 case c < utf8.RuneSelf: 537 buf.AppendString(s[p:i]) 538 switch c { 539 case '\t': 540 buf.AppendString(`\t`) 541 case '\r': 542 buf.AppendString(`\r`) 543 case '\n': 544 buf.AppendString(`\n`) 545 case '\\': 546 buf.AppendString(`\\`) 547 case '"': 548 buf.AppendString(`\"`) 549 default: 550 buf.AppendString(`\u00`) 551 buf.AppendByte(hex[c>>4]) 552 buf.AppendByte(hex[c&0xf]) 553 } 554 i++ 555 p = i 556 557 continue 558 } 559 v, wd := utf8.DecodeRuneInString(s[i:]) 560 if v == utf8.RuneError && wd == 1 { 561 buf.AppendString(s[p:i]) 562 buf.AppendString(`\ufffd`) 563 i++ 564 p = i 565 566 continue 567 } else { 568 i += wd 569 } 570 } 571 buf.AppendString(s[p:]) 572 573 return nil 574 } 575 576 // EscapeByteString processes a single escape sequence to the given Buffer. 577 func EscapeByteString(buf *Buffer, s []byte) error { 578 p := 0 579 for i := 0; i < len(s); { 580 c := s[i] 581 switch { 582 case c >= 0x20 && c != '\\' && c != '"': 583 i++ 584 585 continue 586 587 default: 588 buf.AppendBytes(s[p:i]) 589 switch c { 590 case '\t': 591 buf.AppendString(`\t`) 592 case '\r': 593 buf.AppendString(`\r`) 594 case '\n': 595 buf.AppendString(`\n`) 596 case '\\': 597 buf.AppendString(`\\`) 598 case '"': 599 buf.AppendString(`\"`) 600 default: 601 buf.AppendString(`\u00`) 602 buf.AppendByte(hex[c>>4]) 603 buf.AppendByte(hex[c&0xf]) 604 } 605 i++ 606 p = i 607 608 continue 609 } 610 } 611 buf.AppendBytes(s[p:]) 612 613 return nil 614 }