Unverified Commit aef74613 authored by Massimiliano Pippi's avatar Massimiliano Pippi Committed by GitHub

Add an option to format logs with JSON (#378)

* add an option to format logs with JSON

* added integration tests for log format

* clean up format options
parent b035918c
......@@ -21,6 +21,7 @@ import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/arduino/arduino-cli/cli/board"
"github.com/arduino/arduino-cli/cli/compile"
......@@ -51,8 +52,9 @@ var (
PersistentPreRun: preRun,
}
verbose bool
logFile string
verbose bool
logFile string
logFormat string
)
const (
......@@ -80,6 +82,7 @@ func createCliCommandTree(cmd *cobra.Command) {
cmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Print the logs on the standard output.")
cmd.PersistentFlags().StringVar(&globals.LogLevel, "log-level", defaultLogLevel, "Messages with this level and above will be logged (default: warn).")
cmd.PersistentFlags().StringVar(&logFile, "log-file", "", "Path to the file where logs will be written.")
cmd.PersistentFlags().StringVar(&logFormat, "log-format", "text", "The output format for the logs, can be [text|json].")
cmd.PersistentFlags().StringVar(&globals.OutputFormat, "format", "text", "The output format, can be [text|json].")
cmd.PersistentFlags().StringVar(&globals.YAMLConfigFile, "config-file", "", "The custom config file (if not specified the default will be used).")
cmd.PersistentFlags().StringSliceVar(&globals.AdditionalUrls, "additional-urls", []string{}, "Additional URLs for the board manager.")
......@@ -111,6 +114,10 @@ func parseFormatString(arg string) (feedback.OutputFormat, bool) {
}
func preRun(cmd *cobra.Command, args []string) {
// normalize the format strings
globals.OutputFormat = strings.ToLower(globals.OutputFormat)
logFormat = strings.ToLower(logFormat)
// should we log to file?
if logFile != "" {
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
......@@ -120,7 +127,11 @@ func preRun(cmd *cobra.Command, args []string) {
}
// we use a hook so we don't get color codes in the log file
logrus.AddHook(lfshook.NewHook(file, &logrus.TextFormatter{}))
if logFormat == "json" {
logrus.AddHook(lfshook.NewHook(file, &logrus.JSONFormatter{}))
} else {
logrus.AddHook(lfshook.NewHook(file, &logrus.TextFormatter{}))
}
}
// should we log to stdout?
......@@ -142,15 +153,21 @@ func preRun(cmd *cobra.Command, args []string) {
logrus.SetLevel(lvl)
}
// check the right format was passed
if f, found := parseFormatString(globals.OutputFormat); !found {
// set the Logger format
if logFormat == "json" {
logrus.SetFormatter(&logrus.JSONFormatter{})
}
// check the right output format was passed
format, found := parseFormatString(globals.OutputFormat)
if !found {
feedback.Error("Invalid output format: " + globals.OutputFormat)
os.Exit(errorcodes.ErrBadCall)
} else {
// use the format to configure the Feedback
feedback.SetFormat(f)
}
// use the output format to configure the Feedback
feedback.SetFormat(format)
globals.InitConfigs()
logrus.Info(globals.VersionInfo.Application + "-" + globals.VersionInfo.VersionString)
......
......@@ -12,7 +12,9 @@
# otherwise use the software for commercial activities involving the Arduino
# software without disclosing the source code of your own applications. To purchase
# a commercial license, send an email to license@arduino.cc.
import os
import json
import semver
......@@ -36,3 +38,37 @@ def test_version(run_command):
assert parsed_out.get("Application", False) == "arduino-cli"
assert isinstance(semver.parse(parsed_out.get("VersionString", False)), dict)
assert isinstance(parsed_out.get("Commit", False), str)
def test_log_options(run_command, data_dir):
"""
using `version` as a test command
"""
# no logs
out_lines = run_command("version").stdout.strip().split("\n")
assert len(out_lines) == 1
# plain text logs on stdoud
out_lines = run_command("version -v").stdout.strip().split("\n")
assert len(out_lines) > 1
assert out_lines[0].startswith("\x1b[36mINFO\x1b[0m") # account for the colors
# plain text logs on file
log_file = os.path.join(data_dir, "log.txt")
run_command("version --log-file " + log_file)
with open(log_file) as f:
lines = f.readlines()
assert lines[0].startswith('time="') # file format is different from console
# json on stdout
out_lines = run_command("version -v --log-format JSON").stdout.strip().split("\n")
lg = json.loads(out_lines[0])
assert "level" in lg
# json on file
log_file = os.path.join(data_dir, "log.json")
run_command("version --log-format json --log-file " + log_file)
with open(log_file) as f:
for line in f.readlines():
json.loads(line)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment