-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port fields.yml collector to Golang #6911
Changes from all commits
6fa6659
9ed201e
34b29ae
b324d7a
5976927
befbc51
0643e41
72edf89
25d4374
dbfca67
9556c3a
ed703b9
ffe25f7
476e4ac
f76c40f
96d70b1
926743b
d7a8e57
4e97a8e
f3a6021
9c613ca
12e2a58
e982a79
12ad073
56a4591
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
override FIELDS_FILE_PATH= | ||
export FIELDS_FILE_PATH | ||
|
||
include ../common/Makefile |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,4 +46,4 @@ before-build: | |
|
||
# Collects all dependencies and then calls update | ||
.PHONY: collect | ||
collect: | ||
collect: fields |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,16 @@ | ||
BEAT_TYPE=metricbeat | ||
PREPARE_COMMAND=MODULE=elastic METRICSET=test make create-metricset ; | ||
PREPARE_COMMAND=MODULE=elastic METRICSET=test make create-metricset ; FIELDS_FILE_PATH=module | ||
override FIELDS_FILE_PATH= | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are these 2 lines exactly doing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This overrides There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As auditbeat depends on Metricbeat, would it then be need there too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but only if the |
||
export FIELDS_FILE_PATH | ||
|
||
|
||
include ../common/Makefile | ||
|
||
prepare-test:: python-env | ||
|
||
mkdir -p ${BEAT_PATH}/scripts | ||
rsync -a --exclude=build ${PWD}/../../metricbeat/scripts/generate_imports_helper.py ${BEAT_PATH}/scripts | ||
|
||
# Collects all dependencies and then calls update | ||
.PHONY: collect | ||
collect: fields |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,10 @@ | ||
BEAT_NAME=libbeat | ||
TEST_ENVIRONMENT?=true | ||
SYSTEM_TESTS=true | ||
FIELDS_FILE_PATH=processors | ||
|
||
include scripts/Makefile | ||
|
||
# Collects all fields from processors | ||
.PHONY: fields | ||
fields: | ||
@cp _meta/fields.common.yml _meta/fields.generated.yml | ||
@cat processors/*/_meta/fields.yml >> _meta/fields.generated.yml | ||
|
||
# Collects all dependencies and then calls update | ||
.PHONY: collect | ||
collect: fields | ||
collect: libbeat_fields |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package fields | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"path" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
var ( | ||
generatedFieldsYml = filepath.Join("_meta", "fields.generated.yml") | ||
) | ||
|
||
// YmlFile holds the info on files and how to write them into the global fields.yml | ||
type YmlFile struct { | ||
Path string | ||
Indent int | ||
} | ||
|
||
func collectBeatFiles(beatPath string, fieldFiles []*YmlFile) ([]*YmlFile, error) { | ||
commonFields := filepath.Join(beatPath, "_meta", "fields.common.yml") | ||
_, err := os.Stat(commonFields) | ||
if os.IsNotExist(err) { | ||
return fieldFiles, nil | ||
} else if err != nil { | ||
return nil, err | ||
} | ||
|
||
files := []*YmlFile{ | ||
&YmlFile{ | ||
Path: commonFields, | ||
Indent: 0, | ||
}, | ||
} | ||
|
||
return append(files, fieldFiles...), nil | ||
} | ||
|
||
func writeGeneratedFieldsYml(beatsPath string, fieldFiles []*YmlFile) error { | ||
outPath := path.Join(beatsPath, generatedFieldsYml) | ||
f, err := os.Create(outPath) | ||
if err != nil { | ||
return err | ||
} | ||
defer f.Close() | ||
|
||
fw := bufio.NewWriter(f) | ||
for _, p := range fieldFiles { | ||
ff, err := os.Open(p.Path) | ||
if err != nil { | ||
return err | ||
} | ||
defer ff.Close() | ||
|
||
fs := bufio.NewScanner(ff) | ||
for fs.Scan() { | ||
err = writeIndentedLine(fw, fs.Text()+"\n", p.Indent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
} | ||
if err := fs.Err(); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func writeIndentedLine(fw *bufio.Writer, l string, indent int) error { | ||
ll := strings.Repeat(" ", indent) + l | ||
fmt.Fprint(fw, ll) | ||
return fw.Flush() | ||
} | ||
|
||
// Generate collects fields.yml files and concatenates them into one global file. | ||
func Generate(esBeatsPath, beatPath string, files []*YmlFile) error { | ||
files, err := collectBeatFiles(beatPath, files) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = writeGeneratedFieldsYml(beatPath, files) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return AppendFromLibbeat(esBeatsPath, beatPath) | ||
} | ||
|
||
// AppendFromLibbeat appends fields.yml of libbeat to the fields.yml | ||
func AppendFromLibbeat(esBeatsPath, beatPath string) error { | ||
fieldsMetaPath := path.Join(beatPath, "_meta", "fields.yml") | ||
generatedPath := path.Join(beatPath, generatedFieldsYml) | ||
|
||
err := createIfNotExists(fieldsMetaPath, generatedPath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if isLibbeat(beatPath) { | ||
out := filepath.Join(esBeatsPath, "libbeat", "fields.yml") | ||
return copyFileWithFlag(generatedPath, out, os.O_RDWR|os.O_CREATE|os.O_TRUNC) | ||
} | ||
|
||
libbeatPath := filepath.Join(esBeatsPath, "libbeat", generatedFieldsYml) | ||
out := filepath.Join(beatPath, "fields.yml") | ||
err = copyFileWithFlag(libbeatPath, out, os.O_RDWR|os.O_CREATE|os.O_TRUNC) | ||
if err != nil { | ||
return err | ||
} | ||
return copyFileWithFlag(generatedPath, out, os.O_WRONLY|os.O_APPEND) | ||
} | ||
|
||
func isLibbeat(beatPath string) bool { | ||
return filepath.Base(beatPath) == "libbeat" | ||
} | ||
|
||
func createIfNotExists(inPath, outPath string) error { | ||
_, err := os.Stat(outPath) | ||
if os.IsNotExist(err) { | ||
err := copyFileWithFlag(inPath, outPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC) | ||
if err != nil { | ||
fmt.Println("Cannot find _meta/fields.yml") | ||
} | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
func copyFileWithFlag(in, out string, flag int) error { | ||
input, err := ioutil.ReadFile(in) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
output, err := os.OpenFile(out, flag, 0644) | ||
if err != nil { | ||
return err | ||
} | ||
defer output.Close() | ||
|
||
_, err = output.Write(input) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to set permissions somewhere here to 644? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return err | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package fields | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
) | ||
|
||
var indentByModule = map[string]int{ | ||
"processors": 0, | ||
"module": 8, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a bit a pity that libbeat has knowledge here outside the scope of libbeat. But probably best way to go for now. |
||
"active": 8, | ||
"protos": 8, | ||
} | ||
|
||
// CollectModuleFiles looks for fields.yml files under the | ||
// specified root directory | ||
func CollectModuleFiles(root string) ([]*YmlFile, error) { | ||
modules, err := ioutil.ReadDir(root) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var files []*YmlFile | ||
for _, m := range modules { | ||
f, err := collectFiles(m, root) | ||
if err != nil { | ||
return nil, err | ||
} | ||
files = append(files, f...) | ||
} | ||
|
||
return files, nil | ||
} | ||
|
||
func collectFiles(module os.FileInfo, modulesPath string) ([]*YmlFile, error) { | ||
if !module.IsDir() { | ||
return nil, nil | ||
} | ||
|
||
var files []*YmlFile | ||
fieldsYmlPath := filepath.Join(modulesPath, module.Name(), "_meta", "fields.yml") | ||
if _, err := os.Stat(fieldsYmlPath); !os.IsNotExist(err) { | ||
files = append(files, &YmlFile{ | ||
Path: fieldsYmlPath, | ||
Indent: 0, | ||
}) | ||
} else if !os.IsNotExist(err) && err != nil { | ||
return nil, err | ||
} | ||
|
||
modulesRoot := filepath.Base(modulesPath) | ||
sets, err := ioutil.ReadDir(filepath.Join(modulesPath, module.Name())) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
for _, s := range sets { | ||
if !s.IsDir() { | ||
continue | ||
} | ||
|
||
fieldsYmlPath = filepath.Join(modulesPath, module.Name(), s.Name(), "_meta", "fields.yml") | ||
if _, err = os.Stat(fieldsYmlPath); !os.IsNotExist(err) { | ||
files = append(files, &YmlFile{ | ||
Path: fieldsYmlPath, | ||
Indent: indentByModule[modulesRoot], | ||
}) | ||
} else if !os.IsNotExist(err) && err != nil { | ||
return nil, err | ||
} | ||
} | ||
return files, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this only support one path? I could see especially in libbeat or filebeat that a module, processor and inputs have fields.yml.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but it can be changed easily to support lists.