@pippit-dev/cli 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/checksums.txt +6 -6
- package/cmd/short_drama/short_drama.go +60 -10
- package/cmd/short_drama_test.go +62 -0
- package/internal/common/error_log.go +91 -0
- package/internal/common/error_log_test.go +61 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,6 +41,11 @@ Only `.doc`, `.docx`, and `.txt` file extensions are supported.
|
|
|
41
41
|
`+download-result` downloads the result URL to
|
|
42
42
|
the `--output-path` file path.
|
|
43
43
|
|
|
44
|
+
Short drama command errors are appended to a daily local log file under
|
|
45
|
+
`~/.pippit_tool_cli/logs/yyyy-mm-dd.log`. The path is built with the current
|
|
46
|
+
user home directory and the platform path separator, so it works on macOS,
|
|
47
|
+
Linux, and Windows.
|
|
48
|
+
|
|
44
49
|
## HTTP Client
|
|
45
50
|
|
|
46
51
|
Command modules should receive `common.Runner` for service calls. Runtime
|
package/checksums.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
2cd3bb5e214d85004196806643c3b7d0a8ceb141ef3df58d1bbfc7aa9642f6ab pippit-tool-cli-0.0.18-darwin-amd64.tar.gz
|
|
2
|
+
8fb57bef9d7e81b8bcc3421f2179879b656134c23387104e01a1090022f6e7c9 pippit-tool-cli-0.0.18-darwin-arm64.tar.gz
|
|
3
|
+
bdde278cbee36f2b90602b1b58f7be05790a186b3adbc90b8dd8fd970b48b20c pippit-tool-cli-0.0.18-linux-amd64.tar.gz
|
|
4
|
+
878c6b0cd41a2cafdd62f99be98968eee05f0d16de0c6b173f84bb0328c1bef6 pippit-tool-cli-0.0.18-linux-arm64.tar.gz
|
|
5
|
+
e4423154ba1a52625f255e11060459844a4c5bcf3aab21af682f3e1adcce82cd pippit-tool-cli-0.0.18-windows-amd64.zip
|
|
6
|
+
cca47eab19bdc7200aabcea2d59a535c63267fe293f993b1013aa049a4be16b4 pippit-tool-cli-0.0.18-windows-arm64.zip
|
|
@@ -3,6 +3,8 @@ package short_drama
|
|
|
3
3
|
import (
|
|
4
4
|
"fmt"
|
|
5
5
|
"io"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strconv"
|
|
6
8
|
"strings"
|
|
7
9
|
|
|
8
10
|
"github.com/Pippit-dev/pippit-cli/internal/common"
|
|
@@ -35,7 +37,12 @@ func newShortDramaSubmitRunCommand(stdout, stderr io.Writer, runner *common.Runn
|
|
|
35
37
|
Use: "+submit-run",
|
|
36
38
|
Short: "Submit a Run task for the short drama scene",
|
|
37
39
|
Args: cobra.NoArgs,
|
|
38
|
-
RunE:
|
|
40
|
+
RunE: withErrorLog("short-drama +submit-run", func() map[string]string {
|
|
41
|
+
return map[string]string{
|
|
42
|
+
"thread_id": opts.ThreadID,
|
|
43
|
+
"asset_count": strconv.Itoa(len(opts.AssetIDs)),
|
|
44
|
+
}
|
|
45
|
+
}, func(cmd *cobra.Command, _ []string) error {
|
|
39
46
|
opts.Message = strings.TrimSpace(opts.Message)
|
|
40
47
|
opts.ThreadID = strings.TrimSpace(opts.ThreadID)
|
|
41
48
|
|
|
@@ -48,7 +55,7 @@ func newShortDramaSubmitRunCommand(stdout, stderr io.Writer, runner *common.Runn
|
|
|
48
55
|
return err
|
|
49
56
|
}
|
|
50
57
|
return writeJSON(stdout, result)
|
|
51
|
-
},
|
|
58
|
+
}),
|
|
52
59
|
}
|
|
53
60
|
cmd.SetOut(stdout)
|
|
54
61
|
cmd.SetErr(stderr)
|
|
@@ -65,7 +72,11 @@ func newShortDramaUploadFileCommand(stdout, stderr io.Writer, runner *common.Run
|
|
|
65
72
|
Use: "+upload-file",
|
|
66
73
|
Short: "Upload a file for the short drama scene",
|
|
67
74
|
Args: cobra.NoArgs,
|
|
68
|
-
RunE:
|
|
75
|
+
RunE: withErrorLog("short-drama +upload-file", func() map[string]string {
|
|
76
|
+
return map[string]string{
|
|
77
|
+
"file_name": fileNameForLog(opts.Path),
|
|
78
|
+
}
|
|
79
|
+
}, func(cmd *cobra.Command, _ []string) error {
|
|
69
80
|
opts.Path = strings.TrimSpace(opts.Path)
|
|
70
81
|
|
|
71
82
|
if opts.Path == "" {
|
|
@@ -77,7 +88,7 @@ func newShortDramaUploadFileCommand(stdout, stderr io.Writer, runner *common.Run
|
|
|
77
88
|
return err
|
|
78
89
|
}
|
|
79
90
|
return writeJSON(stdout, result)
|
|
80
|
-
},
|
|
91
|
+
}),
|
|
81
92
|
}
|
|
82
93
|
cmd.SetOut(stdout)
|
|
83
94
|
cmd.SetErr(stderr)
|
|
@@ -92,7 +103,13 @@ func newShortDramaDownloadResultCommand(stdout, stderr io.Writer, runner *common
|
|
|
92
103
|
Use: "+download-result",
|
|
93
104
|
Short: "Download a generated result URL",
|
|
94
105
|
Args: cobra.NoArgs,
|
|
95
|
-
RunE:
|
|
106
|
+
RunE: withErrorLog("short-drama +download-result", func() map[string]string {
|
|
107
|
+
return map[string]string{
|
|
108
|
+
"output_path": opts.OutputPath,
|
|
109
|
+
"has_url": strconv.FormatBool(strings.TrimSpace(opts.URL) != ""),
|
|
110
|
+
"workers": strconv.Itoa(opts.Workers),
|
|
111
|
+
}
|
|
112
|
+
}, func(cmd *cobra.Command, _ []string) error {
|
|
96
113
|
opts.OutputPath = strings.TrimSpace(opts.OutputPath)
|
|
97
114
|
if opts.OutputPath == "" {
|
|
98
115
|
return fmt.Errorf("--output-path is required")
|
|
@@ -110,7 +127,7 @@ func newShortDramaDownloadResultCommand(stdout, stderr io.Writer, runner *common
|
|
|
110
127
|
return err
|
|
111
128
|
}
|
|
112
129
|
return writeJSON(stdout, result)
|
|
113
|
-
},
|
|
130
|
+
}),
|
|
114
131
|
}
|
|
115
132
|
cmd.SetOut(stdout)
|
|
116
133
|
cmd.SetErr(stderr)
|
|
@@ -127,7 +144,12 @@ func newShortDramaGetThreadCommand(stdout, stderr io.Writer, runner *common.Runn
|
|
|
127
144
|
Use: "+get-thread",
|
|
128
145
|
Short: "Get a short drama thread detail",
|
|
129
146
|
Args: cobra.NoArgs,
|
|
130
|
-
RunE:
|
|
147
|
+
RunE: withErrorLog("short-drama +get-thread", func() map[string]string {
|
|
148
|
+
return map[string]string{
|
|
149
|
+
"thread_id": opts.ThreadID,
|
|
150
|
+
"run_id": opts.RunID,
|
|
151
|
+
}
|
|
152
|
+
}, func(cmd *cobra.Command, _ []string) error {
|
|
131
153
|
opts.ThreadID = strings.TrimSpace(opts.ThreadID)
|
|
132
154
|
if opts.ThreadID == "" {
|
|
133
155
|
return fmt.Errorf("--thread-id is required")
|
|
@@ -140,7 +162,7 @@ func newShortDramaGetThreadCommand(stdout, stderr io.Writer, runner *common.Runn
|
|
|
140
162
|
}
|
|
141
163
|
_, err = fmt.Fprintln(stdout, result.ReadableText)
|
|
142
164
|
return err
|
|
143
|
-
},
|
|
165
|
+
}),
|
|
144
166
|
}
|
|
145
167
|
cmd.SetOut(stdout)
|
|
146
168
|
cmd.SetErr(stderr)
|
|
@@ -156,7 +178,13 @@ func newShortDramaListThreadFileCommand(stdout, stderr io.Writer, runner *common
|
|
|
156
178
|
Use: "+list-thread-file",
|
|
157
179
|
Short: "List files in a short drama thread",
|
|
158
180
|
Args: cobra.NoArgs,
|
|
159
|
-
RunE:
|
|
181
|
+
RunE: withErrorLog("short-drama +list-thread-file", func() map[string]string {
|
|
182
|
+
return map[string]string{
|
|
183
|
+
"thread_id": opts.ThreadID,
|
|
184
|
+
"page_num": strconv.Itoa(opts.PageNum),
|
|
185
|
+
"page_size": strconv.Itoa(opts.PageSize),
|
|
186
|
+
}
|
|
187
|
+
}, func(cmd *cobra.Command, _ []string) error {
|
|
160
188
|
opts.ThreadID = strings.TrimSpace(opts.ThreadID)
|
|
161
189
|
if opts.ThreadID == "" {
|
|
162
190
|
return fmt.Errorf("--thread-id is required")
|
|
@@ -173,7 +201,7 @@ func newShortDramaListThreadFileCommand(stdout, stderr io.Writer, runner *common
|
|
|
173
201
|
return err
|
|
174
202
|
}
|
|
175
203
|
return writeJSON(stdout, result)
|
|
176
|
-
},
|
|
204
|
+
}),
|
|
177
205
|
}
|
|
178
206
|
cmd.SetOut(stdout)
|
|
179
207
|
cmd.SetErr(stderr)
|
|
@@ -183,6 +211,28 @@ func newShortDramaListThreadFileCommand(stdout, stderr io.Writer, runner *common
|
|
|
183
211
|
return cmd
|
|
184
212
|
}
|
|
185
213
|
|
|
214
|
+
func withErrorLog(command string, fields func() map[string]string, run func(*cobra.Command, []string) error) func(*cobra.Command, []string) error {
|
|
215
|
+
return func(cmd *cobra.Command, args []string) error {
|
|
216
|
+
err := run(cmd, args)
|
|
217
|
+
if err != nil {
|
|
218
|
+
logFields := map[string]string(nil)
|
|
219
|
+
if fields != nil {
|
|
220
|
+
logFields = fields()
|
|
221
|
+
}
|
|
222
|
+
_ = common.AppendDailyErrorLog(command, err, logFields)
|
|
223
|
+
}
|
|
224
|
+
return err
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
func fileNameForLog(path string) string {
|
|
229
|
+
path = strings.TrimSpace(path)
|
|
230
|
+
if path == "" {
|
|
231
|
+
return ""
|
|
232
|
+
}
|
|
233
|
+
return filepath.Base(path)
|
|
234
|
+
}
|
|
235
|
+
|
|
186
236
|
func writeJSON(w io.Writer, v any) error {
|
|
187
237
|
data, err := sonic.Marshal(v)
|
|
188
238
|
if err != nil {
|
package/cmd/short_drama_test.go
CHANGED
|
@@ -9,6 +9,7 @@ import (
|
|
|
9
9
|
"path/filepath"
|
|
10
10
|
"strings"
|
|
11
11
|
"testing"
|
|
12
|
+
"time"
|
|
12
13
|
|
|
13
14
|
"github.com/Pippit-dev/pippit-cli/internal/common"
|
|
14
15
|
"github.com/Pippit-dev/pippit-cli/internal/config"
|
|
@@ -17,6 +18,19 @@ import (
|
|
|
17
18
|
"github.com/spf13/cobra"
|
|
18
19
|
)
|
|
19
20
|
|
|
21
|
+
func TestMain(m *testing.M) {
|
|
22
|
+
home, err := os.MkdirTemp("", "pippit-cli-test-home")
|
|
23
|
+
if err != nil {
|
|
24
|
+
panic(err)
|
|
25
|
+
}
|
|
26
|
+
_ = os.Setenv("HOME", home)
|
|
27
|
+
_ = os.Setenv("USERPROFILE", home)
|
|
28
|
+
|
|
29
|
+
code := m.Run()
|
|
30
|
+
_ = os.RemoveAll(home)
|
|
31
|
+
os.Exit(code)
|
|
32
|
+
}
|
|
33
|
+
|
|
20
34
|
func TestShortDramaSubmitRun(t *testing.T) {
|
|
21
35
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
22
36
|
if r.Method != http.MethodPost {
|
|
@@ -597,6 +611,8 @@ func TestShortDramaGetThread(t *testing.T) {
|
|
|
597
611
|
}
|
|
598
612
|
|
|
599
613
|
func TestShortDramaGetThreadRequiresThreadID(t *testing.T) {
|
|
614
|
+
clearDailyErrorLog(t)
|
|
615
|
+
|
|
600
616
|
var stdout, stderr bytes.Buffer
|
|
601
617
|
root := NewRootCommand(&stdout, &stderr)
|
|
602
618
|
root.SetArgs([]string{"short-drama", "+get-thread"})
|
|
@@ -608,6 +624,17 @@ func TestShortDramaGetThreadRequiresThreadID(t *testing.T) {
|
|
|
608
624
|
if !strings.Contains(err.Error(), "--thread-id is required") {
|
|
609
625
|
t.Fatalf("error = %q, want thread-id validation", err)
|
|
610
626
|
}
|
|
627
|
+
|
|
628
|
+
entries := readDailyErrorLog(t)
|
|
629
|
+
if len(entries) != 1 {
|
|
630
|
+
t.Fatalf("log entries = %d, want 1: %#v", len(entries), entries)
|
|
631
|
+
}
|
|
632
|
+
if entries[0]["command"] != "short-drama +get-thread" {
|
|
633
|
+
t.Fatalf("command = %v, want get-thread", entries[0]["command"])
|
|
634
|
+
}
|
|
635
|
+
if entries[0]["error"] != "--thread-id is required" {
|
|
636
|
+
t.Fatalf("error = %v, want thread-id validation", entries[0]["error"])
|
|
637
|
+
}
|
|
611
638
|
}
|
|
612
639
|
|
|
613
640
|
func TestShortDramaGetThreadRequiresAccessKey(t *testing.T) {
|
|
@@ -787,6 +814,41 @@ func decodeJSON(t *testing.T, data []byte) map[string]any {
|
|
|
787
814
|
return got
|
|
788
815
|
}
|
|
789
816
|
|
|
817
|
+
func clearDailyErrorLog(t *testing.T) {
|
|
818
|
+
t.Helper()
|
|
819
|
+
if err := os.RemoveAll(filepath.Join(testHomeDir(t), ".pippit_tool_cli", "logs")); err != nil {
|
|
820
|
+
t.Fatalf("RemoveAll logs: %v", err)
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
func readDailyErrorLog(t *testing.T) []map[string]any {
|
|
825
|
+
t.Helper()
|
|
826
|
+
path := filepath.Join(testHomeDir(t), ".pippit_tool_cli", "logs", time.Now().Format("2006-01-02")+".log")
|
|
827
|
+
data, err := os.ReadFile(path)
|
|
828
|
+
if err != nil {
|
|
829
|
+
t.Fatalf("ReadFile(%s): %v", path, err)
|
|
830
|
+
}
|
|
831
|
+
lines := strings.Split(strings.TrimSpace(string(data)), "\n")
|
|
832
|
+
entries := make([]map[string]any, 0, len(lines))
|
|
833
|
+
for _, line := range lines {
|
|
834
|
+
var entry map[string]any
|
|
835
|
+
if err := sonic.Unmarshal([]byte(line), &entry); err != nil {
|
|
836
|
+
t.Fatalf("decode log line: %v\n%s", err, line)
|
|
837
|
+
}
|
|
838
|
+
entries = append(entries, entry)
|
|
839
|
+
}
|
|
840
|
+
return entries
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
func testHomeDir(t *testing.T) string {
|
|
844
|
+
t.Helper()
|
|
845
|
+
home, err := os.UserHomeDir()
|
|
846
|
+
if err != nil {
|
|
847
|
+
t.Fatalf("UserHomeDir(): %v", err)
|
|
848
|
+
}
|
|
849
|
+
return home
|
|
850
|
+
}
|
|
851
|
+
|
|
790
852
|
func chdirTemp(t *testing.T) string {
|
|
791
853
|
t.Helper()
|
|
792
854
|
cwd := t.TempDir()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
package common
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"time"
|
|
8
|
+
|
|
9
|
+
"github.com/bytedance/sonic"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
const (
|
|
13
|
+
errorLogDirName = ".pippit_tool_cli"
|
|
14
|
+
errorLogSubdir = "logs"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
type errorLogEntry struct {
|
|
18
|
+
Time string `json:"time"`
|
|
19
|
+
Command string `json:"command"`
|
|
20
|
+
Fields map[string]string `json:"fields,omitempty"`
|
|
21
|
+
Error string `json:"error"`
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// AppendDailyErrorLog appends one CLI error record to ~/.pippit_tool_cli/logs/yyyy-mm-dd.log.
|
|
25
|
+
func AppendDailyErrorLog(command string, err error, fields map[string]string) error {
|
|
26
|
+
if err == nil {
|
|
27
|
+
return nil
|
|
28
|
+
}
|
|
29
|
+
now := time.Now()
|
|
30
|
+
path, pathErr := dailyErrorLogPath(now)
|
|
31
|
+
if pathErr != nil {
|
|
32
|
+
return pathErr
|
|
33
|
+
}
|
|
34
|
+
if mkErr := os.MkdirAll(filepath.Dir(path), 0o700); mkErr != nil {
|
|
35
|
+
return mkErr
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
entry := errorLogEntry{
|
|
39
|
+
Time: now.Format(time.RFC3339),
|
|
40
|
+
Command: strings.TrimSpace(command),
|
|
41
|
+
Fields: cleanErrorLogFields(fields),
|
|
42
|
+
Error: err.Error(),
|
|
43
|
+
}
|
|
44
|
+
data, marshalErr := sonic.Marshal(entry)
|
|
45
|
+
if marshalErr != nil {
|
|
46
|
+
return marshalErr
|
|
47
|
+
}
|
|
48
|
+
data = append(data, '\n')
|
|
49
|
+
file, openErr := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
|
|
50
|
+
if openErr != nil {
|
|
51
|
+
return openErr
|
|
52
|
+
}
|
|
53
|
+
defer file.Close()
|
|
54
|
+
_, writeErr := file.Write(data)
|
|
55
|
+
return writeErr
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
func dailyErrorLogPath(now time.Time) (string, error) {
|
|
59
|
+
home, err := os.UserHomeDir()
|
|
60
|
+
if err != nil {
|
|
61
|
+
return "", err
|
|
62
|
+
}
|
|
63
|
+
return filepath.Join(home, errorLogDirName, errorLogSubdir, now.Format("2006-01-02")+".log"), nil
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
func cleanErrorLogFields(fields map[string]string) map[string]string {
|
|
67
|
+
if len(fields) == 0 {
|
|
68
|
+
return nil
|
|
69
|
+
}
|
|
70
|
+
cleaned := make(map[string]string, len(fields))
|
|
71
|
+
for k, v := range fields {
|
|
72
|
+
key := strings.TrimSpace(k)
|
|
73
|
+
value := strings.TrimSpace(v)
|
|
74
|
+
if key == "" || value == "" || isSensitiveLogField(key) {
|
|
75
|
+
continue
|
|
76
|
+
}
|
|
77
|
+
cleaned[key] = value
|
|
78
|
+
}
|
|
79
|
+
if len(cleaned) == 0 {
|
|
80
|
+
return nil
|
|
81
|
+
}
|
|
82
|
+
return cleaned
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func isSensitiveLogField(key string) bool {
|
|
86
|
+
key = strings.ToLower(key)
|
|
87
|
+
return strings.Contains(key, "access") ||
|
|
88
|
+
strings.Contains(key, "authorization") ||
|
|
89
|
+
strings.Contains(key, "secret") ||
|
|
90
|
+
strings.Contains(key, "token")
|
|
91
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
package common
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"os"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
"time"
|
|
10
|
+
|
|
11
|
+
"github.com/bytedance/sonic"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
func TestAppendDailyErrorLog(t *testing.T) {
|
|
15
|
+
home := t.TempDir()
|
|
16
|
+
t.Setenv("HOME", home)
|
|
17
|
+
t.Setenv("USERPROFILE", home)
|
|
18
|
+
|
|
19
|
+
err := AppendDailyErrorLog("short-drama +get-thread", fmt.Errorf("request failed"), map[string]string{
|
|
20
|
+
"thread_id": "thread_123",
|
|
21
|
+
"access_key": "secret",
|
|
22
|
+
"empty": "",
|
|
23
|
+
})
|
|
24
|
+
if err != nil {
|
|
25
|
+
t.Fatalf("AppendDailyErrorLog(): %v", err)
|
|
26
|
+
}
|
|
27
|
+
if err := AppendDailyErrorLog("short-drama +get-thread", fmt.Errorf("second failure"), nil); err != nil {
|
|
28
|
+
t.Fatalf("AppendDailyErrorLog() second call: %v", err)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
path := filepath.Join(home, ".pippit_tool_cli", "logs", time.Now().Format("2006-01-02")+".log")
|
|
32
|
+
data, err := os.ReadFile(path)
|
|
33
|
+
if err != nil {
|
|
34
|
+
t.Fatalf("ReadFile(%s): %v", path, err)
|
|
35
|
+
}
|
|
36
|
+
lines := strings.Split(strings.TrimSpace(string(data)), "\n")
|
|
37
|
+
if len(lines) != 2 {
|
|
38
|
+
t.Fatalf("log lines = %d, want 2\n%s", len(lines), string(data))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var first map[string]any
|
|
42
|
+
if err := sonic.Unmarshal([]byte(lines[0]), &first); err != nil {
|
|
43
|
+
t.Fatalf("decode first log line: %v\n%s", err, lines[0])
|
|
44
|
+
}
|
|
45
|
+
if first["command"] != "short-drama +get-thread" {
|
|
46
|
+
t.Fatalf("command = %v, want get-thread command", first["command"])
|
|
47
|
+
}
|
|
48
|
+
if first["error"] != "request failed" {
|
|
49
|
+
t.Fatalf("error = %v, want request failed", first["error"])
|
|
50
|
+
}
|
|
51
|
+
fields, ok := first["fields"].(map[string]any)
|
|
52
|
+
if !ok {
|
|
53
|
+
t.Fatalf("fields = %#v, want object", first["fields"])
|
|
54
|
+
}
|
|
55
|
+
if fields["thread_id"] != "thread_123" {
|
|
56
|
+
t.Fatalf("thread_id = %v, want thread_123", fields["thread_id"])
|
|
57
|
+
}
|
|
58
|
+
if _, ok := fields["access_key"]; ok {
|
|
59
|
+
t.Fatalf("access_key should be omitted from log fields: %#v", fields)
|
|
60
|
+
}
|
|
61
|
+
}
|