Skip to content

Commit

Permalink
Merge branch '8.x' into mergify/bp/8.x/pr-42402
Browse files Browse the repository at this point in the history
  • Loading branch information
michel-laterman authored Mar 6, 2025
2 parents f6e22dc + 54233a7 commit ba3b450
Show file tree
Hide file tree
Showing 15 changed files with 276 additions and 31 deletions.
22 changes: 22 additions & 0 deletions .buildkite/filebeat/filebeat-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ env:
IMAGE_WIN_2016: "family/platform-ingest-beats-windows-2016"
IMAGE_WIN_2019: "family/platform-ingest-beats-windows-2019"
IMAGE_WIN_2022: "family/platform-ingest-beats-windows-2022"
IMAGE_WIN_2025: "family/platform-ingest-beats-windows-2025"

IMAGE_BEATS_WITH_HOOKS_LATEST: "docker.elastic.co/ci-agent-images/platform-ingest/buildkite-agent-beats-ci-with-hooks:latest"

Expand Down Expand Up @@ -255,6 +256,27 @@ steps:
if: build.env("BUILDKITE_PULL_REQUEST") == "false" || build.env("GITHUB_PR_LABELS") =~ /.*[Ww]indows.*/

steps:
- label: ":windows: Filebeat: Win 2025 Unit Tests"
key: "windows-extended-2025"
command: |
Set-Location -Path filebeat
mage build unitTest
retry:
automatic:
- limit: 1
agents:
provider: "gcp"
image: "${IMAGE_WIN_2025}"
machine_type: "${GCP_WIN_MACHINE_TYPE}"
disk_size: 200
disk_type: "pd-ssd"
artifact_paths:
- "filebeat/build/*.xml"
- "filebeat/build/*.json"
notify:
- github_commit_status:
context: "filebeat: Win 2025 Unit Tests"

- label: ":windows: Filebeat: Win 2019 Unit Tests"
key: "windows-extended-2019"
command: |
Expand Down
22 changes: 22 additions & 0 deletions .buildkite/metricbeat/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ env:
IMAGE_WIN_2016: "family/platform-ingest-beats-windows-2016"
IMAGE_WIN_2019: "family/platform-ingest-beats-windows-2019"
IMAGE_WIN_2022: "family/platform-ingest-beats-windows-2022"
IMAGE_WIN_2025: "family/platform-ingest-beats-windows-2025"

IMAGE_BEATS_WITH_HOOKS_LATEST: "docker.elastic.co/ci-agent-images/platform-ingest/buildkite-agent-beats-ci-with-hooks:latest"

Expand Down Expand Up @@ -271,6 +272,27 @@ steps:
- github_commit_status:
context: "metricbeat: Win 2019 Unit Tests"

- label: ":windows: Metricbeat: Win 2025 Unit Tests"
command: |
Set-Location -Path metricbeat
mage build unitTest
key: "extended-win-2025-unit-tests"
retry:
automatic:
- limit: 1
agents:
provider: "gcp"
image: "${IMAGE_WIN_2025}"
machineType: "${GCP_WIN_MACHINE_TYPE}"
disk_size: 100
disk_type: "pd-ssd"
artifact_paths:
- "metricbeat/build/*.xml"
- "metricbeat/build/*.json"
notify:
- github_commit_status:
context: "metricbeat: Win 2025 Unit Tests"

- group: "Extended Tests"
key: "metricbeat-extended-tests"
if: build.env("BUILDKITE_PULL_REQUEST") == "false" || build.env("GITHUB_PR_LABELS") =~ /.*macOS.*/
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ otherwise no tag is added. {issue}42208[42208] {pull}42403[42403]
- Add new metricset wmi for the windows module. {pull}42017[42017]
- Update beat module with apm-server tail sampling monitoring metrics fields {pull}42569[42569]
- Log every 401 response from Kubernetes API Server {pull}42714[42714]
- Add a new `match_by_parent_instance` option to `perfmon` module. {pull}43002[43002]

*Metricbeat*
- Add benchmark module {pull}41801[41801]
Expand Down
10 changes: 9 additions & 1 deletion filebeat/beater/filebeat.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,15 @@ func (fb *Filebeat) Run(b *beat.Beat) error {
return nil
}

stateStore.notifier.Notify(outCfg.Config())
// Create a new config with the output configuration. Since r.Config is a pointer, a copy is required to
// avoid concurrent map read and write.
// See https://github.com/elastic/beats/issues/42815
configCopy, err := conf.NewConfigFrom(outCfg.Config())
if err != nil {
logp.Err("Failed to create a new config from the output config: %v", err)
return nil
}
stateStore.notifier.Notify(configCopy)
return nil
})
}
Expand Down
26 changes: 13 additions & 13 deletions libbeat/processors/fingerprint/fingerprint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package fingerprint

import (
"fmt"
"math/rand"
"math/rand/v2"
"strconv"
"testing"
"time"
Expand Down Expand Up @@ -129,11 +129,11 @@ func TestHashMethods(t *testing.T) {
"xxhash": {"37bc50682fba6686"},
}

for method, test := range tests {
t.Run(method, func(t *testing.T) {
for _, method := range hashes {
t.Run(method.Name, func(t *testing.T) {
testConfig, err := config.NewConfigFrom(mapstr.M{
"fields": []string{"field1", "field2"},
"method": method,
"method": method.Name,
})
assert.NoError(t, err)

Expand All @@ -150,7 +150,7 @@ func TestHashMethods(t *testing.T) {

v, err := newEvent.GetValue("fingerprint")
assert.NoError(t, err)
assert.Equal(t, test.expected, v)
assert.Equal(t, tests[method.Name].expected, v)
})
}
}
Expand Down Expand Up @@ -212,16 +212,16 @@ func TestEncoding(t *testing.T) {
tests := map[string]struct {
expectedFingerprint string
}{
"hex": {"8934ca639027aab1ee9f3944d4d6bd1e"},
"base32": {"RE2MUY4QE6VLD3U7HFCNJVV5DY======"},
"base64": {"iTTKY5AnqrHunzlE1Na9Hg=="},
"hex": {"49f15f7c03c606b4bdf43f60481842954ff7b45a020a22a1d0911d76f170c798"},
"base32": {"JHYV67ADYYDLJPPUH5QEQGCCSVH7PNC2AIFCFIOQSEOXN4LQY6MA===="},
"base64": {"SfFffAPGBrS99D9gSBhClU/3tFoCCiKh0JEddvFwx5g="},
}

for encoding, test := range tests {
t.Run(encoding, func(t *testing.T) {
testConfig, err := config.NewConfigFrom(mapstr.M{
"fields": []string{"field2", "nested.field"},
"method": "md5",
"method": "sha256",
"encoding": encoding,
})
assert.NoError(t, err)
Expand Down Expand Up @@ -465,12 +465,12 @@ func TestProcessorStringer(t *testing.T) {
testConfig, err := config.NewConfigFrom(mapstr.M{
"fields": []string{"field1"},
"encoding": "hex",
"method": "md5",
"method": "sha256",
})
require.NoError(t, err)
p, err := New(testConfig)
require.NoError(t, err)
require.Equal(t, `fingerprint={"Method":"md5","Encoding":"hex","Fields":["field1"],"TargetField":"fingerprint","IgnoreMissing":false}`, fmt.Sprint(p))
require.Equal(t, `fingerprint={"Method":"sha256","Encoding":"hex","Fields":["field1"],"TargetField":"fingerprint","IgnoreMissing":false}`, fmt.Sprint(p))
}

func BenchmarkHashMethods(b *testing.B) {
Expand All @@ -497,7 +497,7 @@ func BenchmarkHashMethods(b *testing.B) {
}

func nRandomEvents(num int) []beat.Event {
prng := rand.New(rand.NewSource(12345))
prng := rand.New(rand.NewPCG(0, 12345))

const charset = "abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
Expand All @@ -508,7 +508,7 @@ func nRandomEvents(num int) []beat.Event {
events := make([]beat.Event, 0, num)
for i := 0; i < num; i++ {
for j := range b {
b[j] = charset[prng.Intn(charsetLen)]
b[j] = charset[prng.IntN(charsetLen)]
}
events = append(events, beat.Event{
Fields: mapstr.M{
Expand Down
9 changes: 3 additions & 6 deletions libbeat/processors/fingerprint/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
package fingerprint

import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"hash"
Expand All @@ -37,14 +35,13 @@ type hashMethod func() hash.Hash
var hashes = map[string]namedHashMethod{}

func init() {
for _, h := range []namedHashMethod{
{Name: "md5", Hash: md5.New},
{Name: "sha1", Hash: sha1.New},
fipsApprovedHashes := []namedHashMethod{
{Name: "sha256", Hash: sha256.New},
{Name: "sha384", Hash: sha512.New384},
{Name: "sha512", Hash: sha512.New},
{Name: "xxhash", Hash: newXxHash},
} {
}
for _, h := range fipsApprovedHashes {
hashes[h.Name] = h
}
}
Expand Down
34 changes: 34 additions & 0 deletions libbeat/processors/fingerprint/hash_fips_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build requirefips

package fingerprint

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestHashMethod(t *testing.T) {
require.Len(t, hashes, 4)
require.Contains(t, hashes, "sha256")
require.Contains(t, hashes, "sha384")
require.Contains(t, hashes, "sha512")
require.Contains(t, hashes, "xxhash")
}
35 changes: 35 additions & 0 deletions libbeat/processors/fingerprint/hash_nofips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build !requirefips

package fingerprint

import (
"crypto/md5"
"crypto/sha1"
)

func init() {
nonFipsApprovedHashes := []namedHashMethod{
{Name: "md5", Hash: md5.New},
{Name: "sha1", Hash: sha1.New},
}
for _, h := range nonFipsApprovedHashes {
hashes[h.Name] = h
}
}
36 changes: 36 additions & 0 deletions libbeat/processors/fingerprint/hash_nofips_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build !requirefips

package fingerprint

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestHashMethod(t *testing.T) {
require.Len(t, hashes, 6)
require.Contains(t, hashes, "md5")
require.Contains(t, hashes, "sha1")
require.Contains(t, hashes, "sha256")
require.Contains(t, hashes, "sha384")
require.Contains(t, hashes, "sha512")
require.Contains(t, hashes, "xxhash")
}
2 changes: 1 addition & 1 deletion libbeat/statestore/backend/es/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ func (s *store) Each(fn func(string, backend.ValueDecoder) (bool, error)) error
}

func (s *store) configure(ctx context.Context, c *conf.C) {
s.log.Debugf("Configure ES store")
s.log.Info("Configuring ES store")
s.mx.Lock()
defer s.mx.Unlock()

Expand Down
7 changes: 7 additions & 0 deletions metricbeat/module/windows/perfmon/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ The default behaviour is for all measurements to be sent as separate events.

*`refresh_wildcard_counters`*:: A boolean option to refresh the counter list at each fetch. By default, the counter list will be retrieved at the starting time, to refresh the list at each fetch, users will have to enable this setting.

*`match_by_parent_instance`*:: A boolean option that causes all instances
of the same parent to have the same instance value. In the above example,
this will cause metrics for `svchost`, `svchost#1`, etc. to have an `instance`
value of `svchost`. If set to `false` they will keep the original values
(`svchost`, `svchost#1`, etc.).
It defaults to `true`.


[float]
==== Query Configuration
Expand Down
5 changes: 5 additions & 0 deletions metricbeat/module/windows/perfmon/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type Config struct {
RefreshWildcardCounters bool `config:"perfmon.refresh_wildcard_counters"`
Queries []Query `config:"perfmon.queries"`
GroupAllCountersTo string `config:"perfmon.group_all_counter"`
MatchByParentInstance *bool `config:"perfmon.match_by_parent_instance"`
}

// QueryConfig for perfmon queries. This will be used as the new configuration format
Expand Down Expand Up @@ -77,6 +78,10 @@ func (conf *Config) Validate() error {
return nil
}

func (conf *Config) ShouldMatchByParentInstance() bool {
return conf.MatchByParentInstance == nil || *conf.MatchByParentInstance
}

func isValidFormat(format string) bool {
for _, form := range allowedFormats {
if form == format {
Expand Down
20 changes: 11 additions & 9 deletions metricbeat/module/windows/perfmon/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,14 @@ func (re *Reader) groupToEvents(counters map[string][]pdh.CounterValue) []mb.Eve
eventMap[eventKey].Error = fmt.Errorf("failed on query=%v: %w", counterPath, val.Err.Error)
}
if val.Instance != "" {
// will ignore instance index
if ok, match := matchesParentProcess(val.Instance); ok {
eventMap[eventKey].MetricSetFields.Put(counter.InstanceField, match)
} else {
eventMap[eventKey].MetricSetFields.Put(counter.InstanceField, val.Instance)
instanceName := val.Instance
if re.config.ShouldMatchByParentInstance() {
if ok, match := matchesParentProcess(val.Instance); ok {
// will ignore instance index
instanceName = match
}
}
eventMap[eventKey].MetricSetFields.Put(counter.InstanceField, instanceName)
}
}

Expand Down Expand Up @@ -126,13 +128,13 @@ func (re *Reader) groupToSingleEvent(counters map[string][]pdh.CounterValue) mb.
continue
}
var counterVal float64
switch val.Measurement.(type) {
switch m := val.Measurement.(type) {
case int64:
counterVal = float64(val.Measurement.(int64))
counterVal = float64(m)
case int:
counterVal = float64(val.Measurement.(int))
counterVal = float64(m)
default:
counterVal = val.Measurement.(float64)
counterVal, _ = val.Measurement.(float64)
}
if _, ok := measurements[readerCounter.QueryField]; !ok {
measurements[readerCounter.QueryField] = counterVal
Expand Down
Loading

0 comments on commit ba3b450

Please sign in to comment.