github.com/fafucoder/cilium@v1.6.11/pkg/endpoint/log.go (about)

     1  // Copyright 2017-2019 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package endpoint
    16  
    17  import (
    18  	"sync/atomic"
    19  	"unsafe"
    20  
    21  	"github.com/cilium/cilium/pkg/logging"
    22  	"github.com/cilium/cilium/pkg/logging/logfields"
    23  
    24  	"github.com/cilium/cilium/pkg/option"
    25  	"github.com/sirupsen/logrus"
    26  )
    27  
    28  var (
    29  	Subsystem = "endpoint"
    30  	log       = logging.DefaultLogger.WithField(logfields.LogSubsys, Subsystem)
    31  )
    32  
    33  const (
    34  	fieldRegenLevel = "regeneration-level"
    35  )
    36  
    37  // getLogger returns a logrus object with EndpointID, ContainerID and the Endpoint
    38  // revision fields.
    39  func (e *Endpoint) getLogger() *logrus.Entry {
    40  	v := atomic.LoadPointer(&e.logger)
    41  	return (*logrus.Entry)(v)
    42  }
    43  
    44  // Logger returns a logrus object with EndpointID, ContainerID and the Endpoint
    45  // revision fields. The caller must specify their subsystem.
    46  func (e *Endpoint) Logger(subsystem string) *logrus.Entry {
    47  	if e == nil {
    48  		return log.WithField(logfields.LogSubsys, subsystem)
    49  	}
    50  
    51  	return e.getLogger().WithField(logfields.LogSubsys, subsystem)
    52  }
    53  
    54  // UpdateLogger creates a logger instance specific to this endpoint. It will
    55  // create a custom Debug logger for this endpoint when the option on it is set.
    56  // If fields is not nil only the those specific fields will be updated in the
    57  // endpoint's logger, otherwise a full update of those fields is executed.
    58  // Note: You must hold Endpoint.Mutex for reading if fields is nil.
    59  func (e *Endpoint) UpdateLogger(fields map[string]interface{}) {
    60  	v := atomic.LoadPointer(&e.logger)
    61  	epLogger := (*logrus.Entry)(v)
    62  	if fields != nil && epLogger != nil {
    63  		newLogger := epLogger.WithFields(fields)
    64  		atomic.StorePointer(&e.logger, unsafe.Pointer(newLogger))
    65  		return
    66  	}
    67  
    68  	// We need to update if
    69  	// - e.logger is nil (this happens on the first ever call to UpdateLogger via
    70  	//   Logger above). This clause has to come first to guard the others.
    71  	// - If any of EndpointID, ContainerID or policyRevision are different on the
    72  	//   endpoint from the logger.
    73  	// - The debug option on the endpoint is true, and the logger is not debug,
    74  	//   or vice versa.
    75  	shouldUpdate := epLogger == nil || (e.Options != nil &&
    76  		e.Options.IsEnabled(option.Debug) != (epLogger.Level == logrus.DebugLevel))
    77  
    78  	// do nothing if we do not need an update
    79  	if !shouldUpdate {
    80  		return
    81  	}
    82  
    83  	// default to using the log var set above
    84  	baseLogger := log.Logger
    85  
    86  	// If this endpoint is set to debug ensure it will print debug by giving it
    87  	// an independent logger
    88  	if e.Options != nil && e.Options.IsEnabled(option.Debug) {
    89  		baseLogger = logging.InitializeDefaultLogger()
    90  		baseLogger.SetLevel(logrus.DebugLevel)
    91  	}
    92  
    93  	// When adding new fields, make sure they are abstracted by a setter
    94  	// and update the logger when the value is set.
    95  	l := baseLogger.WithFields(logrus.Fields{
    96  		logfields.LogSubsys:              Subsystem,
    97  		logfields.EndpointID:             e.ID,
    98  		logfields.ContainerID:            e.getShortContainerID(),
    99  		logfields.DatapathPolicyRevision: e.policyRevision,
   100  		logfields.DesiredPolicyRevision:  e.nextPolicyRevision,
   101  		logfields.IPv4:                   e.IPv4.String(),
   102  		logfields.IPv6:                   e.IPv6.String(),
   103  		logfields.K8sPodName:             e.GetK8sNamespaceAndPodNameLocked(),
   104  	})
   105  
   106  	if e.SecurityIdentity != nil {
   107  		l = l.WithField(logfields.Identity, e.SecurityIdentity.ID.StringID())
   108  	}
   109  
   110  	atomic.StorePointer(&e.logger, unsafe.Pointer(l))
   111  }