github.com/facebookincubator/go-belt@v0.0.0-20230703220935-39cd348f1a38/tool/logger/types/entry.go (about)

     1  // Copyright 2022 Meta Platforms, Inc. and affiliates.
     2  //
     3  // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
     4  //
     5  // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
     6  //
     7  // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
     8  //
     9  // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
    10  //
    11  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    12  
    13  package types
    14  
    15  import (
    16  	"time"
    17  
    18  	"github.com/facebookincubator/go-belt"
    19  	"github.com/facebookincubator/go-belt/pkg/field"
    20  	"github.com/facebookincubator/go-belt/pkg/runtime"
    21  )
    22  
    23  // Entry a single log entry to be logged/written.
    24  type Entry struct {
    25  	// Timestamp defines the time moment when the entry was issued (for example method `Debugf` was called).
    26  	Timestamp time.Time
    27  
    28  	// Level is the logging level of the entry.
    29  	Level Level
    30  
    31  	// Message is an arbitrary string explaining the event, an unstructured message.
    32  	// It is set by `*f` (e.g. `Debugf`) functions, by argument "message" in
    33  	// LogFields/TraceFields/etc function or by unstructured values in Log/Trace/Debug/etc functions.
    34  	Message string
    35  
    36  	// Fields implements ways to read the structured fields to be logged.
    37  	//
    38  	// To avoid copying the fields into an intermediate format (which most likely
    39  	// will be transformed into something else anyway in the Logger implementation)
    40  	// we provide here an accessor to Fields instead of compiled Fields themselves.
    41  	Fields field.AbstractFields
    42  
    43  	// TraceIDs is the collection of unique IDs associated with this logging entry.
    44  	// For example it may be useful to attach an unique ID to each network request,
    45  	// so that it will be possible to fetch the whole log of processing for any network request.
    46  	TraceIDs belt.TraceIDs
    47  
    48  	// Properties defines special implementation-specific behavior related to the Entry.
    49  	//
    50  	// See description of EntryProperty.
    51  	Properties EntryProperties
    52  
    53  	// Caller is the Program Counter of the position in the code which initiated the logging
    54  	// of the entry.
    55  	//
    56  	// See also OptionGetCallerFunc and DefaultGetCallerFunc.
    57  	Caller runtime.PC
    58  }
    59  
    60  // EntryProperty defines special implementation-specific behavior related to a specific Entry.
    61  //
    62  // Any Emitter implementation, Hook or other tool may use it
    63  // for internal or/and external needs.
    64  //
    65  // For example, a Emitter may support both async and sync logging,
    66  // and it could be possible to request sync logging through a property.
    67  //
    68  // Another example is: if an error monitor and a logger are hooked to each
    69  // other then these properties could be used to avoid loops (to mark
    70  // already processed entries).
    71  type EntryProperty any
    72  
    73  // EntryProperties is a collection of EntryProperty-es.
    74  type EntryProperties []EntryProperty
    75  
    76  // Has returns true if the collection of properties contains a specific EntryProperty.
    77  // It should be equal by both: type and value.
    78  func (s EntryProperties) Has(p EntryProperty) bool {
    79  	for _, cmp := range s {
    80  		if l, ok := cmp.(EntryProperties); ok {
    81  			if l.Has(p) {
    82  				return true
    83  			}
    84  			continue
    85  		}
    86  		if cmp == p {
    87  			return true
    88  		}
    89  	}
    90  	return false
    91  }
    92  
    93  // Add returns the concatenation of EntryProperties.
    94  //
    95  // Note! It does not work similar to classical `append` function,
    96  // instead it nests two slices into a new slice to optimize for CPU and RAM
    97  // (by avoiding extra memory allocation and copying).
    98  func (s EntryProperties) Add(a ...EntryProperty) EntryProperties {
    99  	switch {
   100  	case len(s) == 0:
   101  		return a
   102  	case len(a) == 0:
   103  		return s
   104  	default:
   105  		return EntryProperties{EntryProperties(s), EntryProperties(a)}
   106  	}
   107  }