-
Notifications
You must be signed in to change notification settings - Fork 42
/
log.go
108 lines (95 loc) · 2.48 KB
/
log.go
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
package yaklib
import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"github.com/kataras/golog"
"github.com/yaklang/yaklang/common/log"
"github.com/yaklang/yaklang/common/yak/antlr4yak"
"github.com/yaklang/yaklang/common/yak/antlr4yak/yakvm"
)
// loglevel 根据传入的字符串设置日志级别
// disable: 禁用所有日志, fatal: 致命错误, error: 错误, warning: 警告, info: 信息, debug: 调试
// Example:
// ```
// loglevel("fatal")
// ```
func setLogLevel(i interface{}) {
l, err := log.ParseLevel(fmt.Sprint(i))
if err != nil {
log.Errorf("parse %v(loglevel) error: %v, default: warning", i, err)
log.SetLevel(log.WarnLevel)
return
}
log.SetLevel(l)
_logs.Range(func(key, value interface{}) bool {
value.(*log.Logger).SetLevel(fmt.Sprint(i))
return true
})
}
type logFunc func(fmtStr string, items ...interface{})
var _logs = new(sync.Map)
func _fixYakModName(name string) string {
_, file := filepath.Split(name)
if file == "" {
return "__main__.yak"
}
if strings.HasSuffix(strings.ToLower(file), ".yak") {
return file
} else {
return file + ".yak"
}
}
type YakLogger struct {
*log.Logger
SetLevel func(string) *golog.Logger
}
func CreateYakLogger(yakFiles ...string) *YakLogger {
var yakFile string
if len(yakFiles) > 0 {
yakFile = yakFiles[0]
}
var logger *log.Logger
loggerRaw, ok := _logs.Load(_fixYakModName(yakFile))
if !ok {
logger = log.GetLogger(_fixYakModName(yakFile))
logger.SetOutput(os.Stdout)
logger.Level = log.DefaultLogger.Level
logger.Printer.IsTerminal = true
_logs.Store(_fixYakModName(yakFile), logger)
} else {
logger = loggerRaw.(*log.Logger)
}
res := &YakLogger{Logger: logger}
res.SetLevel = logger.SetLevel
return res
}
func (y *YakLogger) SetEngine(engine *antlr4yak.Engine) {
y.Logger.SetVMRuntimeInfoGetter(func(infoType string) (res any, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("%v", e)
}
}()
frame := engine.GetVM().VMStack.Peek()
if frame == nil {
return nil, fmt.Errorf("not found runtime.GetInfo")
}
f := frame.(*yakvm.Frame).GlobalVariables["runtime"].(map[string]any)["GetInfo"].(func(string, ...any) (any, error))
return f(infoType)
})
}
var LogExports = map[string]interface{}{
"info": log.Infof,
"setLevel": setLogLevel,
"debug": log.Debugf,
"warn": log.Warningf,
"error": log.Errorf,
"Info": log.Infof,
"SetLevel": setLogLevel,
"Debug": log.Debugf,
"Warn": log.Warningf,
"Error": log.Errorf,
}