1package zerolog 2 3import ( 4 "fmt" 5 "net" 6 "os" 7 "runtime" 8 "sync" 9 "time" 10) 11 12var eventPool = &sync.Pool{ 13 New: func() interface{} { 14 return &Event{ 15 buf: make([]byte, 0, 500), 16 } 17 }, 18} 19 20// Event represents a log event. It is instanced by one of the level method of 21// Logger and finalized by the Msg or Msgf method. 22type Event struct { 23 buf []byte 24 w LevelWriter 25 level Level 26 done func(msg string) 27 stack bool // enable error stack trace 28 ch []Hook // hooks from context 29} 30 31func putEvent(e *Event) { 32 // Proper usage of a sync.Pool requires each entry to have approximately 33 // the same memory cost. To obtain this property when the stored type 34 // contains a variably-sized buffer, we add a hard limit on the maximum buffer 35 // to place back in the pool. 36 // 37 // See https://golang.org/issue/23199 38 const maxSize = 1 << 16 // 64KiB 39 if cap(e.buf) > maxSize { 40 return 41 } 42 eventPool.Put(e) 43} 44 45// LogObjectMarshaler provides a strongly-typed and encoding-agnostic interface 46// to be implemented by types used with Event/Context's Object methods. 47type LogObjectMarshaler interface { 48 MarshalZerologObject(e *Event) 49} 50 51// LogArrayMarshaler provides a strongly-typed and encoding-agnostic interface 52// to be implemented by types used with Event/Context's Array methods. 53type LogArrayMarshaler interface { 54 MarshalZerologArray(a *Array) 55} 56 57func newEvent(w LevelWriter, level Level) *Event { 58 e := eventPool.Get().(*Event) 59 e.buf = e.buf[:0] 60 e.ch = nil 61 e.buf = enc.AppendBeginMarker(e.buf) 62 e.w = w 63 e.level = level 64 e.stack = false 65 return e 66} 67 68func (e *Event) write() (err error) { 69 if e == nil { 70 return nil 71 } 72 if e.level != Disabled { 73 e.buf = enc.AppendEndMarker(e.buf) 74 e.buf = enc.AppendLineBreak(e.buf) 75 if e.w != nil { 76 _, err = e.w.WriteLevel(e.level, e.buf) 77 } 78 } 79 putEvent(e) 80 return 81} 82 83// Enabled return false if the *Event is going to be filtered out by 84// log level or sampling. 85func (e *Event) Enabled() bool { 86 return e != nil && e.level != Disabled 87} 88 89// Discard disables the event so Msg(f) won't print it. 90func (e *Event) Discard() *Event { 91 if e == nil { 92 return e 93 } 94 e.level = Disabled 95 return nil 96} 97 98// Msg sends the *Event with msg added as the message field if not empty. 99// 100// NOTICE: once this method is called, the *Event should be disposed. 101// Calling Msg twice can have unexpected result. 102func (e *Event) Msg(msg string) { 103 if e == nil { 104 return 105 } 106 e.msg(msg) 107} 108 109// Send is equivalent to calling Msg(""). 110// 111// NOTICE: once this method is called, the *Event should be disposed. 112func (e *Event) Send() { 113 if e == nil { 114 return 115 } 116 e.msg("") 117} 118 119// Msgf sends the event with formatted msg added as the message field if not empty. 120// 121// NOTICE: once this method is called, the *Event should be disposed. 122// Calling Msgf twice can have unexpected result. 123func (e *Event) Msgf(format string, v ...interface{}) { 124 if e == nil { 125 return 126 } 127 e.msg(fmt.Sprintf(format, v...)) 128} 129 130func (e *Event) msg(msg string) { 131 for _, hook := range e.ch { 132 hook.Run(e, e.level, msg) 133 } 134 if msg != "" { 135 e.buf = enc.AppendString(enc.AppendKey(e.buf, MessageFieldName), msg) 136 } 137 if e.done != nil { 138 defer e.done(msg) 139 } 140 if err := e.write(); err != nil { 141 if ErrorHandler != nil { 142 ErrorHandler(err) 143 } else { 144 fmt.Fprintf(os.Stderr, "zerolog: could not write event: %v\n", err) 145 } 146 } 147} 148 149// Fields is a helper function to use a map to set fields using type assertion. 150func (e *Event) Fields(fields map[string]interface{}) *Event { 151 if e == nil { 152 return e 153 } 154 e.buf = appendFields(e.buf, fields) 155 return e 156} 157 158// Dict adds the field key with a dict to the event context. 159// Use zerolog.Dict() to create the dictionary. 160func (e *Event) Dict(key string, dict *Event) *Event { 161 if e == nil { 162 return e 163 } 164 dict.buf = enc.AppendEndMarker(dict.buf) 165 e.buf = append(enc.AppendKey(e.buf, key), dict.buf...) 166 putEvent(dict) 167 return e 168} 169 170// Dict creates an Event to be used with the *Event.Dict method. 171// Call usual field methods like Str, Int etc to add fields to this 172// event and give it as argument the *Event.Dict method. 173func Dict() *Event { 174 return newEvent(nil, 0) 175} 176 177// Array adds the field key with an array to the event context. 178// Use zerolog.Arr() to create the array or pass a type that 179// implement the LogArrayMarshaler interface. 180func (e *Event) Array(key string, arr LogArrayMarshaler) *Event { 181 if e == nil { 182 return e 183 } 184 e.buf = enc.AppendKey(e.buf, key) 185 var a *Array 186 if aa, ok := arr.(*Array); ok { 187 a = aa 188 } else { 189 a = Arr() 190 arr.MarshalZerologArray(a) 191 } 192 e.buf = a.write(e.buf) 193 return e 194} 195 196func (e *Event) appendObject(obj LogObjectMarshaler) { 197 e.buf = enc.AppendBeginMarker(e.buf) 198 obj.MarshalZerologObject(e) 199 e.buf = enc.AppendEndMarker(e.buf) 200} 201 202// Object marshals an object that implement the LogObjectMarshaler interface. 203func (e *Event) Object(key string, obj LogObjectMarshaler) *Event { 204 if e == nil { 205 return e 206 } 207 e.buf = enc.AppendKey(e.buf, key) 208 e.appendObject(obj) 209 return e 210} 211 212// EmbedObject marshals an object that implement the LogObjectMarshaler interface. 213func (e *Event) EmbedObject(obj LogObjectMarshaler) *Event { 214 if e == nil { 215 return e 216 } 217 obj.MarshalZerologObject(e) 218 return e 219} 220 221// Str adds the field key with val as a string to the *Event context. 222func (e *Event) Str(key, val string) *Event { 223 if e == nil { 224 return e 225 } 226 e.buf = enc.AppendString(enc.AppendKey(e.buf, key), val) 227 return e 228} 229 230// Strs adds the field key with vals as a []string to the *Event context. 231func (e *Event) Strs(key string, vals []string) *Event { 232 if e == nil { 233 return e 234 } 235 e.buf = enc.AppendStrings(enc.AppendKey(e.buf, key), vals) 236 return e 237} 238 239// Stringer adds the field key with val.String() (or null if val is nil) to the *Event context. 240func (e *Event) Stringer(key string, val fmt.Stringer) *Event { 241 if e == nil { 242 return e 243 } 244 245 if val != nil { 246 e.buf = enc.AppendString(enc.AppendKey(e.buf, key), val.String()) 247 return e 248 } 249 250 e.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), nil) 251 return e 252} 253 254// Bytes adds the field key with val as a string to the *Event context. 255// 256// Runes outside of normal ASCII ranges will be hex-encoded in the resulting 257// JSON. 258func (e *Event) Bytes(key string, val []byte) *Event { 259 if e == nil { 260 return e 261 } 262 e.buf = enc.AppendBytes(enc.AppendKey(e.buf, key), val) 263 return e 264} 265 266// Hex adds the field key with val as a hex string to the *Event context. 267func (e *Event) Hex(key string, val []byte) *Event { 268 if e == nil { 269 return e 270 } 271 e.buf = enc.AppendHex(enc.AppendKey(e.buf, key), val) 272 return e 273} 274 275// RawJSON adds already encoded JSON to the log line under key. 276// 277// No sanity check is performed on b; it must not contain carriage returns and 278// be valid JSON. 279func (e *Event) RawJSON(key string, b []byte) *Event { 280 if e == nil { 281 return e 282 } 283 e.buf = appendJSON(enc.AppendKey(e.buf, key), b) 284 return e 285} 286 287// AnErr adds the field key with serialized err to the *Event context. 288// If err is nil, no field is added. 289func (e *Event) AnErr(key string, err error) *Event { 290 if e == nil { 291 return e 292 } 293 switch m := ErrorMarshalFunc(err).(type) { 294 case nil: 295 return e 296 case LogObjectMarshaler: 297 return e.Object(key, m) 298 case error: 299 if m == nil || isNilValue(m) { 300 return e 301 } else { 302 return e.Str(key, m.Error()) 303 } 304 case string: 305 return e.Str(key, m) 306 default: 307 return e.Interface(key, m) 308 } 309} 310 311// Errs adds the field key with errs as an array of serialized errors to the 312// *Event context. 313func (e *Event) Errs(key string, errs []error) *Event { 314 if e == nil { 315 return e 316 } 317 arr := Arr() 318 for _, err := range errs { 319 switch m := ErrorMarshalFunc(err).(type) { 320 case LogObjectMarshaler: 321 arr = arr.Object(m) 322 case error: 323 arr = arr.Err(m) 324 case string: 325 arr = arr.Str(m) 326 default: 327 arr = arr.Interface(m) 328 } 329 } 330 331 return e.Array(key, arr) 332} 333 334// Err adds the field "error" with serialized err to the *Event context. 335// If err is nil, no field is added. 336// 337// To customize the key name, change zerolog.ErrorFieldName. 338// 339// If Stack() has been called before and zerolog.ErrorStackMarshaler is defined, 340// the err is passed to ErrorStackMarshaler and the result is appended to the 341// zerolog.ErrorStackFieldName. 342func (e *Event) Err(err error) *Event { 343 if e == nil { 344 return e 345 } 346 if e.stack && ErrorStackMarshaler != nil { 347 switch m := ErrorStackMarshaler(err).(type) { 348 case nil: 349 case LogObjectMarshaler: 350 e.Object(ErrorStackFieldName, m) 351 case error: 352 if m != nil && !isNilValue(m) { 353 e.Str(ErrorStackFieldName, m.Error()) 354 } 355 case string: 356 e.Str(ErrorStackFieldName, m) 357 default: 358 e.Interface(ErrorStackFieldName, m) 359 } 360 } 361 return e.AnErr(ErrorFieldName, err) 362} 363 364// Stack enables stack trace printing for the error passed to Err(). 365// 366// ErrorStackMarshaler must be set for this method to do something. 367func (e *Event) Stack() *Event { 368 if e != nil { 369 e.stack = true 370 } 371 return e 372} 373 374// Bool adds the field key with val as a bool to the *Event context. 375func (e *Event) Bool(key string, b bool) *Event { 376 if e == nil { 377 return e 378 } 379 e.buf = enc.AppendBool(enc.AppendKey(e.buf, key), b) 380 return e 381} 382 383// Bools adds the field key with val as a []bool to the *Event context. 384func (e *Event) Bools(key string, b []bool) *Event { 385 if e == nil { 386 return e 387 } 388 e.buf = enc.AppendBools(enc.AppendKey(e.buf, key), b) 389 return e 390} 391 392// Int adds the field key with i as a int to the *Event context. 393func (e *Event) Int(key string, i int) *Event { 394 if e == nil { 395 return e 396 } 397 e.buf = enc.AppendInt(enc.AppendKey(e.buf, key), i) 398 return e 399} 400 401// Ints adds the field key with i as a []int to the *Event context. 402func (e *Event) Ints(key string, i []int) *Event { 403 if e == nil { 404 return e 405 } 406 e.buf = enc.AppendInts(enc.AppendKey(e.buf, key), i) 407 return e 408} 409 410// Int8 adds the field key with i as a int8 to the *Event context. 411func (e *Event) Int8(key string, i int8) *Event { 412 if e == nil { 413 return e 414 } 415 e.buf = enc.AppendInt8(enc.AppendKey(e.buf, key), i) 416 return e 417} 418 419// Ints8 adds the field key with i as a []int8 to the *Event context. 420func (e *Event) Ints8(key string, i []int8) *Event { 421 if e == nil { 422 return e 423 } 424 e.buf = enc.AppendInts8(enc.AppendKey(e.buf, key), i) 425 return e 426} 427 428// Int16 adds the field key with i as a int16 to the *Event context. 429func (e *Event) Int16(key string, i int16) *Event { 430 if e == nil { 431 return e 432 } 433 e.buf = enc.AppendInt16(enc.AppendKey(e.buf, key), i) 434 return e 435} 436 437// Ints16 adds the field key with i as a []int16 to the *Event context. 438func (e *Event) Ints16(key string, i []int16) *Event { 439 if e == nil { 440 return e 441 } 442 e.buf = enc.AppendInts16(enc.AppendKey(e.buf, key), i) 443 return e 444} 445 446// Int32 adds the field key with i as a int32 to the *Event context. 447func (e *Event) Int32(key string, i int32) *Event { 448 if e == nil { 449 return e 450 } 451 e.buf = enc.AppendInt32(enc.AppendKey(e.buf, key), i) 452 return e 453} 454 455// Ints32 adds the field key with i as a []int32 to the *Event context. 456func (e *Event) Ints32(key string, i []int32) *Event { 457 if e == nil { 458 return e 459 } 460 e.buf = enc.AppendInts32(enc.AppendKey(e.buf, key), i) 461 return e 462} 463 464// Int64 adds the field key with i as a int64 to the *Event context. 465func (e *Event) Int64(key string, i int64) *Event { 466 if e == nil { 467 return e 468 } 469 e.buf = enc.AppendInt64(enc.AppendKey(e.buf, key), i) 470 return e 471} 472 473// Ints64 adds the field key with i as a []int64 to the *Event context. 474func (e *Event) Ints64(key string, i []int64) *Event { 475 if e == nil { 476 return e 477 } 478 e.buf = enc.AppendInts64(enc.AppendKey(e.buf, key), i) 479 return e 480} 481 482// Uint adds the field key with i as a uint to the *Event context. 483func (e *Event) Uint(key string, i uint) *Event { 484 if e == nil { 485 return e 486 } 487 e.buf = enc.AppendUint(enc.AppendKey(e.buf, key), i) 488 return e 489} 490 491// Uints adds the field key with i as a []int to the *Event context. 492func (e *Event) Uints(key string, i []uint) *Event { 493 if e == nil { 494 return e 495 } 496 e.buf = enc.AppendUints(enc.AppendKey(e.buf, key), i) 497 return e 498} 499 500// Uint8 adds the field key with i as a uint8 to the *Event context. 501func (e *Event) Uint8(key string, i uint8) *Event { 502 if e == nil { 503 return e 504 } 505 e.buf = enc.AppendUint8(enc.AppendKey(e.buf, key), i) 506 return e 507} 508 509// Uints8 adds the field key with i as a []int8 to the *Event context. 510func (e *Event) Uints8(key string, i []uint8) *Event { 511 if e == nil { 512 return e 513 } 514 e.buf = enc.AppendUints8(enc.AppendKey(e.buf, key), i) 515 return e 516} 517 518// Uint16 adds the field key with i as a uint16 to the *Event context. 519func (e *Event) Uint16(key string, i uint16) *Event { 520 if e == nil { 521 return e 522 } 523 e.buf = enc.AppendUint16(enc.AppendKey(e.buf, key), i) 524 return e 525} 526 527// Uints16 adds the field key with i as a []int16 to the *Event context. 528func (e *Event) Uints16(key string, i []uint16) *Event { 529 if e == nil { 530 return e 531 } 532 e.buf = enc.AppendUints16(enc.AppendKey(e.buf, key), i) 533 return e 534} 535 536// Uint32 adds the field key with i as a uint32 to the *Event context. 537func (e *Event) Uint32(key string, i uint32) *Event { 538 if e == nil { 539 return e 540 } 541 e.buf = enc.AppendUint32(enc.AppendKey(e.buf, key), i) 542 return e 543} 544 545// Uints32 adds the field key with i as a []int32 to the *Event context. 546func (e *Event) Uints32(key string, i []uint32) *Event { 547 if e == nil { 548 return e 549 } 550 e.buf = enc.AppendUints32(enc.AppendKey(e.buf, key), i) 551 return e 552} 553 554// Uint64 adds the field key with i as a uint64 to the *Event context. 555func (e *Event) Uint64(key string, i uint64) *Event { 556 if e == nil { 557 return e 558 } 559 e.buf = enc.AppendUint64(enc.AppendKey(e.buf, key), i) 560 return e 561} 562 563// Uints64 adds the field key with i as a []int64 to the *Event context. 564func (e *Event) Uints64(key string, i []uint64) *Event { 565 if e == nil { 566 return e 567 } 568 e.buf = enc.AppendUints64(enc.AppendKey(e.buf, key), i) 569 return e 570} 571 572// Float32 adds the field key with f as a float32 to the *Event context. 573func (e *Event) Float32(key string, f float32) *Event { 574 if e == nil { 575 return e 576 } 577 e.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f) 578 return e 579} 580 581// Floats32 adds the field key with f as a []float32 to the *Event context. 582func (e *Event) Floats32(key string, f []float32) *Event { 583 if e == nil { 584 return e 585 } 586 e.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f) 587 return e 588} 589 590// Float64 adds the field key with f as a float64 to the *Event context. 591func (e *Event) Float64(key string, f float64) *Event { 592 if e == nil { 593 return e 594 } 595 e.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f) 596 return e 597} 598 599// Floats64 adds the field key with f as a []float64 to the *Event context. 600func (e *Event) Floats64(key string, f []float64) *Event { 601 if e == nil { 602 return e 603 } 604 e.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f) 605 return e 606} 607 608// Timestamp adds the current local time as UNIX timestamp to the *Event context with the "time" key. 609// To customize the key name, change zerolog.TimestampFieldName. 610// 611// NOTE: It won't dedupe the "time" key if the *Event (or *Context) has one 612// already. 613func (e *Event) Timestamp() *Event { 614 if e == nil { 615 return e 616 } 617 e.buf = enc.AppendTime(enc.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat) 618 return e 619} 620 621// Time adds the field key with t formated as string using zerolog.TimeFieldFormat. 622func (e *Event) Time(key string, t time.Time) *Event { 623 if e == nil { 624 return e 625 } 626 e.buf = enc.AppendTime(enc.AppendKey(e.buf, key), t, TimeFieldFormat) 627 return e 628} 629 630// Times adds the field key with t formated as string using zerolog.TimeFieldFormat. 631func (e *Event) Times(key string, t []time.Time) *Event { 632 if e == nil { 633 return e 634 } 635 e.buf = enc.AppendTimes(enc.AppendKey(e.buf, key), t, TimeFieldFormat) 636 return e 637} 638 639// Dur adds the field key with duration d stored as zerolog.DurationFieldUnit. 640// If zerolog.DurationFieldInteger is true, durations are rendered as integer 641// instead of float. 642func (e *Event) Dur(key string, d time.Duration) *Event { 643 if e == nil { 644 return e 645 } 646 e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) 647 return e 648} 649 650// Durs adds the field key with duration d stored as zerolog.DurationFieldUnit. 651// If zerolog.DurationFieldInteger is true, durations are rendered as integer 652// instead of float. 653func (e *Event) Durs(key string, d []time.Duration) *Event { 654 if e == nil { 655 return e 656 } 657 e.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) 658 return e 659} 660 661// TimeDiff adds the field key with positive duration between time t and start. 662// If time t is not greater than start, duration will be 0. 663// Duration format follows the same principle as Dur(). 664func (e *Event) TimeDiff(key string, t time.Time, start time.Time) *Event { 665 if e == nil { 666 return e 667 } 668 var d time.Duration 669 if t.After(start) { 670 d = t.Sub(start) 671 } 672 e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) 673 return e 674} 675 676// Interface adds the field key with i marshaled using reflection. 677func (e *Event) Interface(key string, i interface{}) *Event { 678 if e == nil { 679 return e 680 } 681 if obj, ok := i.(LogObjectMarshaler); ok { 682 return e.Object(key, obj) 683 } 684 e.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), i) 685 return e 686} 687 688// Caller adds the file:line of the caller with the zerolog.CallerFieldName key. 689// The argument skip is the number of stack frames to ascend 690// Skip If not passed, use the global variable CallerSkipFrameCount 691func (e *Event) Caller(skip ...int) *Event { 692 sk := CallerSkipFrameCount 693 if len(skip) > 0 { 694 sk = skip[0] + CallerSkipFrameCount 695 } 696 return e.caller(sk) 697} 698 699func (e *Event) caller(skip int) *Event { 700 if e == nil { 701 return e 702 } 703 _, file, line, ok := runtime.Caller(skip) 704 if !ok { 705 return e 706 } 707 e.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), CallerMarshalFunc(file, line)) 708 return e 709} 710 711// IPAddr adds IPv4 or IPv6 Address to the event 712func (e *Event) IPAddr(key string, ip net.IP) *Event { 713 if e == nil { 714 return e 715 } 716 e.buf = enc.AppendIPAddr(enc.AppendKey(e.buf, key), ip) 717 return e 718} 719 720// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the event 721func (e *Event) IPPrefix(key string, pfx net.IPNet) *Event { 722 if e == nil { 723 return e 724 } 725 e.buf = enc.AppendIPPrefix(enc.AppendKey(e.buf, key), pfx) 726 return e 727} 728 729// MACAddr adds MAC address to the event 730func (e *Event) MACAddr(key string, ha net.HardwareAddr) *Event { 731 if e == nil { 732 return e 733 } 734 e.buf = enc.AppendMACAddr(enc.AppendKey(e.buf, key), ha) 735 return e 736} 737