1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
package logger
import (
"fmt"
"os"
"path"
"regexp"
"strconv"
"strings"
"time"
)
type logFile struct {
FileInfo os.FileInfo
Index int
}
type sortLogFiles struct {
Items []logFile
}
func (sf *sortLogFiles) Len() int {
return len(sf.Items)
}
func (sf *sortLogFiles) Less(i, j int) bool {
return sf.Items[j].Index < sf.Items[i].Index
}
func (sf *sortLogFiles) Swap(i, j int) {
item := sf.Items[i]
sf.Items[i] = sf.Items[j]
sf.Items[j] = item
}
func findStringSubmatchIndexes(r *regexp.Regexp, s string) map[string][2]int {
captures := make(map[string][2]int)
ind := r.FindStringSubmatchIndex(s)
names := r.SubexpNames()
for i, name := range names {
if name != "" && i < len(ind)/2 {
if ind[i*2] != -1 && ind[i*2+1] != -1 {
captures[name] = [2]int{ind[i*2], ind[i*2+1]}
}
}
}
return captures
}
func extractIndex(item os.FileInfo) int {
r := regexp.MustCompile(`.+\.log(\.(?P<index>\d+))?`)
fileName := path.Base(item.Name())
m := findStringSubmatchIndexes(r, fileName)
if v, ok := m["index"]; ok {
i, _ := strconv.Atoi(fileName[v[0]:v[1]])
return i
} else {
return 0
}
}
const (
nocolor = 0
red = 31
green = 32
yellow = 33
blue = 34
gray = 37
)
type IndentKind int
const (
LeftIndent = iota
CenterIndent
RightIndent
)
func cutOrIndentText(text string, length int, indent IndentKind) string {
if length < 0 {
return text
} else if len(text) > length {
text = text[:length]
} else {
switch indent {
case LeftIndent:
text = text + strings.Repeat(" ", length-len(text))
case RightIndent:
text = strings.Repeat(" ", length-len(text)) + text
case CenterIndent:
text = strings.Repeat(" ", (length-len(text))/2) + text +
strings.Repeat(" ", length-len(text)-(length-len(text))/2)
}
}
return text
}
func metaFmtStr(colored bool, level LogLevel, options FormatOptions, appName string,
packageName string, message string, format string) string {
var colorPfx, colorSfx string
if colored {
var levelColor int
switch level {
case DebugLevel:
levelColor = gray
case InfoLevel:
levelColor = blue
case NotifyLevel, WarnLevel:
levelColor = yellow
case ErrorLevel, PanicLevel, FatalLevel:
levelColor = red
default:
levelColor = nocolor
}
colorPfx = "\x1b[" + strconv.Itoa(levelColor) + "m"
colorSfx = "\x1b[0m"
}
arg1 := time.Now().Format(options.TimeFormat)
arg2 := appName
arg3 := cutOrIndentText(packageName, options.PackageLength, RightIndent)
lvlStr := options.GetLevelStr(level)
lvlLen := len([]rune(lvlStr))
arg4 := colorPfx + cutOrIndentText(strings.ToUpper(lvlStr), lvlLen, LeftIndent) + colorSfx
arg5 := message
out := fmt.Sprintf(format, arg1, arg2, arg3, arg4, arg5)
return out
}
func getApplicationName() string {
appName := os.Args[0]
return appName
}
|