ClickHouse/programs/diagnostics/internal/collectors/system/file.go
2022-07-01 11:43:11 +02:00

101 lines
2.6 KiB
Go

package system
import (
"os"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/collectors"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/config"
"github.com/ClickHouse/ClickHouse/programs/diagnostics/internal/platform/data"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"github.com/yargevad/filepathx"
)
// This collector collects arbitrary user files
type FileCollector struct {
resourceManager *platform.ResourceManager
}
func NewFileCollector(m *platform.ResourceManager) *FileCollector {
return &FileCollector{
resourceManager: m,
}
}
func (f *FileCollector) Collect(conf config.Configuration) (*data.DiagnosticBundle, error) {
conf, err := conf.ValidateConfig(f.Configuration())
if err != nil {
return &data.DiagnosticBundle{}, err
}
filePattern, err := config.ReadStringValue(conf, "file_pattern")
if err != nil {
return &data.DiagnosticBundle{}, err
}
var frameErrors []error
// this util package supports recursive file matching e.g. /**/*
matches, err := filepathx.Glob(filePattern)
if err != nil {
return &data.DiagnosticBundle{}, errors.Wrapf(err, "Invalid file_pattern \"%s\"", filePattern)
}
if len(matches) == 0 {
frameErrors = append(frameErrors, errors.New("0 files match glob pattern"))
return &data.DiagnosticBundle{
Errors: data.FrameErrors{Errors: frameErrors},
}, nil
}
var filePaths []string
for _, match := range matches {
fi, err := os.Stat(match)
if err != nil {
frameErrors = append(frameErrors, errors.Wrapf(err, "Unable to read file %s", match))
}
if !fi.IsDir() {
log.Debug().Msgf("Collecting file %s", match)
filePaths = append(filePaths, match)
}
}
frame := data.NewFileFrame("collection", filePaths)
return &data.DiagnosticBundle{
Errors: data.FrameErrors{Errors: frameErrors},
Frames: map[string]data.Frame{
"collection": frame,
},
}, nil
}
func (f *FileCollector) Configuration() config.Configuration {
return config.Configuration{
Params: []config.ConfigParam{
config.StringParam{
Value: "",
Param: config.NewParam("file_pattern", "Glob based pattern to specify files for collection", true),
AllowEmpty: false,
},
},
}
}
func (f *FileCollector) IsDefault() bool {
return false
}
func (f *FileCollector) Description() string {
return "Allows collection of user specified files"
}
// here we register the collector for use
func init() {
collectors.Register("file", func() (collectors.Collector, error) {
return &FileCollector{
resourceManager: platform.GetResourceManager(),
}, nil
})
}