Skip to content
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

Template setting in the configuration file #4284

Merged
merged 1 commit into from
May 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ https://github.com/elastic/beats/compare/v6.0.0-alpha1...master[Check the HEAD d

*Affecting all Beats*

- Added the possibility to set Elasticsearch mapping template settings from the Beat configuration file. {pull}4284[4284]

*Filebeat*

*Heartbeat*
Expand Down
1 change: 1 addition & 0 deletions libbeat/docs/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ include::./version.asciidoc[]
:beatsdevguide: http://www.elastic.co/guide/en/beats/devguide/{doc-branch}
:securitydoc: https://www.elastic.co/guide/en/x-pack/5.2
:logstashdoc: https://www.elastic.co/guide/en/logstash/{doc-branch}
:elasticsearch: https://www.elastic.co/guide/en/elasticsearch/reference/{doc-branch}
:beatname_lc: beatname
:beatname_uc: a Beat
:security: X-Pack Security
Expand Down
13 changes: 10 additions & 3 deletions libbeat/docs/template-config.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,25 @@ you must <<load-template-manually,load the template manually>>.

*`name`*:: The name of the template. The default is +{beatname_lc}+.

*`path`*:: The path to the template file. The default is +fields.yml+. If a relative
path is set, it is considered relative to the config path. See the <<directory-layout>> section for
details.
*`fields`*:: The path to the YAML file describing the fields. The default is +fields.yml+. If a
relative path is set, it is considered relative to the config path. See the <<directory-layout>>
section for details.

*`overwrite`*:: A boolean that specifies whether to overwrite the existing template. The default
is false.

*`settings`*:: A dictionary of settings to place into the `settings` dictionary of the Elasticsearch
template. For more details about the available Elasticsearch mapping options, please see the
Elasticsearch {elasticsearch}/mapping.html[mapping reference].

For example:

["source","yaml",subs="attributes,callouts"]
----------------------------------------------------------------------
setup.template.name: "{beatname_lc}"
setup.template.fields: "fields.yml"
setup.template.overwrite: false
setup.template.settings:
index.number_of_shards: 1
index.number_of_replicas: 1
----------------------------------------------------------------------
12 changes: 6 additions & 6 deletions libbeat/template/config.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package template

type TemplateConfig struct {
Enabled bool `config:"enabled"`
Name string `config:"name"`
Fields string `config:"fields"`
Overwrite bool `config:"overwrite"`
OutputToFile string `config:"output_to_file"`
Settings map[string]string `config:"settings"`
Enabled bool `config:"enabled"`
Name string `config:"name"`
Fields string `config:"fields"`
Overwrite bool `config:"overwrite"`
OutputToFile string `config:"output_to_file"`
Settings map[string]interface{} `config:"settings"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on using a "generic" approach

}

var (
Expand Down
2 changes: 1 addition & 1 deletion libbeat/template/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (l *Loader) Load() error {
l.config.Name = l.beatInfo.Beat
}

tmpl, err := New(l.beatInfo.Version, l.client.GetVersion(), l.config.Name)
tmpl, err := New(l.beatInfo.Version, l.client.GetVersion(), l.config.Name, l.config.Settings)
if err != nil {
return fmt.Errorf("error creating template instance: %v", err)
}
Expand Down
60 changes: 58 additions & 2 deletions libbeat/template/load_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
package template

import (
"encoding/json"
"fmt"
"path/filepath"
"testing"
"time"

"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/outputs/elasticsearch"
"github.com/elastic/beats/libbeat/version"

Expand Down Expand Up @@ -43,7 +46,7 @@ func TestLoadTemplate(t *testing.T) {
fieldsPath := absPath + "/fields.yml"
index := "testbeat"

tmpl, err := New(version.GetDefaultVersion(), client.GetVersion(), index)
tmpl, err := New(version.GetDefaultVersion(), client.GetVersion(), index, common.MapStr{})
assert.NoError(t, err)
content, err := tmpl.Load(fieldsPath)
assert.NoError(t, err)
Expand Down Expand Up @@ -114,7 +117,7 @@ func TestLoadBeatsTemplate(t *testing.T) {
fieldsPath := absPath + "/fields.yml"
index := beat

tmpl, err := New(version.GetDefaultVersion(), client.GetVersion(), index)
tmpl, err := New(version.GetDefaultVersion(), client.GetVersion(), index, common.MapStr{})
assert.NoError(t, err)
content, err := tmpl.Load(fieldsPath)
assert.NoError(t, err)
Expand All @@ -137,3 +140,56 @@ func TestLoadBeatsTemplate(t *testing.T) {
assert.False(t, loader.CheckTemplate(tmpl.GetName()))
}
}

func TestTemplateSettings(t *testing.T) {

// Setup ES
client := elasticsearch.GetTestingElasticsearch()
err := client.Connect(5 * time.Second)
assert.Nil(t, err)

// Load template
absPath, err := filepath.Abs("../")
assert.NotNil(t, absPath)
assert.Nil(t, err)

fieldsPath := absPath + "/fields.yml"

settings := common.MapStr{
"index": common.MapStr{
"number_of_shards": 1,
},
}
tmpl, err := New(version.GetDefaultVersion(), client.GetVersion(), "testbeat", settings)
assert.NoError(t, err)
content, err := tmpl.Load(fieldsPath)
assert.NoError(t, err)

loader := &Loader{
client: client,
}

// Load template
err = loader.LoadTemplate(tmpl.GetName(), content)
assert.Nil(t, err)

// Check that it contains the mapping
status, body, err := loader.client.Request("GET", "/_template/"+tmpl.GetName(), "", nil, nil)
assert.NoError(t, err)
assert.Equal(t, status, 200)

var response common.MapStr
err = json.Unmarshal(body, &response)
assert.NoError(t, err)

templateJSON := common.MapStr(response[tmpl.GetName()].(map[string]interface{}))
val, err := templateJSON.GetValue(fmt.Sprintf("settings.index.number_of_shards"))
assert.NoError(t, err)
assert.Equal(t, val.(string), "1")

// Delete template again to clean up
client.Request("DELETE", "/_template/"+tmpl.GetName(), "", nil, nil)

// Make sure it was removed
assert.False(t, loader.CheckTemplate(tmpl.GetName()))
}
27 changes: 17 additions & 10 deletions libbeat/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ type Template struct {
index string
beatVersion Version
esVersion Version
settings common.MapStr
}

// New creates a new template instance
func New(beatVersion string, esVersion string, index string) (*Template, error) {
func New(beatVersion string, esVersion string, index string, settings common.MapStr) (*Template, error) {

bV, err := NewVersion(beatVersion)
if err != nil {
Expand All @@ -44,6 +45,7 @@ func New(beatVersion string, esVersion string, index string) (*Template, error)
index: index,
beatVersion: *bV,
esVersion: *esV,
settings: settings,
}, nil

}
Expand Down Expand Up @@ -90,6 +92,18 @@ func (t *Template) generate(properties common.MapStr, dynamicTemplates []common.

dynamicTemplates = append(dynamicTemplates, dynamicTemplateBase)

settings := common.MapStr{
"index": common.MapStr{
"refresh_interval": "5s",
"mapping": common.MapStr{
"total_fields": common.MapStr{
"limit": defaultTotalFieldsLimit,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work on all ES versions down to 2.x?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ES 2.x will just ignore the setting, but I'm going to test it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tested, seems to work well.

},
},
},
}
settings.DeepUpdate(t.settings)

// Load basic structure
basicStructure := common.MapStr{
"mappings": common.MapStr{
Expand All @@ -102,10 +116,8 @@ func (t *Template) generate(properties common.MapStr, dynamicTemplates []common.
"properties": properties,
},
},
"order": 1,
"settings": common.MapStr{
"index.refresh_interval": "5s",
},
"order": 1,
"settings": settings,
}

// ES 6 moved from template to index_patterns: https://github.com/elastic/elasticsearch/pull/21009
Expand All @@ -119,11 +131,6 @@ func (t *Template) generate(properties common.MapStr, dynamicTemplates []common.
basicStructure.Put("mappings._default_._all.norms.enabled", false)
}

if t.esVersion.major >= 5 {
// Metricbeat exceeds the default of 1000 fields
basicStructure.Put("settings.index.mapping.total_fields.limit", defaultTotalFieldsLimit)
}

return basicStructure
}

Expand Down