log.go

  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
  7package log
  8
  9import (
 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.
 20type Event string
 21
 22// SetEvents is used to control which events are written to
 23// the log.  By default all log events are writen.
 24func SetEvents(cls ...Event) {
 25	log.cls = cls
 26}
 27
 28// SetListener will set the Logger to write to the specified listener.
 29func 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.
 43func Should(cls Event) bool {
 44	if log.lst == nil {
 45		return false
 46	}
 47	if log.cls == nil || 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.
 60func 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.
 69func 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.
 77func TestResetEvents() {
 78	log.cls = nil
 79}
 80
 81// logger controls which events to log and writing to the underlying log.
 82type logger struct {
 83	cls []Event
 84	lst func(Event, string)
 85}
 86
 87// the process-wide logger
 88var log logger
 89
 90func init() {
 91	initLogging()
 92}
 93
 94// split out for testing purposes
 95func 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}