github.com/Laisky/zap@v1.27.0/zapcore/core.go (about)

     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  
    21  package zapcore
    22  
    23  // Core is a minimal, fast logger interface. It's designed for library authors
    24  // to wrap in a more user-friendly API.
    25  type Core interface {
    26  	LevelEnabler
    27  
    28  	// With adds structured context to the Core.
    29  	With([]Field) Core
    30  	// Check determines whether the supplied Entry should be logged (using the
    31  	// embedded LevelEnabler and possibly some extra logic). If the entry
    32  	// should be logged, the Core adds itself to the CheckedEntry and returns
    33  	// the result.
    34  	//
    35  	// Callers must use Check before calling Write.
    36  	Check(Entry, *CheckedEntry) *CheckedEntry
    37  	// Write serializes the Entry and any Fields supplied at the log site and
    38  	// writes them to their destination.
    39  	//
    40  	// If called, Write should always log the Entry and Fields; it should not
    41  	// replicate the logic of Check.
    42  	Write(Entry, []Field) error
    43  	// Sync flushes buffered logs (if any).
    44  	Sync() error
    45  	// Fields returns the fields embedded in the Core.
    46  	Fields() []Field
    47  }
    48  
    49  type nopCore struct{}
    50  
    51  // NewNopCore returns a no-op Core.
    52  func NewNopCore() Core                                        { return nopCore{} }
    53  func (nopCore) Enabled(Level) bool                            { return false }
    54  func (n nopCore) With([]Field) Core                           { return n }
    55  func (nopCore) Check(_ Entry, ce *CheckedEntry) *CheckedEntry { return ce }
    56  func (nopCore) Write(Entry, []Field) error                    { return nil }
    57  func (nopCore) Sync() error                                   { return nil }
    58  func (nopCore) Fields() []Field                               { return nil }
    59  
    60  // NewCore creates a Core that writes logs to a WriteSyncer.
    61  func NewCore(enc Encoder, ws WriteSyncer, enab LevelEnabler) Core {
    62  	return &ioCore{
    63  		LevelEnabler: enab,
    64  		enc:          enc,
    65  		out:          ws,
    66  	}
    67  }
    68  
    69  type ioCore struct {
    70  	LevelEnabler
    71  	enc    Encoder
    72  	out    WriteSyncer
    73  	fields []Field
    74  }
    75  
    76  var (
    77  	_ Core           = (*ioCore)(nil)
    78  	_ leveledEnabler = (*ioCore)(nil)
    79  )
    80  
    81  func (c *ioCore) Level() Level {
    82  	return LevelOf(c.LevelEnabler)
    83  }
    84  
    85  func (c *ioCore) With(fields []Field) Core {
    86  	clone := c.clone()
    87  	addFields(clone.enc, fields)
    88  	clone.fields = append(c.fields[:len(c.fields):len(c.fields)], fields...)
    89  	return clone
    90  }
    91  
    92  func (c *ioCore) Fields() []Field {
    93  	return c.fields
    94  }
    95  
    96  func (c *ioCore) Check(ent Entry, ce *CheckedEntry) *CheckedEntry {
    97  	if c.Enabled(ent.Level) {
    98  		return ce.AddCore(ent, c)
    99  	}
   100  	return ce
   101  }
   102  
   103  func (c *ioCore) Write(ent Entry, fields []Field) error {
   104  	buf, err := c.enc.EncodeEntry(ent, fields)
   105  	if err != nil {
   106  		return err
   107  	}
   108  	_, err = c.out.Write(buf.Bytes())
   109  	buf.Free()
   110  	if err != nil {
   111  		return err
   112  	}
   113  	if ent.Level > ErrorLevel {
   114  		// Since we may be crashing the program, sync the output.
   115  		// Ignore Sync errors, pending a clean solution to issue #370.
   116  		_ = c.Sync()
   117  	}
   118  	return nil
   119  }
   120  
   121  func (c *ioCore) Sync() error {
   122  	return c.out.Sync()
   123  }
   124  
   125  func (c *ioCore) clone() *ioCore {
   126  	return &ioCore{
   127  		LevelEnabler: c.LevelEnabler,
   128  		enc:          c.enc.Clone(),
   129  		out:          c.out,
   130  		fields:       c.fields,
   131  	}
   132  }