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