...

Source file src/go.mongodb.org/mongo-driver/mongo/integration/unified/logger.go

Documentation: go.mongodb.org/mongo-driver/mongo/integration/unified

     1  // Copyright (C) MongoDB, Inc. 2023-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package unified
     8  
     9  import (
    10  	"context"
    11  	"sync"
    12  
    13  	"go.mongodb.org/mongo-driver/internal/logger"
    14  )
    15  
    16  // orderedLogMessage is a logMessage with an "order" field representing the
    17  // order in which the log message was observed.
    18  type orderedLogMessage struct {
    19  	*logMessage
    20  	order int
    21  }
    22  
    23  // Logger is the Sink used to captured log messages for logger verification in
    24  // the unified spec tests.
    25  type Logger struct {
    26  	// bufSize is the number of logs expected to be sent to the logger for a
    27  	// unified spec test.
    28  	bufSize int
    29  
    30  	// lastOrder increments each time the "Info" method is called, and is used to
    31  	// determine when to close the logQueue.
    32  	lastOrder int
    33  
    34  	// orderMu guards the order value, which increments each time the "Info"
    35  	// method is called. This is necessary since "Info" could be called from
    36  	// multiple go routines, e.g. SDAM logs.
    37  	orderMu        sync.RWMutex
    38  	logQueue       chan orderedLogMessage
    39  	ignoreMessages []*logMessage
    40  }
    41  
    42  func newLogger(olm *observeLogMessages, bufSize int, ignoreMessages []*logMessage) *Logger {
    43  	if olm == nil {
    44  		return nil
    45  	}
    46  
    47  	return &Logger{
    48  		lastOrder:      1,
    49  		logQueue:       make(chan orderedLogMessage, bufSize),
    50  		bufSize:        bufSize,
    51  		ignoreMessages: ignoreMessages,
    52  	}
    53  }
    54  
    55  // Info implements the logger.Sink interface's "Info" method for printing log
    56  // messages.
    57  func (log *Logger) Info(level int, msg string, args ...interface{}) {
    58  	log.orderMu.Lock()
    59  	defer log.orderMu.Unlock()
    60  
    61  	if log.logQueue == nil {
    62  		return
    63  	}
    64  
    65  	// If the order is greater than the buffer size, we must return. This
    66  	// would indicate that the logQueue channel has been closed.
    67  	if log.lastOrder > log.bufSize {
    68  		return
    69  	}
    70  
    71  	// Add the Diff back to the level, as there is no need to create a
    72  	// logging offset.
    73  	level = level + logger.DiffToInfo
    74  
    75  	logMessage, err := newLogMessage(level, msg, args...)
    76  	if err != nil {
    77  		panic(err)
    78  	}
    79  
    80  	for _, ignoreMessage := range log.ignoreMessages {
    81  		if err := verifyLogMatch(context.Background(), ignoreMessage, logMessage); err == nil {
    82  			return
    83  		}
    84  	}
    85  
    86  	defer func() { log.lastOrder++ }()
    87  
    88  	// Send the log message to the "orderedLogMessage" channel for
    89  	// validation.
    90  	log.logQueue <- orderedLogMessage{
    91  		order:      log.lastOrder + 1,
    92  		logMessage: logMessage}
    93  
    94  	// If the order has reached the buffer size, then close the channel.
    95  	if log.lastOrder == log.bufSize {
    96  		close(log.logQueue)
    97  	}
    98  }
    99  
   100  // Error implements the logger.Sink interface's "Error" method for printing log
   101  // errors. In this case, if an error occurs we will simply treat it as
   102  // informational.
   103  func (log *Logger) Error(err error, msg string, args ...interface{}) {
   104  	args = append(args, "error", err)
   105  	log.Info(int(logger.LevelInfo), msg, args)
   106  }
   107  

View as plain text