mirror of
https://github.com/anchore/syft
synced 2024-11-13 23:57:07 +00:00
replace panics with logging
This commit is contained in:
parent
b7c7c5556d
commit
09c7ca8f8f
9 changed files with 73 additions and 26 deletions
|
@ -1,18 +1,20 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/anchore/imgbom/imgbom"
|
"github.com/anchore/imgbom/imgbom"
|
||||||
"github.com/anchore/imgbom/internal/config"
|
"github.com/anchore/imgbom/internal/config"
|
||||||
|
"github.com/anchore/imgbom/internal/log"
|
||||||
"github.com/anchore/imgbom/internal/logger"
|
"github.com/anchore/imgbom/internal/logger"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appConfig *config.Application
|
var appConfig *config.Application
|
||||||
|
|
||||||
func loadAppConfig() {
|
func initAppConfig() {
|
||||||
cfg, err := config.LoadConfigFromFile(viper.GetViper(), &cliOpts)
|
cfg, err := config.LoadConfigFromFile(viper.GetViper(), &cliOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to load application config: \n\t%+v\n", err)
|
fmt.Printf("failed to load application config: \n\t%+v\n", err)
|
||||||
|
@ -21,7 +23,7 @@ func loadAppConfig() {
|
||||||
appConfig = cfg
|
appConfig = cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupLoggingFromAppConfig() {
|
func initLogging() {
|
||||||
config := logger.LogConfig{
|
config := logger.LogConfig{
|
||||||
EnableConsole: appConfig.Log.FileLocation == "" && !appConfig.Quiet,
|
EnableConsole: appConfig.Log.FileLocation == "" && !appConfig.Quiet,
|
||||||
EnableFile: appConfig.Log.FileLocation != "",
|
EnableFile: appConfig.Log.FileLocation != "",
|
||||||
|
@ -32,3 +34,12 @@ func setupLoggingFromAppConfig() {
|
||||||
|
|
||||||
imgbom.SetLogger(logger.NewZapLogger(config))
|
imgbom.SetLogger(logger.NewZapLogger(config))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func logAppConfig() {
|
||||||
|
appCfgStr, err := json.MarshalIndent(&appConfig, " ", " ")
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("Could not display application config: %+v", err)
|
||||||
|
} else {
|
||||||
|
log.Debugf("Application config:\n%+v", string(appCfgStr))
|
||||||
|
}
|
||||||
|
}
|
19
cmd/root.go
19
cmd/root.go
|
@ -1,7 +1,6 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -31,8 +30,9 @@ Supports the following image sources:
|
||||||
func init() {
|
func init() {
|
||||||
setCliOptions()
|
setCliOptions()
|
||||||
|
|
||||||
cobra.OnInitialize(loadAppConfig)
|
cobra.OnInitialize(initAppConfig)
|
||||||
cobra.OnInitialize(setupLoggingFromAppConfig)
|
cobra.OnInitialize(initLogging)
|
||||||
|
cobra.OnInitialize(logAppConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Execute() {
|
func Execute() {
|
||||||
|
@ -43,15 +43,8 @@ func Execute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRunCmd(cmd *cobra.Command, args []string) {
|
func doRunCmd(cmd *cobra.Command, args []string) {
|
||||||
appCfgStr, err := json.MarshalIndent(&appConfig, " ", " ")
|
|
||||||
if err != nil {
|
|
||||||
log.Debugf("could not display application config: %+v", err)
|
|
||||||
} else {
|
|
||||||
log.Debugf("application config:\n%+v", string(appCfgStr))
|
|
||||||
}
|
|
||||||
|
|
||||||
userImageStr := args[0]
|
userImageStr := args[0]
|
||||||
log.Infof("fetching image %s...", userImageStr)
|
log.Infof("Fetching image '%s'", userImageStr)
|
||||||
img, err := stereoscope.GetImage(userImageStr)
|
img, err := stereoscope.GetImage(userImageStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("could not fetch image '%s': %w", userImageStr, err)
|
log.Errorf("could not fetch image '%s': %w", userImageStr, err)
|
||||||
|
@ -59,14 +52,14 @@ func doRunCmd(cmd *cobra.Command, args []string) {
|
||||||
}
|
}
|
||||||
defer stereoscope.Cleanup()
|
defer stereoscope.Cleanup()
|
||||||
|
|
||||||
log.Info("cataloging image...")
|
log.Info("Cataloging image")
|
||||||
catalog, err := imgbom.CatalogImage(img, appConfig.ScopeOpt)
|
catalog, err := imgbom.CatalogImage(img, appConfig.ScopeOpt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("could not catalog image: %w", err)
|
log.Errorf("could not catalog image: %w", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("done!")
|
log.Info("Complete!")
|
||||||
err = presenter.GetPresenter(appConfig.PresenterOpt).Present(os.Stdout, img, catalog)
|
err = presenter.GetPresenter(appConfig.PresenterOpt).Present(os.Stdout, img, catalog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("could not format catalog results: %w", err)
|
log.Errorf("could not format catalog results: %w", err)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Analyzer interface {
|
type Analyzer interface {
|
||||||
|
Name() string
|
||||||
// TODO: add ID / Name for analyze for uniquely identifying this analyzer type
|
// TODO: add ID / Name for analyze for uniquely identifying this analyzer type
|
||||||
SelectFiles([]*tree.FileTree) []file.Reference
|
SelectFiles([]*tree.FileTree) []file.Reference
|
||||||
// NOTE: one of the errors which is returned is "IterationNeeded", which indicates to the driver to
|
// NOTE: one of the errors which is returned is "IterationNeeded", which indicates to the driver to
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"github.com/anchore/imgbom/imgbom/analyzer/dpkg"
|
"github.com/anchore/imgbom/imgbom/analyzer/dpkg"
|
||||||
"github.com/anchore/imgbom/imgbom/pkg"
|
"github.com/anchore/imgbom/imgbom/pkg"
|
||||||
"github.com/anchore/imgbom/imgbom/scope"
|
"github.com/anchore/imgbom/imgbom/scope"
|
||||||
|
"github.com/anchore/imgbom/internal/log"
|
||||||
"github.com/anchore/stereoscope/pkg/file"
|
"github.com/anchore/stereoscope/pkg/file"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
)
|
)
|
||||||
|
@ -26,6 +27,7 @@ type controller struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) add(a Analyzer) {
|
func (c *controller) add(a Analyzer) {
|
||||||
|
log.Debugf("adding analyzer: %s", a.Name())
|
||||||
c.analyzers = append(c.analyzers, a)
|
c.analyzers = append(c.analyzers, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +38,7 @@ func (c *controller) analyze(s scope.Scope) (pkg.Catalog, error) {
|
||||||
// ask analyzers for files to extract from the image tar
|
// ask analyzers for files to extract from the image tar
|
||||||
for _, a := range c.analyzers {
|
for _, a := range c.analyzers {
|
||||||
fileSelection = append(fileSelection, a.SelectFiles(s.Trees)...)
|
fileSelection = append(fileSelection, a.SelectFiles(s.Trees)...)
|
||||||
|
log.Debugf("analyzer '%s' selected '%d' files", a.Name(), len(fileSelection))
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch contents for requested selection by analyzers
|
// fetch contents for requested selection by analyzers
|
||||||
|
@ -47,11 +50,15 @@ func (c *controller) analyze(s scope.Scope) (pkg.Catalog, error) {
|
||||||
// perform analysis, accumulating errors for each failed analysis
|
// perform analysis, accumulating errors for each failed analysis
|
||||||
var errs error
|
var errs error
|
||||||
for _, a := range c.analyzers {
|
for _, a := range c.analyzers {
|
||||||
packages, err := a.Analyze(contents)
|
|
||||||
// TODO: check for multiple rounds of analyses by Iterate error
|
// TODO: check for multiple rounds of analyses by Iterate error
|
||||||
|
packages, err := a.Analyze(contents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = multierror.Append(errs, err)
|
errs = multierror.Append(errs, err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("analyzer '%s' discovered '%d' packages", a.Name(), len(packages))
|
||||||
|
|
||||||
for _, p := range packages {
|
for _, p := range packages {
|
||||||
catalog.Add(p)
|
catalog.Add(p)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/anchore/imgbom/imgbom/pkg"
|
"github.com/anchore/imgbom/imgbom/pkg"
|
||||||
|
"github.com/anchore/imgbom/internal/log"
|
||||||
"github.com/anchore/stereoscope/pkg/file"
|
"github.com/anchore/stereoscope/pkg/file"
|
||||||
"github.com/anchore/stereoscope/pkg/tree"
|
"github.com/anchore/stereoscope/pkg/tree"
|
||||||
)
|
)
|
||||||
|
@ -16,6 +17,10 @@ func NewAnalyzer() *Analyzer {
|
||||||
return &Analyzer{}
|
return &Analyzer{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Analyzer) Name() string {
|
||||||
|
return "dpkg-analyzer"
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Analyzer) SelectFiles(trees []*tree.FileTree) []file.Reference {
|
func (a *Analyzer) SelectFiles(trees []*tree.FileTree) []file.Reference {
|
||||||
files := make([]file.Reference, 0)
|
files := make([]file.Reference, 0)
|
||||||
for _, tree := range trees {
|
for _, tree := range trees {
|
||||||
|
@ -36,14 +41,26 @@ func (a *Analyzer) Analyze(contents map[file.Reference]string) ([]pkg.Package, e
|
||||||
for _, reference := range a.selectedFiles {
|
for _, reference := range a.selectedFiles {
|
||||||
content, ok := contents[reference]
|
content, ok := contents[reference]
|
||||||
if !ok {
|
if !ok {
|
||||||
// TODO: this needs handling
|
// TODO: test case
|
||||||
panic(reference)
|
log.WithFields(map[string]interface{}{
|
||||||
|
"path": reference.Path,
|
||||||
|
"id": reference.ID(),
|
||||||
|
"analyzer": a.Name(),
|
||||||
|
}).Errorf("analyzer file content missing")
|
||||||
|
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
entries, err := ParseEntries(strings.NewReader(content))
|
entries, err := ParseEntries(strings.NewReader(content))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: punt for now, we need to handle this
|
// TODO: test case
|
||||||
panic(err)
|
log.WithFields(map[string]interface{}{
|
||||||
|
"path": reference.Path,
|
||||||
|
"id": reference.ID(),
|
||||||
|
"analyzer": a.Name(),
|
||||||
|
}).Errorf("analyzer failed to parse entries: %w", err)
|
||||||
|
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
packages = append(packages, pkg.Package{
|
packages = append(packages, pkg.Package{
|
||||||
|
@ -55,5 +72,6 @@ func (a *Analyzer) Analyze(contents map[file.Reference]string) ([]pkg.Package, e
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return packages, nil
|
return packages, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ func TestSinglePackage(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
err := file.Close()
|
err := file.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
t.Fatal("closing file failed:", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ func TestMultiplePackages(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
err := file.Close()
|
err := file.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
t.Fatal("closing file failed:", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
4
imgbom/constants.go
Normal file
4
imgbom/constants.go
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
package imgbom
|
||||||
|
|
||||||
|
// note: must be a single word, all lowercase
|
||||||
|
const LibraryName = "imgbom"
|
|
@ -8,3 +8,9 @@ import (
|
||||||
func SetLogger(logger logger.Logger) {
|
func SetLogger(logger logger.Logger) {
|
||||||
log.Log = logger
|
log.Log = logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetLoggerWithTags(logger logger.Logger, tags map[string]interface{}) {
|
||||||
|
log.Log = logger.WithFields(map[string]interface{}{
|
||||||
|
"source": LibraryName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/anchore/imgbom/imgbom/pkg"
|
"github.com/anchore/imgbom/imgbom/pkg"
|
||||||
|
"github.com/anchore/imgbom/internal/log"
|
||||||
stereoscopeImg "github.com/anchore/stereoscope/pkg/image"
|
stereoscopeImg "github.com/anchore/stereoscope/pkg/image"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -88,8 +89,13 @@ func (pres *Presenter) Present(output io.Writer, img *stereoscopeImg.Image, cata
|
||||||
for idx, src := range p.Source {
|
for idx, src := range p.Source {
|
||||||
fileMetadata, err := img.FileCatalog.Get(src)
|
fileMetadata, err := img.FileCatalog.Get(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: replace
|
// TODO: test case
|
||||||
panic(err)
|
log.WithFields(map[string]interface{}{
|
||||||
|
"path": src.Path,
|
||||||
|
"id": src.ID(),
|
||||||
|
"presenter": "json",
|
||||||
|
}).Errorf("could not get metadata from catalog")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srcObj := source{
|
srcObj := source{
|
||||||
|
@ -105,8 +111,9 @@ func (pres *Presenter) Present(output io.Writer, img *stereoscopeImg.Image, cata
|
||||||
|
|
||||||
bytes, err := json.Marshal(&doc)
|
bytes, err := json.Marshal(&doc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: replace
|
log.WithFields(map[string]interface{}{
|
||||||
panic(err)
|
"presenter": "json",
|
||||||
|
}).Errorf("failed to marshal json: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = output.Write(bytes)
|
_, err = output.Write(bytes)
|
||||||
|
|
Loading…
Reference in a new issue