core.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright (c) 2016 Uber Technologies, Inc.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. package zapcore
  21. // Core is a minimal, fast logger interface. It's designed for library authors
  22. // to wrap in a more user-friendly API.
  23. type Core interface {
  24. LevelEnabler
  25. // With adds structured context to the Core.
  26. With([]Field) Core
  27. // Check determines whether the supplied Entry should be logged (using the
  28. // embedded LevelEnabler and possibly some extra logic). If the entry
  29. // should be logged, the Core adds itself to the CheckedEntry and returns
  30. // the result.
  31. //
  32. // Callers must use Check before calling Write.
  33. Check(Entry, *CheckedEntry) *CheckedEntry
  34. // Write serializes the Entry and any Fields supplied at the log site and
  35. // writes them to their destination.
  36. //
  37. // If called, Write should always log the Entry and Fields; it should not
  38. // replicate the logic of Check.
  39. Write(Entry, []Field) error
  40. // Sync flushes buffered logs (if any).
  41. Sync() error
  42. }
  43. type nopCore struct{}
  44. // NewNopCore returns a no-op Core.
  45. func NewNopCore() Core { return nopCore{} }
  46. func (nopCore) Enabled(Level) bool { return false }
  47. func (n nopCore) With([]Field) Core { return n }
  48. func (nopCore) Check(_ Entry, ce *CheckedEntry) *CheckedEntry { return ce }
  49. func (nopCore) Write(Entry, []Field) error { return nil }
  50. func (nopCore) Sync() error { return nil }
  51. // NewCore creates a Core that writes logs to a WriteSyncer.
  52. func NewCore(enc Encoder, ws WriteSyncer, enab LevelEnabler) Core {
  53. return &ioCore{
  54. LevelEnabler: enab,
  55. enc: enc,
  56. out: ws,
  57. }
  58. }
  59. type ioCore struct {
  60. LevelEnabler
  61. enc Encoder
  62. out WriteSyncer
  63. }
  64. func (c *ioCore) With(fields []Field) Core {
  65. clone := c.clone()
  66. addFields(clone.enc, fields)
  67. return clone
  68. }
  69. func (c *ioCore) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
  70. if c.Enabled(ent.Level) {
  71. return ce.AddCore(ent, c)
  72. }
  73. return ce
  74. }
  75. func (c *ioCore) Write(ent Entry, fields []Field) error {
  76. buf, err := c.enc.EncodeEntry(ent, fields)
  77. if err != nil {
  78. return err
  79. }
  80. _, err = c.out.Write(buf.Bytes())
  81. buf.Free()
  82. if err != nil {
  83. return err
  84. }
  85. if ent.Level > ErrorLevel {
  86. // Since we may be crashing the program, sync the output. Ignore Sync
  87. // errors, pending a clean solution to issue #370.
  88. c.Sync()
  89. }
  90. return nil
  91. }
  92. func (c *ioCore) Sync() error {
  93. return c.out.Sync()
  94. }
  95. func (c *ioCore) clone() *ioCore {
  96. return &ioCore{
  97. LevelEnabler: c.LevelEnabler,
  98. enc: c.enc.Clone(),
  99. out: c.out,
  100. }
  101. }