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

Move the compute_vm_scalset to a light metricset and map the cloud metadata #21038

Merged
merged 23 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
938e66c
mofidy doc
narph Jul 23, 2020
4daef08
Merge branch 'master' of github.com:elastic/beats
narph Aug 3, 2020
b613178
Merge branch 'master' of github.com:elastic/beats
narph Aug 4, 2020
05364cf
Merge branch 'master' of github.com:elastic/beats
narph Aug 4, 2020
f147c4d
Merge branch 'master' of github.com:elastic/beats
narph Aug 4, 2020
4574718
Merge branch 'master' of github.com:elastic/beats
narph Aug 17, 2020
1e43077
Merge branch 'master' of github.com:elastic/beats
narph Aug 19, 2020
807cf06
Merge branch 'master' of github.com:elastic/beats
narph Aug 24, 2020
2096668
Merge branch 'master' of github.com:elastic/beats
narph Aug 27, 2020
da8ac1f
Merge branch 'master' of github.com:elastic/beats
narph Aug 27, 2020
c2d8930
Merge branch 'master' of github.com:elastic/beats
narph Aug 27, 2020
7bd9e73
Merge branch 'master' of github.com:elastic/beats
narph Aug 31, 2020
6e89a84
Merge branch 'master' of github.com:elastic/beats
narph Aug 31, 2020
bdf21e9
Merge branch 'master' of github.com:elastic/beats
narph Sep 2, 2020
7833687
Merge branch 'master' of github.com:elastic/beats
narph Sep 3, 2020
bbf6178
Merge branch 'master' of github.com:elastic/beats
narph Sep 4, 2020
4ba8817
Merge branch 'master' of github.com:elastic/beats
narph Sep 7, 2020
0cba5dc
Merge branch 'master' of github.com:elastic/beats
narph Sep 8, 2020
b2625ca
Merge branch 'master' of github.com:elastic/beats
narph Sep 8, 2020
2b56914
vm_scaleset
narph Sep 9, 2020
151f872
changelog
narph Sep 9, 2020
5100e6a
Merge branch 'master' of github.com:elastic/beats
narph Sep 9, 2020
5732161
Merge branch 'master' into azure_vm_sc
narph Sep 9, 2020
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
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Request prometheus endpoints to be gzipped by default {pull}20766[20766]
- Release all kubernetes `state` metricsets as GA {pull}20901[20901]
- Add billing metricset into googlecloud module. {pull}20812[20812] {issue}20738[20738]
- Move `compute_vm_scaleset` to light metricset. {pull}21038[21038] {issue}20985[20985]
- Sanitize `event.host`. {pull}21022[21022]

*Packetbeat*
Expand Down
1 change: 0 additions & 1 deletion metricbeat/docs/modules/azure/compute_vm.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ This file is generated! See scripts/mage/docs_collector.go

include::../../../../x-pack/metricbeat/module/azure/compute_vm/_meta/docs.asciidoc[]

This is a default metricset. If the host module is unconfigured, this metricset is enabled by default.

==== Fields

Expand Down
1 change: 0 additions & 1 deletion x-pack/metricbeat/include/list.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions x-pack/metricbeat/module/azure/add_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ func addHostMetadata(event *mb.Event, metricList common.MapStr) {
}
}

func addCloudVMMetadata(event *mb.Event, resource Resource) {
event.RootFields.Put("cloud.instance.name", resource.Name)
event.RootFields.Put("host.name", resource.Name)
if resource.Vm != (VmResource{}) {
if resource.Vm.Id != "" {
event.RootFields.Put("cloud.instance.id", resource.Vm.Id)
event.RootFields.Put("host.id", resource.Vm.Id)
}
if resource.Vm.Size != "" {
event.RootFields.Put("cloud.machine.type", resource.Vm.Size)
}
func addCloudVMMetadata(event *mb.Event, vm VmResource) {
if vm.Name != "" {
event.RootFields.Put("cloud.instance.name", vm.Name)
event.RootFields.Put("host.name", vm.Name)
}
if vm.Id != "" {
event.RootFields.Put("cloud.instance.id", vm.Id)
event.RootFields.Put("host.id", vm.Id)
}
if vm.Size != "" {
event.RootFields.Put("cloud.machine.type", vm.Size)
}
}
81 changes: 57 additions & 24 deletions x-pack/metricbeat/module/azure/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,39 +185,72 @@ func (client *Client) MapMetricByPrimaryAggregation(metrics []insights.MetricDef
return clientMetrics
}

// GetResourceForData will retrieve resource details for the selected metric configuration
func (client *Client) GetResourceForData(resourceId string) Resource {
for i, res := range client.Resources {
if res.Id == resourceId {
var vmSize string
var vmId string
if client.Config.AddCloudMetadata && res.Vm == (VmResource{}) {
expandedResource, err := client.AzureMonitorService.GetResourceDefinitionById(res.Id)
if err != nil {
client.Log.Error(err, "could not retrieve the resource details by resource ID %s", res.Id)
return Resource{}
// GetVMForMetaData func will retrieve the vm details in order to fill in the cloud metadata and also update the client resources
func (client *Client) GetVMForMetaData(resource *Resource, metricValues []MetricValue) VmResource {
var vm VmResource
resourceName := resource.Name
resourceId := resource.Id
// check first if this is a vm scaleset and the instance name is stored in the dimension value
if dimension, ok := getDimension("VMName", metricValues[0].dimensions); ok {
instanceId := getInstanceId(dimension.Value)
if instanceId != "" {
resourceId += fmt.Sprintf("/virtualMachines/%s", instanceId)
resourceName = dimension.Value
}
}
// if vm has been already added to the resource then it should be returned
if existingVM, ok := getVM(resourceName, resource.Vms); ok {
return existingVM
}
// an additional call is necessary in order to retrieve the vm specific details
expandedResource, err := client.AzureMonitorService.GetResourceDefinitionById(resourceId)
if err != nil {
client.Log.Error(err, "could not retrieve the resource details by resource ID %s", resourceId)
return VmResource{}
}
vm.Name = *expandedResource.Name
if expandedResource.Properties != nil {
if properties, ok := expandedResource.Properties.(map[string]interface{}); ok {
if hardware, ok := properties["hardwareProfile"]; ok {
if vmSz, ok := hardware.(map[string]interface{})["vmSize"]; ok {
vm.Size = vmSz.(string)
}
if expandedResource.Properties != nil {
if properties, ok := expandedResource.Properties.(map[string]interface{}); ok {
if hardware, ok := properties["hardwareProfile"]; ok {
if vmSz, ok := hardware.(map[string]interface{})["vmSize"]; ok {
vmSize = vmSz.(string)
}
if vmID, ok := properties["vmId"]; ok {
vmId = vmID.(string)
}
}
}
if vmID, ok := properties["vmId"]; ok {
vm.Id = vmID.(string)
}
client.Resources[i].Vm = VmResource{Size: vmSize, Id: vmId}
return client.Resources[i]
}
}
}
if len(vm.Size) == 0 && expandedResource.Sku != nil && expandedResource.Sku.Name != nil {
vm.Size = *expandedResource.Sku.Name
}
// the client resource and selected resources are being updated in order to avoid additional calls
client.AddVmToResource(resource.Id, vm)
resource.Vms = append(resource.Vms, vm)
return vm
}

// GetResourceForMetaData will retrieve resource details for the selected metric configuration
func (client *Client) GetResourceForMetaData(grouped Metric) Resource {
for _, res := range client.Resources {
if res.Id == grouped.ResourceId {
return res
}
}
return Resource{}
}

// AddVmToResource will add the vm details to the resource
func (client *Client) AddVmToResource(resourceId string, vm VmResource) {
if len(vm.Id) > 0 && len(vm.Name) > 0 {
for i, res := range client.Resources {
if res.Id == resourceId {
client.Resources[i].Vms = append(client.Resources[i].Vms, vm)
}
}
}
}

// NewMockClient instantiates a new client with the mock azure service
func NewMockClient() *Client {
azureMockService := new(MockService)
Expand Down
37 changes: 30 additions & 7 deletions x-pack/metricbeat/module/azure/client_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package azure

import (
"reflect"
"regexp"
"strings"
"time"

Expand All @@ -15,6 +16,8 @@ import (
// DefaultTimeGrain is set as default timegrain for the azure metrics
const DefaultTimeGrain = "PT5M"

var instanceIdRegex = regexp.MustCompile(`.*?(\d+)$`)

// mapMetricValues should map the metric values
func mapMetricValues(metrics []insights.Metric, previousMetrics []MetricValue, startTime time.Time, endTime time.Time) []MetricValue {
var currentMetrics []MetricValue
Expand Down Expand Up @@ -167,21 +170,41 @@ func groupMetricsByResource(metrics []Metric) map[string][]Metric {
return grouped
}

// ContainsDimension will check if the dimension value is found in the list
func ContainsDimension(dimension string, dimensions []insights.LocalizableString) bool {
// getDimension will check if the dimension value is found in the list
func getDimension(dimension string, dimensions []Dimension) (Dimension, bool) {
for _, dim := range dimensions {
if *dim.Value == dimension {
return true
if strings.ToLower(dim.Name) == strings.ToLower(dimension) {
return dim, true
}
}
return false
return Dimension{}, false
}

func containsResource(resId string, resources []Resource) bool {
func containsResource(resourceId string, resources []Resource) bool {
for _, res := range resources {
if res.Id == resId {
if res.Id == resourceId {
return true
}
}
return false
}

func getInstanceId(dimensionValue string) string {
matches := instanceIdRegex.FindStringSubmatch(dimensionValue)
if len(matches) == 2 {
return matches[1]
}
return ""
}

func getVM(vmName string, vms []VmResource) (VmResource, bool) {
if len(vms) == 0 {
return VmResource{}, false
}
for _, vm := range vms {
if vm.Name == vmName {
return vm, true
}
}
return VmResource{}, false
}
90 changes: 78 additions & 12 deletions x-pack/metricbeat/module/azure/client_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,28 +131,94 @@ func TestCompareMetricValues(t *testing.T) {
assert.True(t, result)
}

func TestContainsDimension(t *testing.T) {
func TestGetDimension(t *testing.T) {
dimension := "VMName"
dim1 := "SlotID"
dim2 := "VNU"
dim3 := "VMName"
dimensionList := []insights.LocalizableString{
dimensionList := []Dimension{
{
Value: &dim1,
LocalizedValue: &dim1,
Name: dim1,
Value: dim1,
},
{
Value: &dim2,
LocalizedValue: &dim2,
Name: dim2,
Value: dim2,
},
{
Value: &dim3,
LocalizedValue: &dim3,
Name: dim3,
Value: dim3,
},
}
result := ContainsDimension(dimension, dimensionList)
assert.True(t, result)
result, ok := getDimension(dimension, dimensionList)
assert.True(t, ok)
assert.Equal(t, result.Name, dim3)
assert.Equal(t, result.Value, dim3)
dimension = "VirtualMachine"
result = ContainsDimension(dimension, dimensionList)
assert.False(t, result)
result, ok = getDimension(dimension, dimensionList)
assert.False(t, ok)
assert.Equal(t, result.Name, "")
assert.Equal(t, result.Value, "")
}

func TestContainsResource(t *testing.T) {
resourceId := "resId"
resourceList := []Resource{
{
Name: "resource name",
Id: "resId",
},
{
Name: "resource name1",
Id: "resId1",
},
{
Name: "resource name2",
Id: "resId2",
},
}
ok := containsResource(resourceId, resourceList)
assert.True(t, ok)
resourceId = "ressId"
ok = containsResource(resourceId, resourceList)
assert.False(t, ok)
}

func TestGetVM(t *testing.T) {
vmName := "resource name1"
vmResourceList := []VmResource{
{
Name: "resource name",
Id: "resId",
},
{
Name: "resource name1",
Id: "resId1",
},
{
Name: "resource name2",
Id: "resId2",
},
}
vm, ok := getVM(vmName, vmResourceList)
assert.True(t, ok)
assert.Equal(t, vm.Name, vmName)
assert.Equal(t, vm.Id, "resId1")
vmName = "resource name3"
vm, ok = getVM(vmName, vmResourceList)
assert.False(t, ok)
assert.Equal(t, vm.Name, "")
assert.Equal(t, vm.Id, "")
}

func TestGetInstanceId(t *testing.T) {
dimensionValue := "sfjsfjghhbsjsjskjkf"
result := getInstanceId(dimensionValue)
assert.Empty(t, result)
dimensionValue = "fjsfhfhsjhjsfs_34"
result = getInstanceId(dimensionValue)
assert.Equal(t, result, "34")
dimensionValue = "fjsfhfhsjhjsfs_34sjsjfhsfsjjsjf_242"
result = getInstanceId(dimensionValue)
assert.Equal(t, result, "242")
}
2 changes: 1 addition & 1 deletion x-pack/metricbeat/module/azure/compute_vm/manifest.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
default: true
default: false
input:
module: azure
metricset: monitor
Expand Down
Loading