-
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
WIP - multiple templates #9247
WIP - multiple templates #9247
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,8 @@ import ( | |
"bytes" | ||
"compress/zlib" | ||
"encoding/base64" | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
) | ||
|
||
|
@@ -42,7 +44,7 @@ func SetFields(beat, name string, asset func() string) error { | |
return nil | ||
} | ||
|
||
// GetFields returns a byte array contains all fields for the given beat | ||
// GetFields returns a byte array containing all fields for the given beat | ||
func GetFields(beat string) ([]byte, error) { | ||
var fields []byte | ||
for _, data := range FieldsRegistry[beat] { | ||
|
@@ -56,6 +58,25 @@ func GetFields(beat string) ([]byte, error) { | |
return fields, nil | ||
} | ||
|
||
// GetFieldsFor returns a byte array containing all fields for the given beat | ||
// and given names | ||
func GetFieldsFor(beat string, names []string) ([]byte, error) { | ||
var fields []byte | ||
for _, name := range names { | ||
data, ok := FieldsRegistry[beat][name] | ||
if !ok { | ||
return nil, errors.New(fmt.Sprintf("No fields available for %s", name)) | ||
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. should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...) |
||
} | ||
output, err := DecodeData(data) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
fields = append(fields, output...) | ||
} | ||
return fields, nil | ||
} | ||
|
||
// EncodeData compresses the data with zlib and base64 encodes it | ||
func EncodeData(data string) (string, error) { | ||
var zlibBuf bytes.Buffer | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,7 +64,7 @@ type Beat struct { | |
|
||
BeatConfig *common.Config // The beat's own configuration section | ||
|
||
Fields []byte // Data from fields.yml | ||
//Fields []byte // Data from fields.yml | ||
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. Why remove this? The libbeat/beat package is supposed to be the (most...) stable API beats devs are facing/interacting with. We should try to reduce the change of breakages... Maybe we've been better off if Fields would have been an interface or not been added at all to the Beats structure. Was Fields even used? 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. Afaics 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. In case you consider removing this a breaking change, I can leave it. It wouldn't be used any more though, so to avoid confusion and errors, I prefer removing it. 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. I did a quick look, I don't see it used outside of creating the template. Lets say that I've used Fields in my code how I move it to the new workflow? |
||
|
||
ConfigManager management.ConfigManager // config manager | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,7 +38,6 @@ import ( | |
"go.uber.org/zap" | ||
|
||
"github.com/elastic/beats/libbeat/api" | ||
"github.com/elastic/beats/libbeat/asset" | ||
"github.com/elastic/beats/libbeat/beat" | ||
"github.com/elastic/beats/libbeat/cfgfile" | ||
"github.com/elastic/beats/libbeat/cloudid" | ||
|
@@ -196,11 +195,6 @@ func NewBeat(name, indexPrefix, v string) (*Beat, error) { | |
return nil, err | ||
} | ||
|
||
fields, err := asset.GetFields(name) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
id, err := uuid.NewV4() | ||
if err != nil { | ||
return nil, err | ||
|
@@ -215,7 +209,7 @@ func NewBeat(name, indexPrefix, v string) (*Beat, error) { | |
Hostname: hostname, | ||
UUID: id, | ||
}, | ||
Fields: fields, | ||
//Fields: fields, | ||
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. We should remove this.. following the change in the struct. 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. Sure, once we decided to remove in the struct, I'll also remove it here. ATM both is commented out as discussions are going on. |
||
} | ||
|
||
return &Beat{Beat: b}, nil | ||
|
@@ -719,7 +713,7 @@ func (b *Beat) loadDashboards(ctx context.Context, force bool) error { | |
// the elasticsearch output. It is important the the registration happens before | ||
// the publisher is created. | ||
func (b *Beat) registerTemplateLoading() error { | ||
var cfg template.TemplateConfig | ||
var cfg template.TemplatesConfig | ||
|
||
// Check if outputting to file is enabled, and output to file if it is | ||
if b.Config.Template.Enabled() { | ||
|
@@ -741,13 +735,14 @@ func (b *Beat) registerTemplateLoading() error { | |
return err | ||
} | ||
|
||
if esCfg.Index != "" && (cfg.Name == "" || cfg.Pattern == "") && (b.Config.Template == nil || b.Config.Template.Enabled()) { | ||
//TODO: what to do with this check with Indices? | ||
if esCfg.Index != "" && (len(cfg.Templates) == 0 || cfg.Templates[0].Name == "" || cfg.Templates[0].Pattern == "") && (b.Config.Template == nil || b.Config.Template.Enabled()) { | ||
return fmt.Errorf("setup.template.name and setup.template.pattern have to be set if index name is modified.") | ||
} | ||
|
||
if b.Config.Template == nil || (b.Config.Template != nil && b.Config.Template.Enabled()) { | ||
|
||
// load template through callback to make sure it is also loaded | ||
// load templates through callback to make sure it is also loaded | ||
// on reconnecting | ||
callback, err := b.templateLoadingCallback() | ||
if err != nil { | ||
|
@@ -760,14 +755,14 @@ func (b *Beat) registerTemplateLoading() error { | |
return nil | ||
} | ||
|
||
// Build and return a callback to load index template into ES | ||
// Build and return a callback to load index templates into ES | ||
func (b *Beat) templateLoadingCallback() (func(esClient *elasticsearch.Client) error, error) { | ||
callback := func(esClient *elasticsearch.Client) error { | ||
if b.Config.Template == nil { | ||
b.Config.Template = common.NewConfig() | ||
} | ||
|
||
loader, err := template.NewLoader(b.Config.Template, esClient, b.Info, b.Fields) | ||
loader, err := template.NewESLoader(b.Config.Template, esClient, b.Info) | ||
if err != nil { | ||
return fmt.Errorf("Error creating Elasticsearch template loader: %v", err) | ||
} | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,21 +17,61 @@ | |
|
||
package template | ||
|
||
import "github.com/elastic/beats/libbeat/common" | ||
import ( | ||
"github.com/elastic/beats/libbeat/common" | ||
) | ||
|
||
func Unpack(c *common.Config) (*TemplatesConfig, error) { | ||
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. exported function Unpack should have comment or be unexported 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. We need to export this? Why no 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. Basically because I didn't see a lot of value in manually creating an empty |
||
var templatesRaw = struct { | ||
Templates []*common.Config `config:"templates"` | ||
}{} | ||
|
||
if err := c.Unpack(&templatesRaw); err != nil { | ||
return nil, err | ||
} | ||
|
||
var tc TemplatesConfig | ||
|
||
// use `settings.template.templates` if configured | ||
for _, t := range templatesRaw.Templates { | ||
var tmplCfg = DefaultTemplateCfg() | ||
t.Unpack(&tmplCfg) | ||
tc.Templates = append(tc.Templates, tmplCfg) | ||
} | ||
|
||
// fallback if no `settings.template.templates` was configured | ||
if len(tc.Templates) == 0 { | ||
var tmplCfg = DefaultTemplateCfg() | ||
c.Unpack(&tmplCfg) | ||
tc.Templates = append(tc.Templates, tmplCfg) | ||
} | ||
|
||
return &tc, nil | ||
} | ||
|
||
type TemplateConfig struct { | ||
Enabled bool `config:"enabled"` | ||
AppendFields common.Fields `config:"append_fields"` | ||
|
||
Name string `config:"name"` | ||
Pattern string `config:"pattern"` | ||
Fields string `config:"fields"` | ||
Modules string `config:"modules"` | ||
JSON struct { | ||
Enabled bool `config:"enabled"` | ||
Path string `config:"path"` | ||
Name string `config:"name"` | ||
} `config:"json"` | ||
AppendFields common.Fields `config:"append_fields"` | ||
Overwrite bool `config:"overwrite"` | ||
Settings TemplateSettings `config:"settings"` | ||
|
||
//TODO: check for overwrites | ||
Settings TemplateSettings `config:"settings"` | ||
Enabled bool `config:"enabled"` | ||
Overwrite bool `config:"overwrite"` | ||
} | ||
|
||
type TemplatesConfig struct { | ||
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. exported type TemplatesConfig should have comment or be unexported |
||
Templates []TemplateConfig `config:"-"` | ||
|
||
Settings TemplateSettings `config:"settings"` | ||
} | ||
|
||
type TemplateSettings struct { | ||
|
@@ -40,9 +80,16 @@ type TemplateSettings struct { | |
} | ||
|
||
var ( | ||
// DefaultConfig for index template | ||
DefaultConfig = TemplateConfig{ | ||
Enabled: true, | ||
Fields: "", | ||
} | ||
// Defaults used in the template | ||
defaultDateDetection = false | ||
defaultTotalFieldsLimit = 10000 | ||
defaultNumberOfRoutingShards = 30 | ||
) | ||
|
||
func DefaultTemplateCfg() TemplateConfig { | ||
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. exported function DefaultTemplateCfg should have comment or be unexported 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. We need to export this function? 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. no, will change. |
||
return TemplateConfig{ | ||
Enabled: true, | ||
Overwrite: false, | ||
Fields: "", | ||
} | ||
} |
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.
An idea I just had: What if we can allow to define dependencies when registering fields. For example the
system
fields depend on thecommon
fields. And common fields depend on theecs
fields. Like this when generating the fields we could loop through the dependencies and get always the full result.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.
I'll look into that when implementing it, but generally not planning on making any dependencies configurable.
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.
No need to look into it now. I think as you mentioned, outside of the scope of this PR.