diff --git a/README.md b/README.md index aff488be..cca6e345 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ fetch-redhat: [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For the first time, run the blow command to fetch data for all versions. $ goval-dictionary fetch-redhat 5 6 7 @@ -103,6 +104,8 @@ For the first time, run the blow command to fetch data for all versions. quiet mode (no output) -log-dir string /path/to/log (default "/var/log/vuls") + -log-json + output log as JSON ``` - Import OVAL data from Internet @@ -126,6 +129,7 @@ fetch-debian: [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For the first time, run the blow command to fetch data for all versions. $ goval-dictionary fetch-debian 7 8 9 10 @@ -144,6 +148,8 @@ For the first time, run the blow command to fetch data for all versions. quiet mode (no output) -log-dir string /path/to/log (default "/var/log/vuls") + -log-json + output log as JSON ``` - Import OVAL data from Internet @@ -167,6 +173,7 @@ fetch-ubuntu: [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For the first time, run the blow command to fetch data for all versions. $ goval-dictionary fetch-ubuntu 12 14 16 @@ -185,6 +192,8 @@ For the first time, run the blow command to fetch data for all versions. quiet mode (no output) -log-dir string /path/to/log (default "/var/log/vuls") + -log-json + output log as JSON ``` - Import OVAL data from Internet @@ -213,6 +222,7 @@ fetch-suse: [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For the first time, run the blow command to fetch data for all versions. $ goval-dictionary fetch-suse -opensuse 13.2 @@ -231,6 +241,8 @@ For the first time, run the blow command to fetch data for all versions. quiet mode (no output) -log-dir string /path/to/log (default "/var/log/vuls") + -log-json + output log as JSON -opensuse OpenSUSE -opensuse-leap @@ -265,6 +277,7 @@ fetch-oracle: [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For the first time, run the blow command to fetch data for all versions. $ goval-dictionary fetch-oracle @@ -283,6 +296,8 @@ For the first time, run the blow command to fetch data for all versions. quiet mode (no output) -log-dir string /path/to/log (default "/var/log/vuls") + -log-json + output log as JSON ``` - Import OVAL data from Internet @@ -307,6 +322,7 @@ fetch-alpine: [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] The version list is here https://git.alpinelinux.org/cgit/alpine-secdb/tree/ $ goval-dictionary fetch-alpine 3.3 3.4 3.5 3.6 @@ -323,6 +339,8 @@ The version list is here https://git.alpinelinux.org/cgit/alpine-secdb/tree/ http://proxy-url:port (default: empty) -log-dir string /path/to/log (default "/var/log/vuls") + -log-json + output log as JSON -quiet quiet mode (no output) ``` @@ -349,6 +367,7 @@ fetch-amazon: [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] $ goval-dictionary fetch-amazon @@ -364,6 +383,8 @@ fetch-amazon: http://proxy-url:port (default: empty) -log-dir string /path/to/log (default "/var/log/vuls") + -log-json + output log as JSON -quiet quiet mode (no output) ``` @@ -815,6 +836,7 @@ server: [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] -bind string HTTP server bind to IP address (default: loop back interface) (default "127.0.0.1") @@ -830,6 +852,8 @@ server: quiet mode (no output) -log-dir string /path/to/log (default "/var/log/vuls") + -log-json + output log as JSON -port string HTTP server port number (default: 1324) diff --git a/commands/fetch-alpine.go b/commands/fetch-alpine.go index 13f827fc..03d3c240 100644 --- a/commands/fetch-alpine.go +++ b/commands/fetch-alpine.go @@ -25,6 +25,7 @@ type FetchAlpineCmd struct { DebugSQL bool Quiet bool LogDir string + LogJSON bool DBPath string DBType string HTTPProxy string @@ -47,6 +48,7 @@ func (*FetchAlpineCmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] The version list is here https://git.alpinelinux.org/cgit/alpine-secdb/tree/ $ goval-dictionary fetch-alpine 3.3 3.4 3.5 3.6 @@ -62,6 +64,7 @@ func (p *FetchAlpineCmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.LogDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.LogJSON, "log-json", false, "output log as JSON") pwd := os.Getenv("PWD") f.StringVar(&p.DBPath, "dbpath", pwd+"/oval.sqlite3", @@ -87,7 +90,7 @@ func (p *FetchAlpineCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interf c.Conf.DBType = p.DBType c.Conf.HTTPProxy = p.HTTPProxy - util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug, p.LogJSON) if !c.Conf.Validate() { return subcommands.ExitUsageError } diff --git a/commands/fetch-amazon.go b/commands/fetch-amazon.go index 85fe490f..741fb996 100644 --- a/commands/fetch-amazon.go +++ b/commands/fetch-amazon.go @@ -24,6 +24,7 @@ type FetchAmazonCmd struct { DebugSQL bool Quiet bool LogDir string + LogJSON bool DBPath string DBType string HTTPProxy string @@ -46,6 +47,7 @@ func (*FetchAmazonCmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] $ goval-dictionary fetch-amazon ` @@ -59,6 +61,7 @@ func (p *FetchAmazonCmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.LogDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.LogJSON, "log-json", false, "output log as JSON") pwd := os.Getenv("PWD") f.StringVar(&p.DBPath, "dbpath", pwd+"/oval.sqlite3", @@ -84,7 +87,7 @@ func (p *FetchAmazonCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interf c.Conf.DBType = p.DBType c.Conf.HTTPProxy = p.HTTPProxy - util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug, p.LogJSON) if !c.Conf.Validate() { return subcommands.ExitUsageError } diff --git a/commands/fetch-debian.go b/commands/fetch-debian.go index 163296ac..61f04a7e 100644 --- a/commands/fetch-debian.go +++ b/commands/fetch-debian.go @@ -25,6 +25,7 @@ type FetchDebianCmd struct { DebugSQL bool Quiet bool LogDir string + LogJSON bool DBPath string DBType string HTTPProxy string @@ -47,6 +48,7 @@ func (*FetchDebianCmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For details, see https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-debian $ goval-dictionary fetch-debian 7 8 9 10 @@ -62,6 +64,7 @@ func (p *FetchDebianCmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.LogDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.LogJSON, "log-json", false, "output log as JSON") pwd := os.Getenv("PWD") f.StringVar(&p.DBPath, "dbpath", pwd+"/oval.sqlite3", @@ -87,7 +90,7 @@ func (p *FetchDebianCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interf c.Conf.DBType = p.DBType c.Conf.HTTPProxy = p.HTTPProxy - util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug, p.LogJSON) if !c.Conf.Validate() { return subcommands.ExitUsageError } diff --git a/commands/fetch-oracle.go b/commands/fetch-oracle.go index e48d98e8..0d577a8f 100644 --- a/commands/fetch-oracle.go +++ b/commands/fetch-oracle.go @@ -24,6 +24,7 @@ type FetchOracleCmd struct { DebugSQL bool Quiet bool LogDir string + LogJSON bool DBPath string DBType string HTTPProxy string @@ -46,6 +47,7 @@ func (*FetchOracleCmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For details, see https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-oracle $ goval-dictionary fetch-oracle @@ -61,6 +63,7 @@ func (p *FetchOracleCmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.LogDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.LogJSON, "log-json", false, "output log as json") pwd := os.Getenv("PWD") f.StringVar(&p.DBPath, "dbpath", pwd+"/oval.sqlite3", @@ -86,7 +89,7 @@ func (p *FetchOracleCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interf c.Conf.DBType = p.DBType c.Conf.HTTPProxy = p.HTTPProxy - util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug, p.LogJSON) if !c.Conf.Validate() { return subcommands.ExitUsageError } diff --git a/commands/fetch-redhat.go b/commands/fetch-redhat.go index 68c36787..cf7d988a 100644 --- a/commands/fetch-redhat.go +++ b/commands/fetch-redhat.go @@ -25,6 +25,7 @@ type FetchRedHatCmd struct { DebugSQL bool Quiet bool LogDir string + LogJSON bool DBPath string DBType string HTTPProxy string @@ -47,6 +48,7 @@ func (*FetchRedHatCmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For details, see https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-redhat @@ -65,6 +67,7 @@ func (p *FetchRedHatCmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.LogDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.LogJSON, "log-json", false, "output log as JSON") pwd := os.Getenv("PWD") f.StringVar(&p.DBPath, "dbpath", pwd+"/oval.sqlite3", @@ -90,7 +93,7 @@ func (p *FetchRedHatCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interf c.Conf.DBType = p.DBType c.Conf.HTTPProxy = p.HTTPProxy - util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug, p.LogJSON) if !c.Conf.Validate() { return subcommands.ExitUsageError } diff --git a/commands/fetch-suse.go b/commands/fetch-suse.go index e2afac22..fb68ea99 100644 --- a/commands/fetch-suse.go +++ b/commands/fetch-suse.go @@ -30,6 +30,7 @@ type FetchSUSECmd struct { DebugSQL bool Quiet bool LogDir string + LogJSON bool DBPath string DBType string HTTPProxy string @@ -58,6 +59,7 @@ func (*FetchSUSECmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For details, see https://github.com/kotakanbe/goval-dictionary#usage-fetch-oval-data-from-suse $ goval-dictionary fetch-suse -opensuse 13.2 @@ -80,6 +82,7 @@ func (p *FetchSUSECmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.LogDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.LogJSON, "log-json", false, "output log as JSON") pwd := os.Getenv("PWD") f.StringVar(&p.DBPath, "dbpath", pwd+"/oval.sqlite3", @@ -102,7 +105,7 @@ func (p *FetchSUSECmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interfac c.Conf.DBType = p.DBType c.Conf.HTTPProxy = p.HTTPProxy - util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug, p.LogJSON) if !c.Conf.Validate() { return subcommands.ExitUsageError } diff --git a/commands/fetch-ubuntu.go b/commands/fetch-ubuntu.go index caedab56..af115f10 100644 --- a/commands/fetch-ubuntu.go +++ b/commands/fetch-ubuntu.go @@ -24,6 +24,7 @@ type FetchUbuntuCmd struct { DebugSQL bool Quiet bool LogDir string + LogJSON bool DBPath string DBType string HTTPProxy string @@ -46,6 +47,7 @@ func (*FetchUbuntuCmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] For the first time, run the blow command to fetch data for all versions. $ goval-dictionary fetch-ubuntu 12 14 16 @@ -61,6 +63,7 @@ func (p *FetchUbuntuCmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.LogDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.LogJSON, "log-json", false, "output log as JSON") pwd := os.Getenv("PWD") f.StringVar(&p.DBPath, "dbpath", pwd+"/oval.sqlite3", @@ -86,7 +89,7 @@ func (p *FetchUbuntuCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interf c.Conf.DBType = p.DBType c.Conf.HTTPProxy = p.HTTPProxy - util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug, p.LogJSON) if !c.Conf.Validate() { return subcommands.ExitUsageError } diff --git a/commands/select.go b/commands/select.go index 391af415..e15a5be5 100644 --- a/commands/select.go +++ b/commands/select.go @@ -22,6 +22,7 @@ type SelectCmd struct { DBType string Quiet bool LogDir string + LogJSON bool ByPackage bool ByCveID bool @@ -42,6 +43,7 @@ func (*SelectCmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] [-by-package] redhat 7 bind [-by-cveid] redhat 7 CVE-2017-6009 @@ -56,6 +58,7 @@ func (p *SelectCmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.LogDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.LogJSON, "log-json", false, "output log as JSON") pwd := os.Getenv("PWD") f.StringVar(&p.DBPath, "dbpath", pwd+"/oval.sqlite3", @@ -74,7 +77,7 @@ func (p *SelectCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{} c.Conf.DBPath = p.DBPath c.Conf.DBType = p.DBType - util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.LogDir, c.Conf.Quiet, c.Conf.Debug, p.LogJSON) if f.NArg() != 3 { log15.Crit(` Usage: diff --git a/commands/server.go b/commands/server.go index b9d83ec0..e0d3eb06 100644 --- a/commands/server.go +++ b/commands/server.go @@ -19,6 +19,7 @@ type ServerCmd struct { debugSQL bool quiet bool logDir string + logJSON bool dbpath string dbtype string @@ -44,6 +45,7 @@ func (*ServerCmd) Usage() string { [-debug-sql] [-quiet] [-log-dir=/path/to/log] + [-log-json] ` } @@ -56,6 +58,7 @@ func (p *ServerCmd) SetFlags(f *flag.FlagSet) { defaultLogDir := util.GetDefaultLogDir() f.StringVar(&p.logDir, "log-dir", defaultLogDir, "/path/to/log") + f.BoolVar(&p.logJSON, "log-json", false, "output log as JSON") pwd := os.Getenv("PWD") f.StringVar(&p.dbpath, "dbpath", pwd+"/oval.sqlite3", @@ -82,7 +85,7 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{} c.Conf.DBPath = p.dbpath c.Conf.DBType = p.dbtype - util.SetLogger(p.logDir, c.Conf.Quiet, c.Conf.Debug) + util.SetLogger(p.logDir, c.Conf.Quiet, c.Conf.Debug, p.logJSON) if !c.Conf.Validate() { return subcommands.ExitUsageError } diff --git a/util/util.go b/util/util.go index b607a051..fe48e79d 100644 --- a/util/util.go +++ b/util/util.go @@ -33,10 +33,17 @@ func GetDefaultLogDir() string { } // SetLogger set logger -func SetLogger(logDir string, quiet, debug bool) { - lvlHundler := log15.LvlFilterHandler(log15.LvlInfo, log15.StderrHandler) +func SetLogger(logDir string, quiet, debug, logJSON bool) { + stderrHundler := log15.StderrHandler + logFormat := log15.LogfmtFormat() + if logJSON { + logFormat = log15.JsonFormatEx(false, true) + stderrHundler = log15.StreamHandler(os.Stderr, logFormat) + } + + lvlHundler := log15.LvlFilterHandler(log15.LvlInfo, stderrHundler) if debug { - lvlHundler = log15.LvlFilterHandler(log15.LvlDebug, log15.StdoutHandler) + lvlHundler = log15.LvlFilterHandler(log15.LvlDebug, stderrHundler) } if quiet { lvlHundler = log15.LvlFilterHandler(log15.LvlDebug, log15.DiscardHandler()) @@ -52,7 +59,7 @@ func SetLogger(logDir string, quiet, debug bool) { if _, err := os.Stat(logDir); err == nil { logPath := filepath.Join(logDir, "goval-dictionary.log") hundler = log15.MultiHandler( - log15.Must.FileHandler(logPath, log15.LogfmtFormat()), + log15.Must.FileHandler(logPath, logFormat), lvlHundler, ) } else {