log.go raw

   1  //go:build go1.18
   2  // +build go1.18
   3  
   4  // Copyright (c) Microsoft Corporation. All rights reserved.
   5  // Licensed under the MIT License.
   6  
   7  package log
   8  
   9  import (
  10  	"fmt"
  11  	"os"
  12  	"time"
  13  )
  14  
  15  ///////////////////////////////////////////////////////////////////////////////////////////////////
  16  // NOTE: The following are exported as public surface area from azcore.  DO NOT MODIFY
  17  ///////////////////////////////////////////////////////////////////////////////////////////////////
  18  
  19  // Event is used to group entries.  Each group can be toggled on or off.
  20  type Event string
  21  
  22  // SetEvents is used to control which events are written to
  23  // the log.  By default all log events are writen.
  24  func SetEvents(cls ...Event) {
  25  	log.cls = cls
  26  }
  27  
  28  // SetListener will set the Logger to write to the specified listener.
  29  func SetListener(lst func(Event, string)) {
  30  	log.lst = lst
  31  }
  32  
  33  ///////////////////////////////////////////////////////////////////////////////////////////////////
  34  // END PUBLIC SURFACE AREA
  35  ///////////////////////////////////////////////////////////////////////////////////////////////////
  36  
  37  // Should returns true if the specified log event should be written to the log.
  38  // By default all log events will be logged.  Call SetEvents() to limit
  39  // the log events for logging.
  40  // If no listener has been set this will return false.
  41  // Calling this method is useful when the message to log is computationally expensive
  42  // and you want to avoid the overhead if its log event is not enabled.
  43  func Should(cls Event) bool {
  44  	if log.lst == nil {
  45  		return false
  46  	}
  47  	if len(log.cls) == 0 {
  48  		return true
  49  	}
  50  	for _, c := range log.cls {
  51  		if c == cls {
  52  			return true
  53  		}
  54  	}
  55  	return false
  56  }
  57  
  58  // Write invokes the underlying listener with the specified event and message.
  59  // If the event shouldn't be logged or there is no listener then Write does nothing.
  60  func Write(cls Event, message string) {
  61  	if !Should(cls) {
  62  		return
  63  	}
  64  	log.lst(cls, message)
  65  }
  66  
  67  // Writef invokes the underlying listener with the specified event and formatted message.
  68  // If the event shouldn't be logged or there is no listener then Writef does nothing.
  69  func Writef(cls Event, format string, a ...interface{}) {
  70  	if !Should(cls) {
  71  		return
  72  	}
  73  	log.lst(cls, fmt.Sprintf(format, a...))
  74  }
  75  
  76  // TestResetEvents is used for TESTING PURPOSES ONLY.
  77  func TestResetEvents() {
  78  	log.cls = nil
  79  }
  80  
  81  // logger controls which events to log and writing to the underlying log.
  82  type logger struct {
  83  	cls []Event
  84  	lst func(Event, string)
  85  }
  86  
  87  // the process-wide logger
  88  var log logger
  89  
  90  func init() {
  91  	initLogging()
  92  }
  93  
  94  // split out for testing purposes
  95  func initLogging() {
  96  	if cls := os.Getenv("AZURE_SDK_GO_LOGGING"); cls == "all" {
  97  		// cls could be enhanced to support a comma-delimited list of log events
  98  		log.lst = func(cls Event, msg string) {
  99  			// simple console logger, it writes to stderr in the following format:
 100  			// [time-stamp] Event: message
 101  			fmt.Fprintf(os.Stderr, "[%s] %s: %s\n", time.Now().Format(time.StampMicro), cls, msg)
 102  		}
 103  	}
 104  }
 105