1diff --git a/pico/cli.go b/pico/cli.go
2index 613873d..48e7909 100644
3--- a/pico/cli.go
4+++ b/pico/cli.go
5@@ -1,6 +1,8 @@
6 package pico
7
8 import (
9+ "bufio"
10+ "encoding/json"
11 "fmt"
12 "log/slog"
13 "strings"
14@@ -34,12 +36,13 @@ func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) {
15 }
16
17 type Cmd struct {
18- User *db.User
19- Session shared.CmdSession
20- Log *slog.Logger
21- Dbpool db.DB
22- Write bool
23- Styles common.Styles
24+ User *db.User
25+ SshSession ssh.Session
26+ Session shared.CmdSession
27+ Log *slog.Logger
28+ Dbpool db.DB
29+ Write bool
30+ Styles common.Styles
31 }
32
33 func (c *Cmd) output(out string) {
34@@ -62,6 +65,59 @@ func (c *Cmd) notifications() error {
35 return nil
36 }
37
38+func (c *Cmd) logs() error {
39+ sshClient, err := shared.CreateSSHClient(
40+ shared.GetEnv("PICO_SENDLOG_ENDPOINT", "send.pico.sh:22"),
41+ shared.GetEnv("PICO_SENDLOG_KEY", "ssh_data/term_info_ed25519"),
42+ shared.GetEnv("PICO_SENDLOG_PASSPHRASE", ""),
43+ shared.GetEnv("PICO_SENDLOG_REMOTE_HOST", "send.pico.sh"),
44+ shared.GetEnv("PICO_SENDLOG_USER", "pico"),
45+ )
46+ if err != nil {
47+ return err
48+ }
49+ defer sshClient.Close()
50+
51+ session, err := sshClient.NewSession()
52+ defer func() {
53+ _ = session.Close()
54+ }()
55+ if err != nil {
56+ return err
57+ }
58+
59+ stdoutPipe, err := session.StdoutPipe()
60+ if err != nil {
61+ return err
62+ }
63+
64+ err = session.Start("sub log-drain -k")
65+ if err != nil {
66+ return err
67+ }
68+
69+ scanner := bufio.NewScanner(stdoutPipe)
70+ for scanner.Scan() {
71+ line := scanner.Text()
72+ parsedData := map[string]any{}
73+
74+ err := json.Unmarshal([]byte(line), &parsedData)
75+ if err != nil {
76+ c.Log.Error("json unmarshal", "err", err)
77+ continue
78+ }
79+
80+ if userName, ok := parsedData["user"]; ok {
81+ if userName, ok := userName.(string); ok {
82+ if userName == c.User.Name {
83+ wish.Println(c.SshSession, line)
84+ }
85+ }
86+ }
87+ }
88+ return scanner.Err()
89+}
90+
91 type CliHandler struct {
92 DBPool db.DB
93 Logger *slog.Logger
94@@ -113,11 +169,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
95 }
96
97 opts := Cmd{
98- Session: sesh,
99- User: user,
100- Log: log,
101- Dbpool: dbpool,
102- Write: false,
103+ Session: sesh,
104+ SshSession: sesh,
105+ User: user,
106+ Log: log,
107+ Dbpool: dbpool,
108+ Write: false,
109 }
110
111 cmd := strings.TrimSpace(args[0])
112@@ -125,6 +182,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
113 if cmd == "help" {
114 opts.help()
115 return
116+ } else if cmd == "logs" {
117+ err = opts.logs()
118+ if err != nil {
119+ wish.Fatalln(sesh, err)
120+ }
121+ return
122 } else if cmd == "pico+" {
123 opts.plus()
124 return
125diff --git a/shared/sendlog.go b/shared/sendlog.go
126index 7d9a476..b407ef7 100644
127--- a/shared/sendlog.go
128+++ b/shared/sendlog.go
129@@ -138,7 +138,7 @@ func (c *SendLogWriter) Open() error {
130 c.Done = make(chan struct{})
131 c.Messages = make(chan []byte, c.BufferSize)
132
133- sshClient, err := createSSHClient(
134+ sshClient, err := CreateSSHClient(
135 GetEnv("PICO_SENDLOG_ENDPOINT", "send.pico.sh:22"),
136 GetEnv("PICO_SENDLOG_KEY", "ssh_data/term_info_ed25519"),
137 GetEnv("PICO_SENDLOG_PASSPHRASE", ""),
138@@ -248,7 +248,7 @@ func (c *SendLogWriter) Reconnect() {
139 }()
140 }
141
142-func createSSHClient(remoteHost string, keyLocation string, keyPassphrase string, remoteHostname string, remoteUser string) (*ssh.Client, error) {
143+func CreateSSHClient(remoteHost string, keyLocation string, keyPassphrase string, remoteHostname string, remoteUser string) (*ssh.Client, error) {
144 if !strings.Contains(remoteHost, ":") {
145 remoteHost += ":22"
146 }