Skip to content

Commit 7639143

Browse files
committed
TUN-7393: Add json output for cloudflared tail
cloudflared tail now has a `--output=json` that will allow it to easily pipe into tools like jq for a more structured view of the streaming logs.
1 parent e8841c0 commit 7639143

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

cmd/cloudflared/tail/cmd.go

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ func buildTailCommand(subcommands []*cli.Command) *cli.Command {
9999
Value: "",
100100
EnvVars: []string{"TUNNEL_MANAGEMENT_TOKEN"},
101101
},
102+
&cli.StringFlag{
103+
Name: "output",
104+
Usage: "Output format for the logs (default, json)",
105+
Value: "default",
106+
EnvVars: []string{"TUNNEL_MANAGEMENT_OUTPUT"},
107+
},
102108
&cli.StringFlag{
103109
Name: "management-hostname",
104110
Usage: "Management hostname to signify incoming management requests",
@@ -270,6 +276,24 @@ func buildURL(c *cli.Context, log *zerolog.Logger) (url.URL, error) {
270276
return url.URL{Scheme: "wss", Host: managementHostname, Path: "/logs", RawQuery: query.Encode()}, nil
271277
}
272278

279+
func printLine(log *management.Log, logger *zerolog.Logger) {
280+
fields, err := json.Marshal(log.Fields)
281+
if err != nil {
282+
fields = []byte("unable to parse fields")
283+
logger.Debug().Msgf("unable to parse fields from event %+v", log)
284+
}
285+
fmt.Printf("%s %s %s %s %s\n", log.Time, log.Level, log.Event, log.Message, fields)
286+
}
287+
288+
func printJSON(log *management.Log, logger *zerolog.Logger) {
289+
output, err := json.Marshal(log)
290+
if err != nil {
291+
logger.Debug().Msgf("unable to parse event to json %+v", log)
292+
} else {
293+
fmt.Println(string(output))
294+
}
295+
}
296+
273297
// Run implements a foreground runner
274298
func Run(c *cli.Context) error {
275299
log := createLogger(c)
@@ -278,6 +302,16 @@ func Run(c *cli.Context) error {
278302
signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT)
279303
defer signal.Stop(signals)
280304

305+
output := "default"
306+
switch c.String("output") {
307+
case "default", "":
308+
output = "default"
309+
case "json":
310+
output = "json"
311+
default:
312+
log.Err(errors.New("invalid --output value provided, please make sure it is one of: default, json")).Send()
313+
}
314+
281315
filters, err := parseFilters(c)
282316
if err != nil {
283317
log.Error().Err(err).Msgf("invalid filters provided")
@@ -358,12 +392,11 @@ func Run(c *cli.Context) error {
358392
}
359393
// Output all the logs received to stdout
360394
for _, l := range logs.Logs {
361-
fields, err := json.Marshal(l.Fields)
362-
if err != nil {
363-
fields = []byte("unable to parse fields")
364-
log.Debug().Msgf("unable to parse fields from event %+v", l)
395+
if output == "json" {
396+
printJSON(l, log)
397+
} else {
398+
printLine(l, log)
365399
}
366-
fmt.Printf("%s %s %s %s %s\n", l.Time, l.Level, l.Event, l.Message, fields)
367400
}
368401
case management.UnknownServerEventType:
369402
fallthrough

0 commit comments

Comments
 (0)