From b4590bbffdbdb0573bdd6e011d1af4b87e9ec93e Mon Sep 17 00:00:00 2001 From: Odboy Date: Tue, 3 Nov 2026 21:12:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20svc.list/log.list?= =?UTF-8?q?=20=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svc.list 列出所有服务(systemctl/launchctl/sc) log.list 列出可用日志来源(journalctl/日志目录/wevtutil) --- README.log.md | 5 +++++ README.svc.md | 5 +++++ internal/executor/builtin.go | 2 ++ internal/executor/logsearch.go | 27 +++++++++++++++++++++++++++ internal/executor/svc.go | 23 +++++++++++++++++++++++ internal/registry/builtin.go | 17 +++++++++++++++++ internal/registry/registry_test.go | 4 ++-- 7 files changed, 81 insertions(+), 2 deletions(-) diff --git a/README.log.md b/README.log.md index 2b44dd6..0b5cf04 100644 --- a/README.log.md +++ b/README.log.md @@ -6,12 +6,16 @@ | 命令 | 作用 | | --- | --- | +| `kopsc log list` | 列出可用的日志来源 | | `kopsc log search <关键字> [选项]` | 在系统日志中搜索关键字 | | `kopsc log last [行数] [-u 服务]` | 查看最近的系统日志 | ## 示例 ```bash +# 列出可用的日志来源 +kopsc log list + # 搜索最近 1 小时包含 "error" 的日志 kopsc log search "error" --since 1h @@ -49,5 +53,6 @@ kopsc log last -u nginx | 操作 | Linux | macOS | Windows | | --- | --- | --- | --- | +| list | `journalctl --list-boots` | 列出日志目录 | `wevtutil el` | | search | `journalctl --grep` | `log show --predicate` | `wevtutil` + 过滤 | | last | `journalctl -n` | `log show --last` | `wevtutil /c:` | diff --git a/README.svc.md b/README.svc.md index f28db52..17cc666 100644 --- a/README.svc.md +++ b/README.svc.md @@ -6,6 +6,7 @@ | 命令 | 作用 | | --- | --- | +| `kopsc svc list` | 列出所有服务 | | `kopsc svc status <服务名>` | 查看服务状态与最近 20 行日志 | | `kopsc svc enable <服务名>` | 启用并启动服务(开机自启 + 立即启动) | | `kopsc svc disable <服务名>` | 禁用并停止服务 | @@ -14,6 +15,9 @@ ## 示例 ```bash +# 列出所有服务 +kopsc svc list + # 查看 nginx 状态和最近日志 kopsc svc status nginx @@ -34,6 +38,7 @@ kopsc svc logs nginx -f | 操作 | Linux | macOS | Windows | | --- | --- | --- | --- | +| list | `systemctl list-unit-files` | `launchctl list` | `sc query state= all` | | status | `systemctl status` + `journalctl` | `launchctl list` + `log show` | `sc query` | | enable | `systemctl enable` + `start` | `launchctl load -w` | `sc config start=auto` + `start` | | disable | `systemctl stop` + `disable` | `launchctl unload -w` | `sc stop` + `config start=disabled` | diff --git a/internal/executor/builtin.go b/internal/executor/builtin.go index e368bf4..94211b4 100644 --- a/internal/executor/builtin.go +++ b/internal/executor/builtin.go @@ -59,6 +59,7 @@ var builtins = map[string]Builtin{ "java.run": runJavaRun, "java.run.preview": runJavaPreview, "log.last": runLogLast, + "log.list": runLogList, "log.search": runLogSearch, "net.conn": runNetConn, "net.curl": runNetCurl, @@ -77,6 +78,7 @@ var builtins = map[string]Builtin{ "proc.wait": runProcWait, "svc.disable": runSvcDisable, "svc.enable": runSvcEnable, + "svc.list": runSvcList, "svc.logs": runSvcLogs, "svc.status": runSvcStatus, "sysinfo": runSysInfo, diff --git a/internal/executor/logsearch.go b/internal/executor/logsearch.go index 9ebf76c..e74a11d 100644 --- a/internal/executor/logsearch.go +++ b/internal/executor/logsearch.go @@ -11,6 +11,33 @@ import ( "time" ) +// runLogList implements `kopsc log list`: list available log sources. +func runLogList(ctx context.Context, req BuiltinRequest) error { + switch runtime.GOOS { + case "linux": + cmd := exec.CommandContext(ctx, "journalctl", "--list-boots", "--no-pager") + cmd.Stdout = req.Stdout + cmd.Stderr = req.Stderr + return cmd.Run() + case "darwin": + fmt.Fprintln(req.Stdout, "macOS 日志目录:") + fmt.Fprintln(req.Stdout, " /var/log - 系统日志") + fmt.Fprintln(req.Stdout, " ~/Library/Logs - 用户日志") + fmt.Fprintln(req.Stdout, " /Library/Logs - 全局日志") + cmd := exec.CommandContext(ctx, "ls", "-la", "/var/log") + cmd.Stdout = req.Stdout + cmd.Stderr = req.Stderr + return cmd.Run() + case "windows": + cmd := exec.CommandContext(ctx, "wevtutil", "el") + cmd.Stdout = req.Stdout + cmd.Stderr = req.Stderr + return cmd.Run() + default: + return fmt.Errorf("不支持的操作系统: %s", runtime.GOOS) + } +} + // runLogSearch implements `kopsc log search `: search system logs. func runLogSearch(ctx context.Context, req BuiltinRequest) error { opts, err := parseLogSearchArgs(req.Args) diff --git a/internal/executor/svc.go b/internal/executor/svc.go index 4c477c8..50e18de 100644 --- a/internal/executor/svc.go +++ b/internal/executor/svc.go @@ -10,6 +10,29 @@ import ( "strings" ) +// runSvcList implements `kopsc svc list`: list all services. +func runSvcList(ctx context.Context, req BuiltinRequest) error { + switch runtime.GOOS { + case "linux": + cmd := exec.CommandContext(ctx, "systemctl", "list-unit-files", "--type=service", "--no-pager") + cmd.Stdout = req.Stdout + cmd.Stderr = req.Stderr + return cmd.Run() + case "darwin": + cmd := exec.CommandContext(ctx, "launchctl", "list") + cmd.Stdout = req.Stdout + cmd.Stderr = req.Stderr + return cmd.Run() + case "windows": + cmd := exec.CommandContext(ctx, "sc", "query", "state=", "all") + cmd.Stdout = req.Stdout + cmd.Stderr = req.Stderr + return cmd.Run() + default: + return fmt.Errorf("不支持的操作系统: %s", runtime.GOOS) + } +} + // runSvcStatus implements `kopsc svc status `: show service status // and recent log lines in one step. func runSvcStatus(ctx context.Context, req BuiltinRequest) error { diff --git a/internal/registry/builtin.go b/internal/registry/builtin.go index f87d021..d711e96 100644 --- a/internal/registry/builtin.go +++ b/internal/registry/builtin.go @@ -641,6 +641,15 @@ func Builtin() *Registry { }, // ----- svc ----- + { + ID: "svc.list", + Group: "svc", + Summary: "列出所有服务", + Action: "列出系统中所有服务。" + + "Linux: systemctl list-unit-files;macOS: launchctl list;" + + "Windows: sc query state= all", + Variants: threePlatformBuiltins("svc.list"), + }, { ID: "svc.status", Group: "svc", @@ -783,6 +792,14 @@ func Builtin() *Registry { }, // ----- log ----- + { + ID: "log.list", + Group: "log", + Summary: "列出可用的日志来源", + Action: "列出系统中可用的日志来源。" + + "Linux: journalctl --list-boots;macOS: 列出日志目录;Windows: wevtutil el", + Variants: threePlatformBuiltins("log.list"), + }, { ID: "log.search", Group: "log", diff --git a/internal/registry/registry_test.go b/internal/registry/registry_test.go index 8c97157..d82e5bb 100644 --- a/internal/registry/registry_test.go +++ b/internal/registry/registry_test.go @@ -28,12 +28,12 @@ func TestBuiltinIDsStable(t *testing.T) { "disk.usage", "net.pids", "net.ports", "proc.nohup", "proc.wait", "java.run", "git.retime", "pkg.refreshindex", "user.grant", "user.revoke", "file.findbig", "file.findrecent", "file.findname", - "svc.status", "svc.enable", "svc.disable", "svc.logs", + "svc.list", "svc.status", "svc.enable", "svc.disable", "svc.logs", "archive.extract", "sysinfo", "proc.topmem", "proc.topcpu", "proc.killname", "net.ping", "net.trace", "net.dns", "net.curl", - "log.search", "log.last", + "log.list", "log.search", "log.last", "fw.status", "fw.allow", "fw.deny", "net.iface", "net.conn", "net.speed", "proc.tree",