diff --git a/base/log/log.go b/base/log/log.go index fc33825a..c12fcb94 100644 --- a/base/log/log.go +++ b/base/log/log.go @@ -3,7 +3,9 @@ package log import ( "bufio" "fmt" + "os" "path" + "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/lex" @@ -103,3 +105,22 @@ var Index = &ice.Context{Name: LOG, Help: "日志模块", Configs: ice.Configs{ }} func init() { ice.Index.Register(Index, &Frame{}, TAIL) } + +const ( + LOG_TRACE = "log_trace" +) + +func Traceid() (traceid string) { + ls := []string{} + kit.For(kit.Split(os.Getenv(LOG_TRACE)), func(key string) { + switch key { + case "short": + ls = append(ls, kit.Hashs(mdb.UNIQ)[:6]) + case "long": + ls = append(ls, kit.Hashs(mdb.UNIQ)) + case "node": + ls = append(ls, ice.Info.NodeName) + } + }) + return strings.Join(ls, "-") +} diff --git a/base/mdb/hash.go b/base/mdb/hash.go index 25b8f74e..9ea894fa 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -23,7 +23,7 @@ func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) { kit.For(list, func(k string, i int) { m.Push(field, k).Push(COUNT, i) }) m.SortIntR(COUNT) }() - defer RLock(m, prefix, chain)() + defer RLock(m, prefix)() Richs(m, prefix, chain, FOREACH, func(key string, value Map) { value = kit.GetMeta(value) list[kit.Format(value[field])] += kit.Int(kit.Select("1", value[COUNT])) @@ -31,7 +31,7 @@ func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) { } func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) string { m.Logs(INSERT, KEY, path.Join(prefix, chain), arg) - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() if expire := m.Conf(prefix, kit.Keys(chain, kit.Keym(EXPIRE))); expire != "" && arg[0] != HASH { arg = kit.Simple(TIME, m.Time(expire), arg) } @@ -44,7 +44,7 @@ func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) string { return m.Result() } func _hash_delete(m *ice.Message, prefix, chain, field, value string) { - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() Richs(m, prefix, chain, value, func(key string, val Map) { if target, ok := kit.GetMeta(val)[TARGET].(io.Closer); ok { target.Close() @@ -56,7 +56,7 @@ func _hash_delete(m *ice.Message, prefix, chain, field, value string) { } func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) { m.Logs(MODIFY, KEY, path.Join(prefix, chain), field, value, arg) - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() Richs(m, prefix, chain, value, func(key string, val Map) { saveImportant(m, prefix, chain, kit.Simple(MODIFY, prefix, chain, HASH, HASH, key, arg)...) _mdb_modify(m, val, field, arg...) @@ -66,18 +66,18 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) { kit.If(field == HASH && value == RANDOM, func() { value = RANDOMS }) defer m.SortStrR(TIME) fields := _hash_fields(m) - defer RLock(m, prefix, chain)() + defer RLock(m, prefix)() Richs(m, prefix, chain, value, func(key string, value Map) { _mdb_select(m, m.OptionCB(""), key, value, fields, nil) }) } func _hash_select_field(m *ice.Message, prefix, chain string, key string, field string) (value string) { - defer RLock(m, prefix, chain)() + defer RLock(m, prefix)() Richs(m, prefix, chain, key, func(key string, val Map) { value = kit.Select(kit.Format(val[field]), key, field == HASH) }) return } func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) { fields := _hash_fields(m) kit.If(kit.IndexOf(fields, HASH) == -1, func() { fields = append(fields, HASH) }) - defer RLock(m, prefix, chain)() + defer RLock(m, prefix)() Richs(m, prefix, chain, FOREACH, func(key string, value Map) { switch value = kit.GetMeta(value); cb := m.OptionCB("").(type) { case func(string, Map) bool: @@ -90,7 +90,7 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) { }) } func _hash_export(m *ice.Message, prefix, chain, file string) { - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() count := len(Confm(m, prefix, kit.Keys(chain, HASH))) p := kit.Keys(file, JSON) if count == 0 { @@ -110,7 +110,7 @@ func _hash_export(m *ice.Message, prefix, chain, file string) { } } func _hash_import(m *ice.Message, prefix, chain, file string) { - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() f, e := ice.Info.Open(m, kit.Keys(file, JSON)) if os.IsNotExist(e) { return diff --git a/base/mdb/list.go b/base/mdb/list.go index c98c0986..ace26115 100644 --- a/base/mdb/list.go +++ b/base/mdb/list.go @@ -20,7 +20,7 @@ func _list_inputs(m *ice.Message, prefix, chain string, field, value string) { kit.For(list, func(k string, i int) { m.Push(field, k).Push(COUNT, i) }) m.SortIntR(COUNT) }() - defer RLock(m, prefix, chain)() + defer RLock(m, prefix)() Grows(m, prefix, chain, "", "", func(value ice.Map) { value = kit.GetMeta(value) list[kit.Format(value[field])] += kit.Int(kit.Select("1", value[COUNT])) @@ -28,26 +28,26 @@ func _list_inputs(m *ice.Message, prefix, chain string, field, value string) { } func _list_insert(m *ice.Message, prefix, chain string, arg ...string) { m.Logs(INSERT, KEY, path.Join(prefix, chain), arg) - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() saveImportant(m, prefix, chain, kit.Simple(INSERT, prefix, chain, LIST, TIME, m.Time(), arg)...) m.Echo("%d", Grow(m, prefix, chain, kit.Dict(arg, TARGET, m.Optionv(TARGET)))) } func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) { m.Logs(MODIFY, KEY, path.Join(prefix, chain), field, value, arg) - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() saveImportant(m, prefix, chain, kit.Simple(MODIFY, prefix, chain, LIST, field, value, arg)...) Grows(m, prefix, chain, field, value, func(index int, val ice.Map) { _mdb_modify(m, val, field, arg...) }) } func _list_select(m *ice.Message, prefix, chain, field, value string) { defer m.SortIntR(ID) fields := _list_fields(m) - defer RLock(m, prefix, chain)() + defer RLock(m, prefix)() Grows(m, prefix, chain, kit.Select(m.Option(CACHE_FIELD), field), kit.Select(m.Option(CACHE_VALUE), value), func(value ice.Map) { _mdb_select(m, m.OptionCB(""), "", value, fields, nil) }) } func _list_export(m *ice.Message, prefix, chain, file string) { - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() f, p, e := miss.CreateFile(kit.Keys(file, CSV)) m.Assert(e) defer f.Close() @@ -68,7 +68,7 @@ func _list_export(m *ice.Message, prefix, chain, file string) { m.Conf(prefix, kit.Keys(chain, LIST), "") } func _list_import(m *ice.Message, prefix, chain, file string) { - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() f, e := miss.OpenFile(kit.Keys(file, CSV)) m.Assert(e) defer f.Close() diff --git a/base/mdb/zone.go b/base/mdb/zone.go index 44f265ca..f0cd1650 100644 --- a/base/mdb/zone.go +++ b/base/mdb/zone.go @@ -13,7 +13,7 @@ import ( ) func _zone_meta(m *ice.Message, prefix, chain, key string) string { - defer RLock(m, prefix, chain)() + defer RLock(m, prefix)() return m.Conf(prefix, kit.Keys(chain, kit.Keym(key))) } func _zone_fields(m *ice.Message) []string { @@ -25,7 +25,6 @@ func _zone_inputs(m *ice.Message, prefix, chain, zone string, field, value strin return } h := _hash_select_field(m, prefix, chain, zone, HASH) - defer RLock(m, prefix, chain)() _list_inputs(m, prefix, kit.Keys(chain, HASH, h), field, value) } func _zone_insert(m *ice.Message, prefix, chain, zone string, arg ...string) { @@ -34,13 +33,11 @@ func _zone_insert(m *ice.Message, prefix, chain, zone string, arg ...string) { h = _hash_insert(m, prefix, chain, kit.Select(ZONE, _zone_meta(m, prefix, chain, SHORT)), zone) } m.Assert(h != "") - defer Lock(m, prefix, chain)() _list_insert(m, prefix, kit.Keys(chain, HASH, h), arg...) } func _zone_modify(m *ice.Message, prefix, chain, zone, id string, arg ...string) { h := _hash_select_field(m, prefix, chain, zone, HASH) m.Assert(h != "") - defer Lock(m, prefix, chain)() _list_modify(m, prefix, kit.Keys(chain, HASH, h), ID, id, arg...) } func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { @@ -52,17 +49,16 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { } defer m.SortIntR(ID) fields := _zone_fields(m) - defer RLock(m, prefix, chain)() + defer RLock(m, prefix)() Richs(m, prefix, chain, kit.Select(FOREACH, zone), func(key string, val Map) { chain := kit.Keys(chain, HASH, key) - defer RLock(m, prefix, chain)() Grows(m, prefix, chain, ID, id, func(value ice.Map) { _mdb_select(m, m.OptionCB(""), key, value, fields, val) }) }) } func _zone_export(m *ice.Message, prefix, chain, file string) { - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() f, p, e := miss.CreateFile(kit.Keys(file, CSV)) m.Assert(e) defer f.Close() @@ -76,7 +72,6 @@ func _zone_export(m *ice.Message, prefix, chain, file string) { Richs(m, prefix, chain, key, func(key string, val ice.Map) { val = kit.GetMeta(val) chain := kit.Keys(chain, HASH, key) - defer Lock(m, prefix, chain)() Grows(m, prefix, chain, "", "", func(value ice.Map) { value = kit.GetMeta(value) w.Write(kit.Simple(head, func(k string) string { @@ -94,7 +89,7 @@ func _zone_export(m *ice.Message, prefix, chain, file string) { m.Conf(prefix, kit.Keys(chain, HASH), "") } func _zone_import(m *ice.Message, prefix, chain, file string) { - defer Lock(m, prefix, chain)() + defer Lock(m, prefix)() f, e := ice.Info.Open(m, kit.Keys(file, CSV)) if os.IsNotExist(e) { return @@ -133,7 +128,6 @@ func _zone_import(m *ice.Message, prefix, chain, file string) { } func() { chain := kit.Keys(chain, HASH, list[zone]) - defer Lock(m, prefix, chain)() Grow(m, prefix, chain, data) }() count++ diff --git a/base/nfs/cat.go b/base/nfs/cat.go index 6f1073d7..790c122f 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -120,7 +120,10 @@ func init() { )), }, DIR), Hand: func(m *ice.Message, arg ...string) { if !DirList(m, arg...) { - _cat_list(m.Logs(FIND, m.OptionSimple(DIR_ROOT), FILE, arg[0]), arg[0]) + if arg[0] != "" { + m.Logs(FIND, m.OptionSimple(DIR_ROOT), FILE, arg[0]) + } + _cat_list(m, arg[0]) } }}, }) diff --git a/base/nfs/dir.go b/base/nfs/dir.go index b5e11a9d..7c0a1fe9 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -200,8 +200,9 @@ func init() { } m.Logs(FIND, DIR_ROOT, root, PATH, dir, m.OptionSimple(DIR_TYPE, DIR_REG)) fields := kit.Split(kit.Select(kit.Select(DIR_DEF_FIELDS, m.OptionFields()), kit.Join(kit.Slice(arg, 1)))) - size, last := _dir_list(m, root, dir, 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), regexp.MustCompile(m.Option(DIR_REG)), fields) - m.Status(mdb.TIME, last, mdb.COUNT, kit.Split(m.FormatSize())[0], SIZE, kit.FmtSize(size), m.OptionSimple(DIR_ROOT), kit.MDB_COST, m.FormatCost()) + size, _ := _dir_list(m, root, dir, 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), regexp.MustCompile(m.Option(DIR_REG)), fields) + // m.Status(mdb.TIME, last, mdb.COUNT, kit.Split(m.FormatSize())[0], SIZE, kit.FmtSize(size), m.OptionSimple(DIR_ROOT), kit.MDB_COST, m.FormatCost()) + m.StatusTimeCount(SIZE, kit.FmtSize(size), m.OptionSimple(DIR_ROOT)) }}, }) } diff --git a/base/web/render.go b/base/web/render.go index fa78bf90..9f00e5f8 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -32,8 +32,10 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool { arg := kit.Simple(args...) kit.If(len(arg) == 0, func() { args = nil }) if cmd != "" { - if cmd != ice.RENDER_DOWNLOAD || !kit.HasPrefix(arg[0], ice.USR_VOLCANOS, ice.USR_INTSHELL, ice.SRC_TEMPLATE, ice.USR_ICONS, "usr/node_modules/") { - defer func() { m.Logs("Render", cmd, args) }() + if cmd != ice.RENDER_DOWNLOAD || !kit.HasPrefix(arg[0], ice.SRC_TEMPLATE, ice.USR_INTSHELL, ice.USR_VOLCANOS, ice.USR_ICONS, ice.USR_MODULES) { + if !(cmd == ice.RENDER_RESULT && len(args) == 0) { + defer func() { m.Logs("Render", cmd, args) }() + } } } switch cmd { diff --git a/base/web/serve.go b/base/web/serve.go index d81b5edc..05c07453 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -12,11 +12,13 @@ import ( "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/lex" + "shylinux.com/x/icebergs/base/log" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/ssh" "shylinux.com/x/icebergs/base/tcp" kit "shylinux.com/x/toolkits" + "shylinux.com/x/toolkits/logs" ) func _serve_address(m *ice.Message) string { return Domain(tcp.LOCALHOST, m.Option(tcp.PORT)) } @@ -53,7 +55,9 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { } else { r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, nfs.DF)[0]) } - if m.Logs(r.Header.Get(ice.MSG_USERIP), r.Method, r.URL.String()); r.Method == http.MethodGet { + traceid := log.Traceid() + r.Header.Set(ice.LOG_TRACEID, traceid) + if m.Logs(r.Header.Get(ice.MSG_USERIP), r.Method, r.URL.String(), logs.TraceidMeta(traceid)); r.Method == http.MethodGet { ispod := kit.Contains(r.URL.String(), CHAT_POD, "pod=") || kit.Contains(r.Header.Get(Referer), CHAT_POD, "pod=") if msg := m.Spawn(w, r).Options(ice.MSG_USERUA, r.UserAgent()); path.Join(r.URL.Path) == nfs.PS { if !msg.IsCliUA() { @@ -80,6 +84,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { } func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.ResponseWriter, r *http.Request) { debug := strings.Contains(r.URL.String(), "debug=true") || strings.Contains(r.Header.Get(Referer), "debug=true") + m.Option(ice.LOG_TRACEID, r.Header.Get(ice.LOG_TRACEID)) _log := func(level string, arg ...ice.Any) *ice.Message { if debug || arg[0] == ice.MSG_CMDS { return m.Logs(strings.Title(level), arg...) @@ -115,10 +120,11 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response kit.If(m.Optionv(ice.MSG_CMDS) == nil, func() { kit.If(strings.TrimPrefix(r.URL.Path, key), func(p string) { m.Optionv(ice.MSG_CMDS, strings.Split(p, nfs.PS)) }) }) + m.W.Header().Add(strings.ReplaceAll(ice.LOG_TRACEID, ".", "-"), m.Option(ice.LOG_TRACEID)) defer func() { Render(m, m.Option(ice.MSG_OUTPUT), kit.List(m.Optionv(ice.MSG_ARGS))...) }() if cmds, ok := _serve_auth(m, key, kit.Simple(m.Optionv(ice.MSG_CMDS)), w, r); ok { defer func() { - m.Cost(kit.Format("%s: /chat/cmd/%s/%s %v %s", r.Method, m.Option(ice.MSG_INDEX), path.Join(cmds...), m.FormatSize(), kit.FmtSize(len(m.Result())))) + m.Cost(kit.Format("%s: /chat/cmd/%s/%s %v", r.Method, m.Option(ice.MSG_INDEX), path.Join(cmds...), m.FormatSize())) }() m.Option(ice.MSG_OPTS, kit.Simple(m.Optionv(ice.MSG_OPTION), func(k string) bool { return !strings.HasPrefix(k, ice.MSG_SESSID) })) if m.Detailv(m.PrefixKey(), cmds); len(cmds) > 1 && cmds[0] == ctx.ACTION { diff --git a/base/web/space.go b/base/web/space.go index ed229a48..52f0fa4d 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -89,6 +89,7 @@ func _space_handle(m *ice.Message, safe bool, name string, c *websocket.Conn) { break } msg := m.Spawn(b) + // msg.Option(ice.LOG_TRACEID, kit.Split(msg.Option(ice.LOG_TRACEID), "-")[0]+"-"+ice.Info.NodeName) if safe { // 下行权限 msg.OptionDefault(ice.MSG_USERROLE, aaa.UserRole(msg, msg.Option(ice.MSG_USERNAME))) } else { // 上行权限 diff --git a/conf.go b/conf.go index 3137f8f6..f8740bcd 100644 --- a/conf.go +++ b/conf.go @@ -177,6 +177,7 @@ const ( // DIR ) const ( // MSG MSG_CMDS = "cmds" + MSG_DEBUG = "debug" MSG_FIELDS = "fields" MSG_SESSID = "sessid" MSG_METHOD = "method" @@ -224,6 +225,7 @@ const ( // MSG MSG_DAEMON = "sess.daemon" MSG_FILES = "file.system" LOG_DISABLE = "log.disable" + LOG_TRACEID = "log.id" YAC_MESSAGE = "yac.message" YAC_STACK = "yac.stack" SSH_ALIAS = "ssh.alias" diff --git a/core/code/bench.go b/core/code/bench.go index c2184caa..1b679f3f 100644 --- a/core/code/bench.go +++ b/core/code/bench.go @@ -41,7 +41,7 @@ func _bench_http(m *ice.Message, target string, arg ...string) { } }) var ndata int64 - if s, e := bench.HTTP(nconn, nreqs, list, func(req *http.Request, res *http.Response) { + if s, e := bench.HTTP(m.FormatTaskMeta(), nconn, nreqs, list, func(req *http.Request, res *http.Response) { n, _ := io.Copy(ioutil.Discard, res.Body) atomic.AddInt64(&ndata, n) }); m.Assert(e) { diff --git a/core/code/xterm.go b/core/code/xterm.go index 785718ce..85cb10db 100644 --- a/core/code/xterm.go +++ b/core/code/xterm.go @@ -41,7 +41,6 @@ func _xterm_get(m *ice.Message, h string) xterm.XTerm { for { if n, e := term.Read(buf); !m.Warn(e) && e == nil { if _xterm_echo(m, h, string(buf[:n])); len(text) > 0 { - m.Debug("what %v", text[0]) kit.If(text[0], func(cmd string) { m.Go(func() { m.Sleep30ms(); term.Writeln(cmd) }) }) text = text[1:] } diff --git a/exec.go b/exec.go index db27e1ad..575630c1 100644 --- a/exec.go +++ b/exec.go @@ -62,7 +62,7 @@ func (m *Message) GoSleep(t string, arg ...Any) { } func (m *Message) Go(cb func(), arg ...Any) *Message { kit.If(len(arg) == 0, func() { arg = append(arg, logs.FileLine(cb)) }) - task.Put(arg[0], func(task *task.Task) { m.TryCatch(true, func(m *Message) { cb() }) }) + task.Put(m.FormatTaskMeta(), arg[0], func(task *task.Task) { m.TryCatch(true, func(m *Message) { cb() }) }) return m } func (m *Message) Wait(d string, cb ...Handler) (wait func() bool, done Handler) { @@ -82,7 +82,7 @@ func (m *Message) Cmdv(arg ...Any) string { return m._command(kit.Slice(args, 0, -1), OptionFields(field)).Append(field) } func (m *Message) Cmdx(arg ...Any) string { - res := strings.TrimSpace(kit.Select("", m._command(arg...).meta[MSG_RESULT], 0)) + res := strings.TrimSpace(m._command(arg...).index(MSG_RESULT, 0)) return kit.Select("", res, res != strings.TrimSpace(ErrWarn)) } func (m *Message) Cmdy(arg ...Any) *Message { return m.Copy(m._command(arg...)) } @@ -147,7 +147,7 @@ func (m *Message) _command(arg ...Any) *Message { panic(count) } list := kit.Simple(args...) - kit.If(len(list) == 0, func() { list = m.meta[MSG_DETAIL] }) + kit.If(len(list) == 0, func() { list = m.value(MSG_DETAIL) }) if len(list) == 0 { return m } @@ -175,7 +175,7 @@ func (c *Context) _command(m *Message, cmd *Command, key string, arg ...string) if m._cmd, m._key = cmd, key; cmd == nil { return m } - if m.meta[MSG_DETAIL] = kit.Simple(m.PrefixKey(), arg); cmd.Actions != nil { + if m.value(MSG_DETAIL, kit.Simple(m.PrefixKey(), arg)...); cmd.Actions != nil { if len(arg) > 1 && arg[0] == ACTION { if h, ok := cmd.Actions[arg[1]]; ok { return c._action(m, cmd, key, arg[1], h, arg[2:]...) diff --git a/init.go b/init.go index a361218e..7156ff65 100644 --- a/init.go +++ b/init.go @@ -77,7 +77,7 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Commands: Commands{ }) }}, }, server: &Frame{}} -var Pulse = &Message{meta: map[string][]string{}, data: Map{}, source: Index, target: Index} +var Pulse = &Message{_meta: map[string][]string{}, _data: Map{}, source: Index, target: Index} func init() { switch tz := os.Getenv("TZ"); tz { @@ -98,7 +98,7 @@ func Run(arg ...string) string { } else if arg[0] == FOREVER && arg[1] == START && runtime.GOOS == WINDOWS { arg[0] = SERVE } - Pulse.meta[MSG_DETAIL] = arg + Pulse.value(MSG_DETAIL, arg...) kit.For(kit.Sort(os.Environ()), func(env string) { if ls := strings.SplitN(env, EQ, 2); strings.ToLower(ls[0]) == ls[0] && ls[0] != "_" { Pulse.Option(ls[0], ls[1]) diff --git a/lock.go b/lock.go new file mode 100644 index 00000000..8f668a68 --- /dev/null +++ b/lock.go @@ -0,0 +1,107 @@ +package ice + +import ( + kit "shylinux.com/x/toolkits" +) + +func (m *Message) index(key string, index int, value ...string) string { + if len(value) > 0 { + defer m.lock.Lock()() + m._meta[key][index] = value[0] + } else { + defer m.lock.RLock()() + } + return kit.Select("", m._meta[key], index) +} +func (m *Message) value(key string, list ...string) []string { + if len(list) > 0 { + defer m.lock.Lock()() + m._meta[key] = list + } else { + defer m.lock.RLock()() + } + return m._meta[key] +} +func (m *Message) delete(key ...string) { + defer m.lock.Lock()() + for _, key := range key { + delete(m._meta, key) + } +} + +func (m *Message) Add(key string, arg ...string) *Message { + if len(arg) == 0 { + return m + } + defer m.lock.Lock()() + switch key { + case MSG_DETAIL, MSG_RESULT: + m._meta[key] = append(m._meta[key], arg...) + case MSG_OPTION, MSG_APPEND: + if index := 0; key == MSG_APPEND { + if m._meta[MSG_OPTION], index = kit.SliceRemove(m._meta[MSG_OPTION], arg[0]); index > -1 { + delete(m._meta, arg[0]) + } + } + if m._meta[arg[0]] = append(m._meta[arg[0]], arg[1:]...); kit.IndexOf(m._meta[key], arg[0]) == -1 { + m._meta[key] = append(m._meta[key], arg[0]) + } + } + return m +} +func (m *Message) setDetail(key string, arg ...string) *Message { + defer m.lock.Lock()() + for i := 0; i < len(m._meta[KEY]); i++ { + if m._meta[KEY][i] == key { + if len(arg) > 0 { + m._meta[VALUE][i] = arg[0] + return m + } + for ; i < len(m._meta[KEY])-1; i++ { + m._meta[KEY][i] = m._meta[KEY][i+1] + m._meta[VALUE][i] = m._meta[VALUE][i+1] + } + m._meta[KEY] = kit.Slice(m._meta[KEY], 0, -1) + m._meta[VALUE] = kit.Slice(m._meta[VALUE], 0, -1) + return m + } + } + if len(arg) > 0 { + m._meta[KEY] = append(m._meta[KEY], key) + m._meta[VALUE] = append(m._meta[VALUE], arg[0]) + } + return m +} +func (m *Message) Optionv(key string, arg ...Any) Any { + var unlock func() + if len(arg) > 0 { + unlock = m.lock.Lock() + kit.If(kit.IndexOf(m._meta[MSG_OPTION], key) == -1, func() { m._meta[MSG_OPTION] = append(m._meta[MSG_OPTION], key) }) + switch delete(m._data, key); v := arg[0].(type) { + case nil: + delete(m._meta, key) + case string: + m._meta[key] = kit.Simple(arg...) + case []string: + m._meta[key] = v + default: + m._data[key] = v + } + } else { + unlock = m.lock.RLock() + } + if v, ok := m._data[key]; ok { + unlock() + return v + } else if v, ok := m._meta[key]; ok { + unlock() + return v + } else { + unlock() + } + if m.message != nil { + return m.message.Optionv(key) + } else { + return nil + } +} diff --git a/logs.go b/logs.go index 164e7eca..3bea180c 100644 --- a/logs.go +++ b/logs.go @@ -14,6 +14,7 @@ import ( kit "shylinux.com/x/toolkits" "shylinux.com/x/toolkits/logs" + "shylinux.com/x/toolkits/task" ) func (m *Message) join(arg ...Any) (string, []Any) { @@ -52,8 +53,20 @@ func (m *Message) log(level string, str string, arg ...Any) *Message { if m.Option(LOG_DISABLE) == TRUE { return m } + arg = append(arg, logs.TraceidMeta(m.Option(LOG_TRACEID))) + args, traceid := []Any{}, "" + for _, v := range arg { + switch v := v.(type) { + case logs.Meta: + if v.Key == logs.TRACEID { + traceid = kit.Select(strings.TrimSpace(v.Value), traceid) + continue + } + } + args = append(args, v) + } _source := logs.FileLineMeta(3) - kit.If(Info.Log != nil, func() { Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...)) }) + kit.If(Info.Log != nil, func() { Info.Log(m, m.FormatPrefix(traceid), level, logs.Format(str, append(args, _source)...)) }) prefix, suffix := "", "" if Info.Colors { switch level { @@ -65,7 +78,8 @@ func (m *Message) log(level string, str string, arg ...Any) *Message { prefix, suffix = "\033[31m", "\033[0m" } } - logs.Infof(str, append(arg, logs.PrefixMeta(kit.Format("%02d %4s->%-4s %s%s ", m.code, m.source.Name, m.target.Name, prefix, level)), logs.SuffixMeta(suffix), _source)...) + kit.If(traceid, func() { traceid = kit.Format("%s: %s ", logs.TRACEID, traceid) }) + logs.Infof(str, append(args, logs.PrefixMeta(kit.Format("%s%02d %4s->%-4s %s%s ", traceid, m.code, m.source.Name, m.target.Name, prefix, level)), logs.SuffixMeta(suffix), _source)...) return m } func (m *Message) Log(level string, str string, arg ...Any) *Message { @@ -83,7 +97,7 @@ func (m *Message) Auth(arg ...Any) *Message { } func (m *Message) Cost(arg ...Any) *Message { str, meta := m.join(arg...) - kit.If(str == "" || len(arg) == 0, func() { str, meta = kit.Join(m.meta[MSG_DETAIL], SP), []Any{logs.FileLineMeta(m._fileline())} }) + kit.If(str == "" || len(arg) == 0, func() { str, meta = kit.Join(m.value(MSG_DETAIL), SP), []Any{logs.FileLineMeta(m._fileline())} }) return m.log(LOG_COST, kit.Join([]string{m.FormatCost(), str}, SP), meta...) } func (m *Message) Info(str string, arg ...Any) *Message { @@ -145,7 +159,7 @@ func (m *Message) error(arg ...Any) { } func (m *Message) IsOk() bool { return m.Result() == OK } func (m *Message) IsErr(arg ...string) bool { - return len(arg) == 0 && kit.Select("", m.meta[MSG_RESULT], 0) == ErrWarn || len(arg) > 0 && kit.Select("", m.meta[MSG_RESULT], 1) == arg[0] + return len(arg) == 0 && m.index(MSG_RESULT, 0) == ErrWarn || len(arg) > 0 && m.index(MSG_RESULT, 1) == arg[0] } func (m *Message) IsErrNotFound() bool { return m.IsErr(ErrNotFound) } func (m *Message) Debug(str string, arg ...Any) { @@ -153,41 +167,55 @@ func (m *Message) Debug(str string, arg ...Any) { m.log(LOG_DEBUG, str, arg...) } -func (m *Message) FormatPrefix() string { - return kit.Format("%s %d %s->%s", logs.FmtTime(logs.Now()), m.code, m.source.Name, m.target.Name) +func (m *Message) FormatTaskMeta() task.Meta { + _traceid := "" + kit.If(m.Option(LOG_TRACEID), func(traceid string) { _traceid = kit.Format("%s: %s ", logs.TRACEID, traceid) }) + return task.Meta{ + Prefix: kit.Format("%s%d %4s->%-4s ", _traceid, m.code, m.source.Name, m.target.Name), + FileLine: kit.FileLine(2, 3), + } +} +func (m *Message) FormatPrefix(traceid ...string) string { + _traceid := "" + kit.If(kit.Select(m.Option(LOG_TRACEID), traceid, 0), func(traceid string) { _traceid = kit.Format("%s: %s ", logs.TRACEID, traceid) }) + return kit.Format("%s %s%d %s->%s", logs.FmtTime(logs.Now()), _traceid, m.code, m.source.Name, m.target.Name) } func (m *Message) FormatSize() string { - return kit.Format("%dx%d %v", m.Length(), len(m.meta[MSG_APPEND]), kit.Simple(m.meta[MSG_APPEND])) + return kit.Format("%dx%d %v %v", m.Length(), len(m.value(MSG_APPEND)), kit.Simple(m.value(MSG_APPEND)), kit.FmtSize(len(m.Result()))) } func (m *Message) FormatCost() string { return kit.FmtDuration(time.Since(m.time)) } -func (m *Message) FormatMeta() string { return kit.Format(m.meta) } +func (m *Message) FormatMeta() string { + defer m.lock.RLock()() + return kit.Format(m._meta) +} func (m *Message) FormatsMeta(w io.Writer, arg ...string) (res string) { if w == nil { buf := bytes.NewBuffer(make([]byte, 0, MOD_BUFS)) defer func() { res = buf.String() }() w = buf } - kit.For(m.meta[MSG_OPTION], func(i int, k string) { - kit.If(len(m.meta[k]) == 0 || len(m.meta[k]) == 1 && m.meta[k][0] == "", func() { m.meta[MSG_OPTION][i] = "" }) + kit.For(m.value(MSG_OPTION), func(i int, k string) { + ls := m.value(k) + kit.If(len(ls) == 0 || len(ls) == 1 && ls[0] == "", func() { m.index(MSG_OPTION, i, "") }) }) - m.meta[MSG_OPTION] = kit.Filters(m.meta[MSG_OPTION], MSG_CMDS, MSG_FIELDS, MSG_SESSID, MSG_OPTS, MSG_INDEX, "", "aaa.checker") + m.value(MSG_OPTION, kit.Filters(m.value(MSG_OPTION), MSG_CMDS, MSG_FIELDS, MSG_SESSID, MSG_OPTS, MSG_INDEX, "", "aaa.checker")...) kit.If(len(arg) == 0 && m.Option(DEBUG) == TRUE, func() { arg = []string{SP, SP, NL} }) bio, count, NL := bufio.NewWriter(w), 0, kit.Select("", arg, 2) defer bio.Flush() echo := func(arg ...Any) { fmt.Fprint(bio, arg...) } push := func(k string) { - if len(m.meta[k]) == 0 { + if len(m.value(k)) == 0 { return } kit.If(count > 0, func() { echo(FS, NL) }) echo(kit.Format("%s%q:%s", kit.Select("", arg, 0), k, kit.Select("", arg, 1))) - b, _ := json.Marshal(m.meta[k]) + b, _ := json.Marshal(m.value(k)) bio.Write(b) count++ } echo("{", NL) defer echo(NL, "}", NL) - kit.For(kit.Simple(MSG_DETAIL, MSG_OPTION, m.meta[MSG_OPTION], m.meta[MSG_APPEND], MSG_APPEND, MSG_RESULT), push) + kit.For(kit.Simple(MSG_DETAIL, MSG_OPTION, m.value(MSG_OPTION), m.value(MSG_APPEND), MSG_APPEND, MSG_RESULT), push) return } func (m *Message) FormatChain() string { @@ -196,17 +224,18 @@ func (m *Message) FormatChain() string { ms = append(ms, msg) } show := func(msg *Message, key string, arg ...string) string { - if len(msg.meta[key]) == 0 || len(msg.meta[key]) == 1 && msg.meta[key][0] == "" { + ls := msg.value(key) + if len(ls) == 0 || len(ls) == 1 && ls[0] == "" { return "" } - return kit.Format("%s%s:%s%d %v", kit.Select("", arg, 0), key, kit.Select("", arg, 1), len(msg.meta[key]), msg.meta[key]) + return kit.Format("%s%s:%s%d %v", kit.Select("", arg, 0), key, kit.Select("", arg, 1), len(ls), ls) } meta := []string{} for i := len(ms) - 1; i >= 0; i-- { msg := ms[i] meta = append(meta, kit.Join([]string{msg.FormatPrefix(), show(msg, MSG_DETAIL), show(msg, MSG_OPTION), show(msg, MSG_APPEND), show(msg, MSG_RESULT), msg._cmd.FileLines()}, SP)) - kit.For(msg.meta[MSG_OPTION], func(k string) { kit.If(show(msg, k, TB, SP), func(s string) { meta = append(meta, s) }) }) - kit.For(msg.meta[MSG_APPEND], func(k string) { kit.If(show(msg, k, TB, SP), func(s string) { meta = append(meta, s) }) }) + kit.For(msg.value(MSG_OPTION), func(k string) { kit.If(show(msg, k, TB, SP), func(s string) { meta = append(meta, s) }) }) + kit.For(msg.value(MSG_APPEND), func(k string) { kit.If(show(msg, k, TB, SP), func(s string) { meta = append(meta, s) }) }) } return kit.Join(meta, NL) } diff --git a/meta.go b/meta.go index 14fcb3f6..ad6f3f33 100644 --- a/meta.go +++ b/meta.go @@ -7,82 +7,39 @@ import ( kit "shylinux.com/x/toolkits" ) -func (m *Message) setDetail(key string, arg ...string) *Message { - for i := 0; i < len(m.meta[KEY]); i++ { - if m.meta[KEY][i] == key { - if len(arg) > 0 { - m.meta[VALUE][i] = arg[0] - return m - } - for ; i < len(m.meta[KEY])-1; i++ { - m.meta[KEY][i] = m.meta[KEY][i+1] - m.meta[VALUE][i] = m.meta[VALUE][i+1] - } - m.meta[KEY] = kit.Slice(m.meta[KEY], 0, -1) - m.meta[VALUE] = kit.Slice(m.meta[VALUE], 0, -1) - return m - } - } - if len(arg) > 0 { - m.meta[KEY] = append(m.meta[KEY], key) - m.meta[VALUE] = append(m.meta[VALUE], arg[0]) - } - return m -} func (m *Message) Set(key string, arg ...string) *Message { switch key { case MSG_DETAIL, MSG_RESULT: - delete(m.meta, key) + m.delete(key) case MSG_OPTION, MSG_APPEND: if m.FieldsIsDetail() { if len(arg) > 0 { m.setDetail(arg[0], arg[1:]...) } else { - delete(m.meta, KEY) - delete(m.meta, VALUE) - delete(m.meta, MSG_APPEND) + m.delete(KEY, VALUE, MSG_APPEND) } } else if len(arg) > 0 { - if delete(m.meta, arg[0]); len(arg) > 1 { - m.meta[arg[0]] = arg[1:] + if m.delete(arg[0]); len(arg) > 1 { + m.value(arg[0], arg[1:]...) } } else { - kit.For(m.meta[key], func(k string) { delete(m.meta, k) }) - delete(m.meta, key) + kit.For(m.value(key), func(k string) { m.delete(k) }) + m.delete(key) } return m default: if m.FieldsIsDetail() { return m.setDetail(key, arg...) } - kit.For(kit.Split(key), func(k string) { delete(m.meta, k) }) + kit.For(kit.Split(key), func(k string) { m.delete(k) }) } if len(arg) == 0 { return m } return m.Add(key, arg...) } -func (m *Message) Add(key string, arg ...string) *Message { - if len(arg) == 0 { - return m - } - switch key { - case MSG_DETAIL, MSG_RESULT: - m.meta[key] = append(m.meta[key], arg...) - case MSG_OPTION, MSG_APPEND: - if index := 0; key == MSG_APPEND { - if m.meta[MSG_OPTION], index = kit.SliceRemove(m.meta[MSG_OPTION], arg[0]); index > -1 { - delete(m.meta, arg[0]) - } - } - if m.meta[arg[0]] = append(m.meta[arg[0]], arg[1:]...); kit.IndexOf(m.meta[key], arg[0]) == -1 { - m.meta[key] = append(m.meta[key], arg[0]) - } - } - return m -} func (m *Message) Cut(fields ...string) *Message { - m.meta[MSG_APPEND] = kit.Split(kit.Join(fields)) + m.value(MSG_APPEND, kit.Split(kit.Join(fields))...) return m } func (m *Message) CutTo(key, to string) *Message { @@ -91,7 +48,7 @@ func (m *Message) CutTo(key, to string) *Message { func (m *Message) Push(key string, value Any, arg ...Any) *Message { head := kit.Simple() kit.If(len(head) == 0 && len(arg) > 0, func() { head = kit.Simple(arg[0]) }) - kit.If(len(head) == 0, func() { head = kit.Simple(m.meta[MSG_APPEND]) }) + kit.If(len(head) == 0, func() { head = kit.Simple(m.value(MSG_APPEND)) }) kit.If(len(head) == 0 && !m.FieldsIsDetail(), func() { head = kit.Split(m.OptionFields()) }) switch value := value.(type) { case Map: @@ -144,7 +101,7 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { if m.FieldsIsDetail() { m.Add(MSG_APPEND, KEY, key).Add(MSG_APPEND, VALUE, kit.Format(value)) } else { - if m.ActionKey() == INPUTS && kit.IndexOf(m.meta[key], v) > -1 { + if m.ActionKey() == INPUTS && kit.IndexOf(m.value(key), v) > -1 { // return } m.Add(MSG_APPEND, key, v) @@ -167,10 +124,10 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message { return m } if len(arg) > 0 { - kit.For(arg[1:], func(k string) { m.Add(arg[0], kit.Simple(k, msg.meta[k])...) }) + kit.For(arg[1:], func(k string) { m.Add(arg[0], kit.Simple(k, msg.value(k))...) }) return m } - for _, k := range msg.meta[MSG_OPTION] { + for _, k := range msg.value(MSG_OPTION) { switch k { case MSG_CMDS, MSG_FIELDS, MSG_SESSID, EVENT: continue @@ -178,21 +135,24 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message { if strings.HasSuffix(k, ".cb") { continue } - if kit.IndexOf(m.meta[MSG_APPEND], k) > -1 { + if kit.IndexOf(m.value(MSG_APPEND), k) > -1 { continue } - if v, ok := msg.data[k]; ok { - m.data[k] = v + unlock := m.lock.Lock() + if v, ok := msg._data[k]; ok { + m._data[k] = v + unlock() } else { + unlock() m.Set(MSG_OPTION, k) } - m.Add(MSG_OPTION, kit.Simple(k, msg.meta[k])...) + m.Add(MSG_OPTION, kit.Simple(k, msg.value(k))...) } - kit.For(msg.meta[MSG_APPEND], func(k string) { m.Add(MSG_APPEND, kit.Simple(k, msg.meta[k])...) }) - return m.Add(MSG_RESULT, msg.meta[MSG_RESULT]...) + kit.For(msg.value(MSG_APPEND), func(k string) { m.Add(MSG_APPEND, kit.Simple(k, msg.value(k))...) }) + return m.Add(MSG_RESULT, msg.value(MSG_RESULT)...) } func (m *Message) Length() (max int) { - kit.For(m.meta[MSG_APPEND], func(k string) { max = kit.Max(len(m.meta[k]), max) }) + kit.For(m.value(MSG_APPEND), func(k string) { max = kit.Max(len(m.value(k)), max) }) return max } func (m *Message) TablesLimit(count int, cb func(value Maps)) *Message { @@ -217,14 +177,14 @@ func (m *Message) Table(cb Any) *Message { } if m.FieldsIsDetail() { value := Maps{} - kit.For(m.meta[KEY], func(i int, k string) { value[k] = kit.Select("", m.meta[VALUE], i) }) - cbs(0, value, m.meta[KEY]) + kit.For(m.value(KEY), func(i int, k string) { value[k] = kit.Select("", m.value(VALUE), i) }) + cbs(0, value, m.value(KEY)) return m } for i := 0; i < n; i++ { value := Maps{} - kit.For(m.meta[MSG_APPEND], func(k string) { value[k] = kit.Select("", m.meta[k], i) }) - cbs(i, value, m.meta[MSG_APPEND]) + kit.For(m.value(MSG_APPEND), func(k string) { value[k] = kit.Select("", m.value(k), i) }) + cbs(i, value, m.value(MSG_APPEND)) } return m } @@ -260,16 +220,16 @@ func (m *Message) TableEcho() *Message { } } length, width := 0, map[string]int{} - for _, k := range m.meta[MSG_APPEND] { - kit.If(len(m.meta[k]) > length, func() { length = len(m.meta[k]) }) + for _, k := range m.value(MSG_APPEND) { + kit.If(len(m.value(k)) > length, func() { length = len(m.value(k)) }) width[k] = kit.Width(k, len(space)) - kit.For(m.meta[k], func(v string) { + kit.For(m.value(k), func(v string) { kit.If(kit.Width(v, len(space)) > width[k], func() { width[k] = kit.Width(v, len(space)) }) }) } - show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return _align(k, width[k]) })) + show(kit.Simple(m.value(MSG_APPEND), func(k string) string { return _align(k, width[k]) })) for i := 0; i < length; i++ { - show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return _align(kit.Select("", m.meta[k], i), width[k]) })) + show(kit.Simple(m.value(MSG_APPEND), func(k string) string { return _align(kit.Select("", m.value(k), i), width[k]) })) } return m } @@ -299,7 +259,7 @@ func (m *Message) Sort(key string, arg ...string) *Message { cmp := kit.Select("", arg, i) if cmp == "" { cmp = INT - for _, v := range m.meta[k] { + for _, v := range m.value(k) { if _, e := strconv.Atoi(v); e != nil { cmp = STR } @@ -339,9 +299,9 @@ func (m *Message) Sort(key string, arg ...string) *Message { list[j], list[j-1] = list[j-1], list[j] } } - kit.For(m.meta[MSG_APPEND], func(k string) { delete(m.meta, k) }) + kit.For(m.value(MSG_APPEND), func(k string) { m.delete(k) }) for _, v := range list { - kit.For(m.meta[MSG_APPEND], func(k string) { m.Add(MSG_APPEND, k, v[k]) }) + kit.For(m.value(MSG_APPEND), func(k string) { m.Add(MSG_APPEND, k, v[k]) }) } return m } @@ -350,10 +310,10 @@ func (m *Message) SortStrR(key string) *Message { return m.Sort(key, STR_R) } func (m *Message) SortIntR(key string) *Message { return m.Sort(key, INT_R) } func (m *Message) SortInt(key string) *Message { return m.Sort(key, INT) } -func (m *Message) Detail(arg ...Any) string { return kit.Select("", m.meta[MSG_DETAIL], 0) } +func (m *Message) Detail(arg ...Any) string { return m.index(MSG_DETAIL, 0) } func (m *Message) Detailv(arg ...Any) []string { - kit.If(len(arg) > 0, func() { m.meta[MSG_DETAIL] = kit.Simple(arg...) }) - return m.meta[MSG_DETAIL] + kit.If(len(arg) > 0, func() { m.value(MSG_DETAIL, kit.Simple(arg...)...) }) + return m.value(MSG_DETAIL) } func (m *Message) Options(arg ...Any) *Message { for i := 0; i < len(arg); i += 2 { @@ -366,39 +326,6 @@ func (m *Message) Options(arg ...Any) *Message { } return m } -func (m *Message) Optionv(key string, arg ...Any) Any { - var unlock func() - if len(arg) > 0 { - unlock = m.lock.Lock() - kit.If(kit.IndexOf(m.meta[MSG_OPTION], key) == -1, func() { m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key) }) - switch delete(m.data, key); v := arg[0].(type) { - case nil: - delete(m.meta, key) - case string: - m.meta[key] = kit.Simple(arg...) - case []string: - m.meta[key] = v - default: - m.data[key] = v - } - } else { - unlock = m.lock.RLock() - } - if v, ok := m.data[key]; ok { - unlock() - return v - } else if v, ok := m.meta[key]; ok { - unlock() - return v - } else { - unlock() - } - if m.message != nil { - return m.message.Optionv(key) - } else { - return nil - } -} func (m *Message) Option(key string, arg ...Any) string { return kit.Select("", kit.Simple(m.Optionv(key, arg...)), 0) } @@ -410,10 +337,10 @@ func (m *Message) Append(key string, arg ...Any) string { } func (m *Message) Appendv(key string, arg ...Any) []string { if m.FieldsIsDetail() { - for i, k := range m.meta[KEY] { + for i, k := range m.value(KEY) { if k == key || k == kit.Keys(EXTRA, key) { - kit.If(len(arg) > 0, func() { m.meta[VALUE][i] = kit.Format(arg[0]) }) - return []string{kit.Select("", m.meta[VALUE], i)} + kit.If(len(arg) > 0, func() { m.index(VALUE, i, kit.Format(arg[0])) }) + return []string{m.index(VALUE, i)} } } if len(arg) > 0 { @@ -423,21 +350,28 @@ func (m *Message) Appendv(key string, arg ...Any) []string { return nil } if key == MSG_APPEND { - kit.If(len(arg) > 0, func() { m.meta[key] = kit.Simple(arg) }) - return m.meta[key] + kit.If(len(arg) > 0, func() { m.value(key, kit.Simple(arg)...) }) + return m.value(key) } - kit.If(len(arg) > 0, func() { m.meta[key] = kit.Simple(arg...) }) - if v, ok := m.meta[key]; ok { + kit.If(len(arg) > 0, func() { m.value(key, kit.Simple(arg...)...) }) + + defer m.lock.RLock()() + if v, ok := m._meta[key]; ok { return v } - if v, ok := m.meta[kit.Keys(EXTRA, key)]; ok { + if v, ok := m._meta[kit.Keys(EXTRA, key)]; ok { return v } return nil } func (m *Message) Resultv(arg ...Any) []string { - kit.If(len(arg) > 0, func() { m.meta[MSG_RESULT] = kit.Simple(arg...) }) - return m.meta[MSG_RESULT] + if len(arg) > 0 { + defer m.lock.Lock()() + m._meta[MSG_RESULT] = kit.Simple(arg...) + } else { + defer m.lock.RLock()() + } + return m._meta[MSG_RESULT] } func (m *Message) Result(arg ...Any) string { return strings.Join(m.Resultv(arg...), "") } func (m *Message) Results(arg ...Any) string { diff --git a/misc.go b/misc.go index ca6dd15d..afba7946 100644 --- a/misc.go +++ b/misc.go @@ -90,10 +90,11 @@ func (m *Message) RenameAppend(arg ...string) *Message { if from == to { return } - kit.For(m.meta[MSG_APPEND], func(i int, k string) { + defer m.lock.Lock()() + kit.For(m._meta[MSG_APPEND], func(i int, k string) { if k == from { - m.meta[MSG_APPEND][i], m.meta[to] = to, m.meta[from] - delete(m.meta, from) + m._meta[MSG_APPEND][i], m._meta[to] = to, m._meta[from] + delete(m._meta, from) } }) }) @@ -102,19 +103,20 @@ func (m *Message) RenameAppend(arg ...string) *Message { func (m *Message) RewriteAppend(cb func(value, key string, index int) string) *Message { m.Table(func(index int, value Maps, head []string) { for _, key := range head { - m.meta[key][index] = cb(value[key], key, index) + v := cb(value[key], key, index) + m.index(key, index, v) } }) return m } func (m *Message) ToLowerAppend(arg ...string) *Message { - kit.For(m.meta[MSG_APPEND], func(k string) { m.RenameAppend(k, strings.ToLower(k)) }) + kit.For(m.value(MSG_APPEND), func(k string) { m.RenameAppend(k, strings.ToLower(k)) }) return m } func (m *Message) AppendSimple(key ...string) (res []string) { if len(key) == 0 { if m.FieldsIsDetail() { - key = append(key, m.meta[KEY]...) + key = append(key, m.value(KEY)...) } else { key = append(key, m.Appendv(MSG_APPEND)...) } @@ -124,15 +126,17 @@ func (m *Message) AppendSimple(key ...string) (res []string) { } func (m *Message) AppendTrans(cb func(value string, key string, index int) string) *Message { if m.FieldsIsDetail() { - for i, v := range m.meta[VALUE] { - k := m.meta[KEY][i] - m.meta[VALUE][i] = cb(v, k, 0) + defer m.lock.Lock()() + for i, v := range m._meta[VALUE] { + k := m._meta[KEY][i] + m._meta[VALUE][i] = cb(v, k, 0) } return m } - for _, k := range m.meta[MSG_APPEND] { - for i, v := range m.meta[k] { - m.meta[k][i] = cb(v, k, i) + defer m.lock.Lock()() + for _, k := range m._meta[MSG_APPEND] { + for i, v := range m._meta[k] { + m._meta[k][i] = cb(v, k, i) } } return m diff --git a/misc/git/search.go b/misc/git/search.go index 618e18f8..9f4acac5 100644 --- a/misc/git/search.go +++ b/misc/git/search.go @@ -70,7 +70,7 @@ func init() { kit.For([]string{HTML_URL, WEBSITE}, func(key string) { kit.If(kit.Format(value[key]), func() { button = append(button, key) }) }) m.PushButton(button...) }) - m.RenameAppend(CLONE_URL, REPOS).StatusTimeCount().Display("").Action(ORIGIN) + m.RenameAppend(CLONE_URL, REPOS).Action(ORIGIN).StatusTimeCount().Display("") }}, }) } diff --git a/misc/git/total.go b/misc/git/total.go index 3e1902b6..00af927b 100644 --- a/misc/git/total.go +++ b/misc/git/total.go @@ -47,7 +47,7 @@ func init() { return } from, days, commit, adds, dels, rest := "", 0, 0, 0, 0, 0 - TableGo(ReposList(m), func(value ice.Maps, lock *task.Lock) { + TableGo(ReposList(m.Spawn()), func(value ice.Maps, lock *task.Lock) { msg := m.Cmd("_sum", value[nfs.PATH], mdb.TOTAL, "10000") defer lock.Lock()() msg.Table(func(value ice.Maps) { @@ -118,7 +118,7 @@ func TableGo(m *ice.Message, cb ice.Any) *ice.Message { defer wg.Wait() m.Table(func(value ice.Maps) { wg.Add(1) - task.Put(logs.FileLine(cb), func(*task.Task) { + task.Put(m.FormatTaskMeta(), logs.FileLine(cb), func(*task.Task) { defer wg.Done() switch cb := cb.(type) { case func(ice.Maps, *task.Lock): diff --git a/option.go b/option.go index cc3ac378..0012ec06 100644 --- a/option.go +++ b/option.go @@ -62,7 +62,8 @@ func (m *Message) MergePodCmd(pod, cmd string, arg ...Any) string { return kit.MergeURL2(strings.Split(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), QS)[0], PS+kit.Join(ls, PS), arg...) } func (m *Message) FieldsIsDetail() bool { - return len(m.meta[MSG_APPEND]) == 2 && m.meta[MSG_APPEND][0] == KEY && m.meta[MSG_APPEND][1] == VALUE || m.OptionFields() == FIELDS_DETAIL + ls := m.value(MSG_APPEND) + return len(ls) == 2 && ls[0] == KEY && ls[1] == VALUE || m.OptionFields() == FIELDS_DETAIL } func (m *Message) Fields(length int, fields ...string) string { kit.If(length >= len(fields), func() { m.Option(MSG_FIELDS, FIELDS_DETAIL) }) @@ -78,13 +79,15 @@ func (m *Message) Status(arg ...Any) *Message { return m.Options(MSG_STATUS, kit.Format(list)) } func (m *Message) StatusTime(arg ...Any) *Message { - return m.Status(TIME, m.Time(), arg, kit.MDB_COST, m.FormatCost()) + traceid := []string{} + kit.If(m.Option(MSG_DEBUG) == TRUE, func() { traceid = m.OptionSimple(LOG_TRACEID) }) + return m.Status(TIME, m.Time(), arg, kit.MDB_COST, m.FormatCost(), traceid) } func (m *Message) StatusTimeCount(arg ...Any) *Message { - return m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], arg, kit.MDB_COST, m.FormatCost()) + return m.StatusTime(append([]Any{kit.MDB_COUNT, kit.Split(m.FormatSize())[0]}, arg...)) } func (m *Message) StatusTimeCountTotal(arg ...Any) *Message { - return m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_TOTAL, arg, kit.MDB_COST, m.FormatCost()) + return m.StatusTimeCount(append([]Any{kit.MDB_TOTAL}, arg...)) } func (m *Message) Process(cmd string, arg ...Any) *Message { diff --git a/render.go b/render.go index bf55a427..95112451 100644 --- a/render.go +++ b/render.go @@ -137,7 +137,7 @@ func (m *Message) PushSearch(arg ...Any) { } } func (m *Message) PushAction(arg ...Any) *Message { - if len(m.meta[MSG_APPEND]) == 0 { + if len(m.value(MSG_APPEND)) == 0 { return m } return m.Set(MSG_APPEND, ACTION).Table(func(value Maps) { m.PushButton(arg...) }) @@ -145,14 +145,14 @@ func (m *Message) PushAction(arg ...Any) *Message { func (m *Message) PushButton(arg ...Any) *Message { if !m.IsCliUA() { if m.FieldsIsDetail() { - for i, k := range m.meta[KEY] { + for i, k := range m.value(KEY) { if k == ACTION { - m.meta[VALUE][i] = Render(m, RENDER_BUTTON, arg...) + m.index(VALUE, i, Render(m, RENDER_BUTTON, arg...)) return m } } - } else if len(m.meta[ACTION]) >= m.Length() { - m.meta[ACTION] = []string{} + } else if len(m.value(ACTION)) >= m.Length() { + m.delete(ACTION) } m.Push(ACTION, Render(m, RENDER_BUTTON, arg...)) } diff --git a/type.go b/type.go index 340522fd..de1fc9bd 100644 --- a/type.go +++ b/type.go @@ -100,15 +100,9 @@ func (c *Context) Register(s *Context, x Server, cmd ...string) *Context { return s } func (c *Context) MergeCommands(Commands Commands) *Context { - for key, cmd := range Commands { - // for _, cmd := range Commands { + for _, cmd := range Commands { if cmd.Hand == nil && cmd.RawHand == nil { - if cmd.RawHand = logs.FileLines(2); cmd.Actions != nil { - if action, ok := cmd.Actions[SELECT]; ok { - cmd.Name = kit.Select(strings.Replace(action.Name, SELECT, key, 1), cmd.Name) - cmd.Help = kit.Select(action.Help, cmd.Help) - } - } + cmd.RawHand = logs.FileLines(2) } } configs := Configs{} @@ -165,7 +159,8 @@ func (c *Context) Merge(s *Context) *Context { } } } - // kit.If(sub == SELECT, func() { cmd.Name = kit.Select(action.Name, cmd.Name) }) + kit.If(sub == SELECT, func() { cmd.Name = kit.Select(action.Name, cmd.Name) }) + kit.If(sub == SELECT, func() { cmd.Help = kit.Select(action.Help, cmd.Help) }) if help := kit.Split(action.Help, " ::"); len(help) > 0 { if kit.Value(cmd.Meta, kit.Keys("_trans", strings.TrimPrefix(sub, "_")), help[0]); len(help) > 1 { kit.Value(cmd.Meta, kit.Keys("_title", sub), help[1]) @@ -178,7 +173,6 @@ func (c *Context) Merge(s *Context) *Context { kit.If(action.List == nil, func() { action.List = SplitCmd(action.Name, nil) }) kit.If(len(action.List) > 0, func() { cmd.Meta[sub] = action.List }) } - // kit.If(cmd.Name == "", func() { cmd.Name = "list list" }) kit.If(strings.HasPrefix(cmd.Name, LIST), func() { cmd.Name = strings.Replace(cmd.Name, LIST, key, 1) }) kit.If(cmd.List == nil, func() { cmd.List = SplitCmd(cmd.Name, cmd.Actions) }) } @@ -211,9 +205,9 @@ type Message struct { time time.Time code int - data Map - meta map[string][]string - lock task.Lock + _data Map + _meta map[string][]string + lock task.Lock root *Message message *Message @@ -254,14 +248,14 @@ func (m *Message) _fileline() string { } func (m *Message) Spawn(arg ...Any) *Message { msg := &Message{time: time.Now(), code: int(m.target.root.ID()), - meta: map[string][]string{}, data: Map{}, message: m, root: m.root, + _meta: map[string][]string{}, _data: Map{}, message: m, root: m.root, _source: logs.FileLine(2), source: m.target, target: m.target, _cmd: m._cmd, _key: m._key, _sub: m._sub, W: m.W, R: m.R, O: m.O, I: m.I, } for _, val := range arg { switch val := val.(type) { case []byte: - if m.Warn(json.Unmarshal(val, &msg.meta), string(val)) { + if m.Warn(json.Unmarshal(val, &msg._meta), string(val)) { m.Debug(m.FormatStack(1, 100)) } case Option: