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}