fortio.org/log@v1.12.2/console_logging.go (about) 1 // Copyright 2023 Fortio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package log 16 17 import ( 18 "fmt" 19 "os" 20 "time" 21 22 "fortio.org/log/goroutine" 23 ) 24 25 // to avoid making a new package/namespace for colors, we use a struct. 26 type color struct { 27 Reset string 28 Red string 29 Green string 30 Yellow string 31 Blue string 32 Purple string 33 Cyan string 34 Gray string 35 White string 36 BrightRed string 37 DarkGray string 38 } 39 40 var ( 41 // these should really be constants but go doesn't have constant structs, arrays etc... 42 43 // ANSI color codes. 44 // This isn't meant to be used directly and is here only to document the names of the struct. 45 // Use the Colors variable instead. 46 ANSIColors = color{ 47 Reset: "\033[0m", 48 Red: "\033[31m", 49 Green: "\033[32m", 50 Yellow: "\033[33m", 51 Blue: "\033[34m", 52 Purple: "\033[35m", 53 Cyan: "\033[36m", 54 Gray: "\033[37m", 55 White: "\033[97m", 56 BrightRed: "\033[91m", 57 DarkGray: "\033[90m", 58 } 59 60 // ANSI color codes or empty depending on ColorMode. 61 // These will be reset to empty string if color is disabled (see ColorMode() and SetColorMode()). 62 // Start with actual colors, will be reset to empty if color is disabled. 63 Colors = ANSIColors 64 65 // Mapping of log levels to color. 66 LevelToColor = []string{ 67 Colors.Gray, 68 Colors.Cyan, 69 Colors.Green, 70 Colors.Yellow, 71 Colors.Red, 72 Colors.Purple, 73 Colors.BrightRed, 74 Colors.Green, // NoLevel log.Printf 75 } 76 // Used for color version of console logging. 77 LevelToText = []string{ 78 "DBG", 79 "VRB", 80 "INF", 81 "WRN", 82 "ERR", 83 "CRI", 84 "FTL", 85 "", 86 } 87 // Cached flag for whether to use color output or not. 88 Color = false 89 ) 90 91 // ConsoleLogging is a utility to check if the current logger output is a console (terminal). 92 func ConsoleLogging() bool { 93 f, ok := jWriter.w.(*os.File) 94 if !ok { 95 return false 96 } 97 s, _ := f.Stat() 98 return (s.Mode() & os.ModeCharDevice) == os.ModeCharDevice 99 } 100 101 // SetColorMode computes whether we currently should be using color text mode or not. 102 // Need to be reset if config changes (but is already automatically re evaluated when calling SetOutput()). 103 // It will reset the Colors variable to either be the actual escape sequences or empty strings (when 104 // color is disabled). 105 func SetColorMode() { 106 Color = ColorMode() 107 if Color { 108 Colors = ANSIColors 109 } else { 110 Colors = color{} 111 } 112 // Also reset the level to color mapping to empty or customized colors, as needed. 113 LevelToColor = []string{ 114 Colors.Gray, 115 Colors.Cyan, 116 Colors.Green, 117 Colors.Yellow, 118 Colors.Red, 119 Colors.Purple, 120 Colors.BrightRed, 121 Colors.Green, // NoLevel log.Printf 122 } 123 } 124 125 // ColorMode returns true if we should be using color text mode, which is either because it's 126 // forced or because we are in a console and the config allows it. 127 // Should not be called often, instead read/update the Color variable when needed. 128 func ColorMode() bool { 129 return Config.ForceColor || (Config.ConsoleColor && ConsoleLogging()) 130 } 131 132 func colorTimestamp() string { 133 if Config.NoTimestamp { 134 return "" 135 } 136 return time.Now().Format(Colors.DarkGray + "15:04:05.000 ") 137 } 138 139 // Color version of jsonGID(). 140 func colorGID() string { 141 if !Config.GoroutineID { 142 return "" 143 } 144 return Colors.Gray + fmt.Sprintf("r%d ", goroutine.ID()) 145 } 146 147 // Longer version when colorizing on console of the level text. 148 func ColorLevelToStr(lvl Level) string { 149 if lvl == NoLevel { 150 return Colors.DarkGray 151 } 152 return Colors.DarkGray + "[" + LevelToColor[lvl] + LevelToText[lvl] + Colors.DarkGray + "]" 153 }