Skip to content

Commit 644cbe7

Browse files
committed
Merge remote-tracking branch 'upstream/master' into feature/macosx-pipeline-2.0
* upstream/master: libbeat/cmd/instance: report cgroup stats (elastic#21113) Configurable index template loading (elastic#21212) [Ingest Manager] Thread safe sorted set (elastic#21290)
2 parents af59638 + b4c7a93 commit 644cbe7

23 files changed

+381
-55
lines changed

CHANGELOG.next.asciidoc

+1
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
437437
- Added experimental dataset `juniper/netscreen`. {pull}20820[20820]
438438
- Added experimental dataset `sophos/utm`. {pull}20820[20820]
439439
- Add Cloud Foundry tags in related events. {pull}21177[21177]
440+
- Add option to select the type of index template to load: legacy, component, index. {pull}21212[21212]
440441

441442
*Auditbeat*
442443

auditbeat/auditbeat.reference.yml

+5
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,11 @@ output.elasticsearch:
11441144
# Set to false to disable template loading.
11451145
#setup.template.enabled: true
11461146

1147+
# Select the kind of index template. From Elasticsearch 7.8, it is possible to
1148+
# use component templates. Available options: legacy, component, index.
1149+
# By default auditbeat uses the legacy index templates.
1150+
#setup.template.type: legacy
1151+
11471152
# Template name. By default the template name is "auditbeat-%{[agent.version]}"
11481153
# The template name and pattern has to be set in case the Elasticsearch index pattern is modified.
11491154
#setup.template.name: "auditbeat-%{[agent.version]}"

filebeat/filebeat.reference.yml

+5
Original file line numberDiff line numberDiff line change
@@ -1870,6 +1870,11 @@ output.elasticsearch:
18701870
# Set to false to disable template loading.
18711871
#setup.template.enabled: true
18721872

1873+
# Select the kind of index template. From Elasticsearch 7.8, it is possible to
1874+
# use component templates. Available options: legacy, component, index.
1875+
# By default filebeat uses the legacy index templates.
1876+
#setup.template.type: legacy
1877+
18731878
# Template name. By default the template name is "filebeat-%{[agent.version]}"
18741879
# The template name and pattern has to be set in case the Elasticsearch index pattern is modified.
18751880
#setup.template.name: "filebeat-%{[agent.version]}"

heartbeat/heartbeat.reference.yml

+5
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,11 @@ output.elasticsearch:
13211321
# Set to false to disable template loading.
13221322
#setup.template.enabled: true
13231323

1324+
# Select the kind of index template. From Elasticsearch 7.8, it is possible to
1325+
# use component templates. Available options: legacy, component, index.
1326+
# By default heartbeat uses the legacy index templates.
1327+
#setup.template.type: legacy
1328+
13241329
# Template name. By default the template name is "heartbeat-%{[agent.version]}"
13251330
# The template name and pattern has to be set in case the Elasticsearch index pattern is modified.
13261331
#setup.template.name: "heartbeat-%{[agent.version]}"

journalbeat/journalbeat.reference.yml

+5
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,11 @@ output.elasticsearch:
10861086
# Set to false to disable template loading.
10871087
#setup.template.enabled: true
10881088

1089+
# Select the kind of index template. From Elasticsearch 7.8, it is possible to
1090+
# use component templates. Available options: legacy, component, index.
1091+
# By default journalbeat uses the legacy index templates.
1092+
#setup.template.type: legacy
1093+
10891094
# Template name. By default the template name is "journalbeat-%{[agent.version]}"
10901095
# The template name and pattern has to be set in case the Elasticsearch index pattern is modified.
10911096
#setup.template.name: "journalbeat-%{[agent.version]}"

libbeat/_meta/config/setup.template.reference.yml.tmpl

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
# Set to false to disable template loading.
88
#setup.template.enabled: true
99

10+
# Select the kind of index template. From Elasticsearch 7.8, it is possible to
11+
# use component templates. Available options: legacy, component, index.
12+
# By default {{.BeatName}} uses the legacy index templates.
13+
#setup.template.type: legacy
14+
1015
# Template name. By default the template name is "{{.BeatIndexPrefix}}-%{[agent.version]}"
1116
# The template name and pattern has to be set in case the Elasticsearch index pattern is modified.
1217
#setup.template.name: "{{.BeatIndexPrefix}}-%{[agent.version]}"

libbeat/cmd/instance/metrics.go

+84-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/elastic/beats/v7/libbeat/metric/system/cpu"
2929
"github.com/elastic/beats/v7/libbeat/metric/system/process"
3030
"github.com/elastic/beats/v7/libbeat/monitoring"
31+
"github.com/elastic/gosigar/cgroup"
3132
)
3233

3334
var (
@@ -65,10 +66,15 @@ func setupMetrics(name string) error {
6566
}
6667

6768
func setupPlatformSpecificMetrics() {
69+
switch runtime.GOOS {
70+
case "linux":
71+
monitoring.NewFunc(beatMetrics, "cgroup", reportBeatCgroups, monitoring.Report)
72+
case "windows":
73+
setupWindowsHandlesMetrics()
74+
}
75+
6876
if runtime.GOOS != "windows" {
6977
monitoring.NewFunc(systemMetrics, "load", reportSystemLoadAverage, monitoring.Report)
70-
} else {
71-
setupWindowsHandlesMetrics()
7278
}
7379

7480
setupLinuxBSDFDMetrics()
@@ -254,3 +260,79 @@ func reportRuntime(_ monitoring.Mode, V monitoring.Visitor) {
254260

255261
monitoring.ReportInt(V, "goroutines", int64(runtime.NumGoroutine()))
256262
}
263+
264+
func reportBeatCgroups(_ monitoring.Mode, V monitoring.Visitor) {
265+
V.OnRegistryStart()
266+
defer V.OnRegistryFinished()
267+
268+
pid, err := process.GetSelfPid()
269+
if err != nil {
270+
logp.Err("error getting PID for self process: %v", err)
271+
return
272+
}
273+
274+
cgroups, err := cgroup.NewReader("", true)
275+
if err != nil {
276+
if err == cgroup.ErrCgroupsMissing {
277+
logp.Warn("cgroup data collection disabled: %v", err)
278+
} else {
279+
logp.Err("cgroup data collection disabled: %v", err)
280+
}
281+
return
282+
}
283+
selfStats, err := cgroups.GetStatsForProcess(pid)
284+
if err != nil {
285+
logp.Err("error getting group status: %v", err)
286+
return
287+
}
288+
289+
if cpu := selfStats.CPU; cpu != nil {
290+
monitoring.ReportNamespace(V, "cpu", func() {
291+
if cpu.ID != "" {
292+
monitoring.ReportString(V, "id", cpu.ID)
293+
}
294+
monitoring.ReportNamespace(V, "cfs", func() {
295+
monitoring.ReportNamespace(V, "period", func() {
296+
monitoring.ReportInt(V, "us", int64(cpu.CFS.PeriodMicros))
297+
})
298+
monitoring.ReportNamespace(V, "quota", func() {
299+
monitoring.ReportInt(V, "us", int64(cpu.CFS.QuotaMicros))
300+
})
301+
})
302+
monitoring.ReportNamespace(V, "stats", func() {
303+
monitoring.ReportInt(V, "periods", int64(cpu.Stats.Periods))
304+
monitoring.ReportNamespace(V, "throttled", func() {
305+
monitoring.ReportInt(V, "periods", int64(cpu.Stats.ThrottledPeriods))
306+
monitoring.ReportInt(V, "ns", int64(cpu.Stats.ThrottledTimeNanos))
307+
})
308+
})
309+
})
310+
}
311+
312+
if cpuacct := selfStats.CPUAccounting; cpuacct != nil {
313+
monitoring.ReportNamespace(V, "cpuacct", func() {
314+
if cpuacct.ID != "" {
315+
monitoring.ReportString(V, "id", cpuacct.ID)
316+
}
317+
monitoring.ReportNamespace(V, "total", func() {
318+
monitoring.ReportInt(V, "ns", int64(cpuacct.TotalNanos))
319+
})
320+
})
321+
}
322+
323+
if memory := selfStats.Memory; memory != nil {
324+
monitoring.ReportNamespace(V, "memory", func() {
325+
if memory.ID != "" {
326+
monitoring.ReportString(V, "id", memory.ID)
327+
}
328+
monitoring.ReportNamespace(V, "mem", func() {
329+
monitoring.ReportNamespace(V, "limit", func() {
330+
monitoring.ReportInt(V, "bytes", int64(memory.Mem.Limit))
331+
})
332+
monitoring.ReportNamespace(V, "usage", func() {
333+
monitoring.ReportInt(V, "bytes", int64(memory.Mem.Usage))
334+
})
335+
})
336+
})
337+
}
338+
}

libbeat/docs/template-config.asciidoc

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ existing one.
2626
*`setup.template.enabled`*:: Set to false to disable template loading. If set this to false,
2727
you must <<load-template-manually,load the template manually>>.
2828

29+
*`setup.template.type`*:: The type of template to use. Available options: `legacy` (default), index templates
30+
before Elasticsearch v7.8. Use this to avoid breaking existing deployments. New options are `composite`
31+
and `index`. Selecting `component` loads a component template which can be included in new index templates.
32+
The option `index` loads the new index template.
33+
2934
*`setup.template.name`*:: The name of the template. The default is
3035
+{beatname_lc}+. The {beatname_uc} version is always appended to the given
3136
name, so the final name is +{beatname_lc}-%{[{beat_version_key}]}+.

libbeat/template/config.go

+48-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,27 @@
1717

1818
package template
1919

20-
import "github.com/elastic/beats/v7/libbeat/mapping"
20+
import (
21+
"fmt"
22+
23+
"github.com/elastic/beats/v7/libbeat/mapping"
24+
)
25+
26+
const (
27+
IndexTemplateLegacy IndexTemplateType = iota
28+
IndexTemplateComponent
29+
IndexTemplateIndex
30+
)
31+
32+
var (
33+
templateTypes = map[string]IndexTemplateType{
34+
"legacy": IndexTemplateLegacy,
35+
"component": IndexTemplateComponent,
36+
"index": IndexTemplateIndex,
37+
}
38+
)
39+
40+
type IndexTemplateType uint8
2141

2242
// TemplateConfig holds config information about the Elasticsearch template
2343
type TemplateConfig struct {
@@ -30,10 +50,12 @@ type TemplateConfig struct {
3050
Path string `config:"path"`
3151
Name string `config:"name"`
3252
} `config:"json"`
33-
AppendFields mapping.Fields `config:"append_fields"`
34-
Overwrite bool `config:"overwrite"`
35-
Settings TemplateSettings `config:"settings"`
36-
Order int `config:"order"`
53+
AppendFields mapping.Fields `config:"append_fields"`
54+
Overwrite bool `config:"overwrite"`
55+
Settings TemplateSettings `config:"settings"`
56+
Order int `config:"order"`
57+
Priority int `config:"priority"`
58+
Type IndexTemplateType `config:"type"`
3759
}
3860

3961
// TemplateSettings are part of the Elasticsearch template and hold index and source specific information.
@@ -45,8 +67,26 @@ type TemplateSettings struct {
4567
// DefaultConfig for index template
4668
func DefaultConfig() TemplateConfig {
4769
return TemplateConfig{
48-
Enabled: true,
49-
Fields: "",
50-
Order: 1,
70+
Enabled: true,
71+
Fields: "",
72+
Type: IndexTemplateLegacy,
73+
Order: 1,
74+
Priority: 150,
5175
}
5276
}
77+
78+
func (t *IndexTemplateType) Unpack(v string) error {
79+
if v == "" {
80+
*t = IndexTemplateLegacy
81+
return nil
82+
}
83+
84+
var tt IndexTemplateType
85+
var ok bool
86+
if tt, ok = templateTypes[v]; !ok {
87+
return fmt.Errorf("unknown index template type: %s", v)
88+
}
89+
*t = tt
90+
91+
return nil
92+
}

libbeat/template/load.go

+20-6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ import (
3131
"github.com/elastic/beats/v7/libbeat/paths"
3232
)
3333

34+
var (
35+
templateLoaderPath = map[IndexTemplateType]string{
36+
IndexTemplateLegacy: "/_template/",
37+
IndexTemplateComponent: "/_component_template/",
38+
IndexTemplateIndex: "/_index_template/",
39+
}
40+
)
41+
3442
//Loader interface for loading templates
3543
type Loader interface {
3644
Load(config TemplateConfig, info beat.Info, fields []byte, migration bool) error
@@ -97,7 +105,7 @@ func (l *ESLoader) Load(config TemplateConfig, info beat.Info, fields []byte, mi
97105
templateName = config.JSON.Name
98106
}
99107

100-
if l.templateExists(templateName) && !config.Overwrite {
108+
if l.templateExists(templateName, config.Type) && !config.Overwrite {
101109
l.log.Infof("Template %s already exists and will not be overwritten.", templateName)
102110
return nil
103111
}
@@ -107,7 +115,7 @@ func (l *ESLoader) Load(config TemplateConfig, info beat.Info, fields []byte, mi
107115
if err != nil {
108116
return err
109117
}
110-
if err := l.loadTemplate(templateName, body); err != nil {
118+
if err := l.loadTemplate(templateName, config.Type, body); err != nil {
111119
return fmt.Errorf("could not load template. Elasticsearch returned: %v. Template is: %s", err, body.StringToPrint())
112120
}
113121
l.log.Infof("template with name '%s' loaded.", templateName)
@@ -117,10 +125,11 @@ func (l *ESLoader) Load(config TemplateConfig, info beat.Info, fields []byte, mi
117125
// loadTemplate loads a template into Elasticsearch overwriting the existing
118126
// template if it exists. If you wish to not overwrite an existing template
119127
// then use CheckTemplate prior to calling this method.
120-
func (l *ESLoader) loadTemplate(templateName string, template map[string]interface{}) error {
128+
func (l *ESLoader) loadTemplate(templateName string, templateType IndexTemplateType, template map[string]interface{}) error {
121129
l.log.Infof("Try loading template %s to Elasticsearch", templateName)
122-
path := "/_template/" + templateName
123-
params := esVersionParams(l.client.GetVersion())
130+
clientVersion := l.client.GetVersion()
131+
path := templateLoaderPath[templateType] + templateName
132+
params := esVersionParams(clientVersion)
124133
status, body, err := l.client.Request("PUT", path, "", params, template)
125134
if err != nil {
126135
return fmt.Errorf("couldn't load template: %v. Response body: %s", err, body)
@@ -133,11 +142,16 @@ func (l *ESLoader) loadTemplate(templateName string, template map[string]interfa
133142

134143
// templateExists checks if a given template already exist. It returns true if
135144
// and only if Elasticsearch returns with HTTP status code 200.
136-
func (l *ESLoader) templateExists(templateName string) bool {
145+
func (l *ESLoader) templateExists(templateName string, templateType IndexTemplateType) bool {
137146
if l.client == nil {
138147
return false
139148
}
140149

150+
if templateType == IndexTemplateComponent {
151+
status, _, _ := l.client.Request("GET", "/_component_template/"+templateName, "", nil, nil)
152+
return status == http.StatusOK
153+
}
154+
141155
status, body, _ := l.client.Request("GET", "/_cat/templates/"+templateName, "", nil, nil)
142156

143157
return status == http.StatusOK && strings.Contains(string(body), templateName)

0 commit comments

Comments
 (0)