Skip to content

Commit 4dcdbab

Browse files
committed
feat: support streaming of rule logs
1 parent 7ea959a commit 4dcdbab

File tree

7 files changed

+117
-0
lines changed

7 files changed

+117
-0
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/enapter/enapter-cli
33
go 1.21
44

55
require (
6+
github.com/gorilla/websocket v1.5.3
67
github.com/stretchr/testify v1.9.0
78
github.com/urfave/cli/v2 v2.27.4
89
)

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB
22
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
33
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
44
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
6+
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
57
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
68
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
79
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=

internal/app/enaptercli/cmd_base.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"net/url"
1313
"strings"
1414

15+
"github.com/gorilla/websocket"
1516
"github.com/urfave/cli/v2"
1617
)
1718

@@ -122,6 +123,32 @@ func (c *cmdBase) doHTTPRequest(ctx context.Context, p doHTTPRequestParams) erro
122123
return p.RespProcessor(resp)
123124
}
124125

126+
func (c *cmdBase) dialWebSocket(ctx context.Context, path string) (*websocket.Conn, error) {
127+
url, err := url.Parse(c.apiHost + "/v3" + path)
128+
if err != nil {
129+
return nil, fmt.Errorf("parse url: %w", err)
130+
}
131+
if url.Scheme == "https" {
132+
url.Scheme = "wss"
133+
} else {
134+
url.Scheme = "ws"
135+
}
136+
137+
headers := make(http.Header)
138+
headers.Add("X-Enapter-Auth-Token", c.token)
139+
140+
//nolint:bodyclose // body should be closed by callers
141+
conn, resp, err := websocket.DefaultDialer.DialContext(ctx, url.String(), headers)
142+
if err != nil {
143+
return nil, fmt.Errorf("dial: %w", err)
144+
}
145+
if resp.StatusCode != http.StatusSwitchingProtocols {
146+
return nil, cli.Exit(parseRespErrorMessage(resp), 1)
147+
}
148+
149+
return conn, nil
150+
}
151+
125152
func (c *cmdBase) defaultRespProcessor(resp *http.Response) error {
126153
if resp.StatusCode != http.StatusOK {
127154
return cli.Exit(parseRespErrorMessage(resp), 1)

internal/app/enaptercli/cmd_rule_engine_rule.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func buildCmdRuleEngineRule() *cli.Command {
3030
buildCmdRuleEngineRuleList(),
3131
buildCmdRuleEngineRuleUpdate(),
3232
buildCmdRuleEngineRuleUpdateScript(),
33+
buildCmdRuleEngineRuleLogsf(),
3334
},
3435
}
3536
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package enaptercli
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/urfave/cli/v2"
7+
)
8+
9+
type cmdRuleEngineRuleLogsf struct {
10+
cmdRuleEngineRule
11+
ruleID string
12+
}
13+
14+
func buildCmdRuleEngineRuleLogsf() *cli.Command {
15+
cmd := &cmdRuleEngineRuleLogsf{}
16+
return &cli.Command{
17+
Name: "logsf",
18+
Usage: "Stream rule logs",
19+
CustomHelpTemplate: cmd.HelpTemplate(),
20+
Flags: cmd.Flags(),
21+
Before: cmd.Before,
22+
Action: func(cliCtx *cli.Context) error {
23+
return cmd.do(cliCtx)
24+
},
25+
}
26+
}
27+
28+
func (c *cmdRuleEngineRuleLogsf) Flags() []cli.Flag {
29+
return append(c.cmdRuleEngineRule.Flags(),
30+
&cli.StringFlag{
31+
Name: "rule-id",
32+
Usage: "Rule ID or slug to update",
33+
Destination: &c.ruleID,
34+
Required: true,
35+
},
36+
)
37+
}
38+
39+
func (c *cmdRuleEngineRuleLogsf) do(cliCtx *cli.Context) error {
40+
path := fmt.Sprintf("/site/rule_engine/rules/%s/logs/ws", c.ruleID)
41+
conn, err := c.dialWebSocket(cliCtx.Context, path)
42+
if err != nil {
43+
return fmt.Errorf("dial ws: %w", err)
44+
}
45+
defer conn.Close()
46+
47+
for {
48+
select {
49+
case <-cliCtx.Done():
50+
return nil
51+
default:
52+
}
53+
54+
_, payload, err := conn.ReadMessage()
55+
if err != nil {
56+
return fmt.Errorf("read: %w", err)
57+
}
58+
59+
select {
60+
case <-cliCtx.Done():
61+
return nil
62+
default:
63+
}
64+
65+
payload = append(payload, '\n')
66+
if _, err = c.writer.Write(payload); err != nil {
67+
return fmt.Errorf("write: %w", err)
68+
}
69+
}
70+
}

internal/app/enaptercli/testdata/helps/enapter rule-engine rule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ COMMANDS:
1313
list List rules
1414
update Update a rule
1515
update-script Update the script of a rule
16+
logsf Stream rule logs
1617
help, h Shows a list of commands or help for one command
1718

1819
OPTIONS:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
NAME:
2+
enaptercli.test rule-engine rule logsf - Stream rule logs
3+
4+
USAGE:
5+
enaptercli.test rule-engine rule logsf [command options]
6+
7+
OPTIONS:
8+
--verbose log extra details about operation (default: false)
9+
--rule-id value Rule ID or slug to update
10+
--help, -h show help
11+
12+
ENVIRONMENT VARIABLES:
13+
ENAPTER3_API_TOKEN Enapter API access token
14+
ENAPTER3_API_HOST Enapter API base URL (https://api.enapter.com by default)
15+

0 commit comments

Comments
 (0)