mirror of
https://shylinux.com/x/ContextOS
synced 2025-04-25 16:58:06 +08:00
193 lines
6.1 KiB
Go
193 lines
6.1 KiB
Go
package log
|
|
|
|
import (
|
|
"contexts/ctx"
|
|
"path"
|
|
"toolkit"
|
|
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
type LOG struct {
|
|
queue chan map[string]interface{}
|
|
file map[string]*os.File
|
|
*ctx.Context
|
|
}
|
|
|
|
func (log *LOG) Log(msg *ctx.Message, action string, str string, arg ...interface{}) {
|
|
if log.queue != nil {
|
|
log.queue <- map[string]interface{}{"action": action, "str": str, "arg": arg, "msg": msg}
|
|
}
|
|
}
|
|
|
|
func (log *LOG) Value(msg *ctx.Message, arg ...interface{}) []string {
|
|
args := append(kit.Trans(arg...))
|
|
|
|
if value, ok := kit.Chain(log.Configs["output"].Value, args).(map[string]interface{}); ok {
|
|
if kit.Right(value["source"]) && kit.Format(value["source"]) != msg.Source().Name {
|
|
return nil
|
|
}
|
|
|
|
if kit.Right(value["target"]) && kit.Format(value["target"]) != msg.Target().Name {
|
|
return nil
|
|
}
|
|
return kit.Trans(value["value"])
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
|
|
return &LOG{Context: c}
|
|
}
|
|
func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
|
return log
|
|
}
|
|
func (log *LOG) Start(m *ctx.Message, arg ...string) bool {
|
|
// 创建文件
|
|
log.file = map[string]*os.File{}
|
|
m.Assert(os.MkdirAll(m.Conf("logdir"), 0770))
|
|
m.Confm("output", "file", func(key string, value string) {
|
|
switch value {
|
|
case "":
|
|
case "stderr":
|
|
log.file[key] = os.Stderr
|
|
case "stdout":
|
|
log.file[key] = os.Stdout
|
|
default:
|
|
if f, e := os.Create(path.Join(m.Conf("logdir"), value)); m.Assert(e) {
|
|
log.file[key] = f
|
|
}
|
|
}
|
|
})
|
|
|
|
// 创建队列
|
|
log.queue = make(chan map[string]interface{}, m.Confi("logbuf"))
|
|
m.Cap("stream", m.Conf("output", []string{"bench", "value", "file"}))
|
|
|
|
for {
|
|
select {
|
|
case l := <-log.queue:
|
|
m.Capi("nlog", 1)
|
|
msg := l["msg"].(*ctx.Message)
|
|
args := kit.Trans(l["arg"].([]interface{})...)
|
|
|
|
loop:
|
|
for _, v := range []string{kit.Format(l["action"]), "bench"} {
|
|
for i := len(args); i >= 0; i-- {
|
|
value := log.Value(msg, append([]string{v}, args[:i]...))
|
|
if !kit.Right(value) {
|
|
continue
|
|
}
|
|
|
|
if value[0] == "debug" && !m.Options("log.debug") {
|
|
break loop
|
|
}
|
|
|
|
// 日志文件
|
|
file := os.Stderr
|
|
if f, ok := log.file[value[0]]; ok {
|
|
file = f
|
|
} else {
|
|
break loop
|
|
}
|
|
|
|
// 日志格式
|
|
font := m.Conf("output", []string{"font", kit.Select("", value, 1)})
|
|
meta := msg.Format(m.Confv("output", []string{"meta", kit.Select("short", value, 2)}).([]interface{})...)
|
|
|
|
// 输出日志
|
|
fmt.Fprintln(file, fmt.Sprintf("%d %s %s%s %s%s", m.Capi("nout", 1), meta, font,
|
|
kit.Format(l["action"]), fmt.Sprintf(kit.Format(l["str"]), l["arg"].([]interface{})...),
|
|
kit.Select("", "\033[0m", font != "")))
|
|
break loop
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
func (log *LOG) Close(m *ctx.Message, arg ...string) bool {
|
|
return false
|
|
}
|
|
|
|
var Index = &ctx.Context{Name: "log", Help: "日志中心",
|
|
Caches: map[string]*ctx.Cache{
|
|
"nlog": &ctx.Cache{Name: "nlog", Value: "0", Help: "日志调用数量"},
|
|
"nout": &ctx.Cache{Name: "nout", Value: "0", Help: "日志输出数量"},
|
|
},
|
|
Configs: map[string]*ctx.Config{
|
|
"logbuf": &ctx.Config{Name: "logbuf", Value: "1024", Help: "日志队列长度"},
|
|
"logdir": &ctx.Config{Name: "logdir", Value: "var/log", Help: "日志目录"},
|
|
|
|
"output": &ctx.Config{Name: "output", Value: map[string]interface{}{
|
|
"file": map[string]interface{}{
|
|
"debug": "debug.log",
|
|
"bench": "bench.log",
|
|
"right": "right.log",
|
|
"error": "error.log",
|
|
},
|
|
"font": map[string]interface{}{
|
|
"red": "\033[31m",
|
|
"green": "\033[32m",
|
|
"yellow": "\033[33m",
|
|
},
|
|
"meta": map[string]interface{}{
|
|
"short": []interface{}{"time", "ship"},
|
|
"long": []interface{}{"time", "ship"},
|
|
},
|
|
|
|
"debug": map[string]interface{}{"value": []interface{}{"debug"}},
|
|
"search": map[string]interface{}{"value": []interface{}{"debug"}},
|
|
"call": map[string]interface{}{"value": []interface{}{"debug"}},
|
|
"back": map[string]interface{}{"value": []interface{}{"debug"}},
|
|
"send": map[string]interface{}{"value": []interface{}{"debug"}},
|
|
"recv": map[string]interface{}{"value": []interface{}{"debug"}},
|
|
|
|
"bench": map[string]interface{}{"value": []interface{}{"bench"}},
|
|
"begin": map[string]interface{}{"value": []interface{}{"bench", "red"}},
|
|
"start": map[string]interface{}{"value": []interface{}{"bench", "red"}},
|
|
"close": map[string]interface{}{"value": []interface{}{"bench", "red"}},
|
|
"stack": map[string]interface{}{"value": []interface{}{"bench", "yellow"}},
|
|
"warn": map[string]interface{}{"value": []interface{}{"bench", "yellow"}},
|
|
|
|
"right": map[string]interface{}{"value": []interface{}{"right"}},
|
|
|
|
"error": map[string]interface{}{"value": []interface{}{"error", "red"}},
|
|
"trace": map[string]interface{}{"value": []interface{}{"error", "red"}},
|
|
|
|
"cmd": map[string]interface{}{"value": []interface{}{"bench", "green"},
|
|
"lex": map[string]interface{}{"value": []interface{}{"debug", "green"}},
|
|
"yac": map[string]interface{}{"value": []interface{}{"debug", "green"}},
|
|
"cli": map[string]interface{}{
|
|
"cmd": map[string]interface{}{"value": []interface{}{"debug", "red"}},
|
|
},
|
|
"mdb": map[string]interface{}{
|
|
"note": map[string]interface{}{"value": []interface{}{"debug", "red"}},
|
|
},
|
|
"aaa": map[string]interface{}{
|
|
"auth": map[string]interface{}{"value": []interface{}{"debug", "red"}},
|
|
"hash": map[string]interface{}{"value": []interface{}{"debug", "red"}},
|
|
"rsa": map[string]interface{}{"value": []interface{}{"debug", "red"}},
|
|
},
|
|
},
|
|
}, Help: "日志输出配置"},
|
|
},
|
|
Commands: map[string]*ctx.Command{
|
|
"_init": &ctx.Command{Name: "_init", Help: "初始化", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
|
m.Target().Start(m)
|
|
return
|
|
}},
|
|
"log": &ctx.Command{Name: "log level string...", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
|
if log, ok := m.Target().Server.(*LOG); m.Assert(ok) {
|
|
log.Log(m, arg[0], arg[1], arg[2:])
|
|
}
|
|
return
|
|
}},
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
ctx.Index.Register(Index, &LOG{Context: Index})
|
|
}
|