feat(xo-server-perf-alert): ability to choose all hosts, VMs and SRs (#5692)

Fixes #2987
This commit is contained in:
Rajaa.BARHTAOUI 2021-03-30 17:26:48 +02:00 committed by GitHub
parent 9ef05b8afe
commit 7c9850ada8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 49 deletions

View File

@ -6,6 +6,7 @@
### Enhancements
- [Host/Load-balancer] Add a new anti-affinity mode (PR [#5652](https://github.com/vatesfr/xen-orchestra/pull/5652))
- [Plugins/perf-alert] Ability to choose all hosts, VMs and SRs [#2987](https://github.com/vatesfr/xen-orchestra/issues/2987) (PR [#5692](https://github.com/vatesfr/xen-orchestra/pull/5692))
### Bug fixes
@ -29,5 +30,6 @@
- @xen-orchestra/xapi minor
- @xen-orchestra/backups minor
- xo-server-load-balancer minor
- xo-server-perf-alert minor
- xo-server patch
- xo-web minor

View File

@ -157,6 +157,12 @@ export const configurationSchema = {
items: {
type: 'object',
properties: {
smartMode: {
title: 'All hosts',
type: 'boolean',
description: 'When enabled, all hosts will be considered for the alert.',
default: 'false',
},
uuids: {
title: 'Hosts',
type: 'array',
@ -190,6 +196,13 @@ export const configurationSchema = {
enum: [60, 600],
},
},
oneOf: [
{ required: ['uuids'] },
{
properties: { smartMode: { const: true } },
required: ['smartMode'],
},
],
},
},
vmMonitors: {
@ -201,6 +214,12 @@ export const configurationSchema = {
items: {
type: 'object',
properties: {
smartMode: {
title: 'All VMs',
type: 'boolean',
description: 'When enabled, all VMs will be considered for the alert.',
default: 'false',
},
uuids: {
title: 'Virtual Machines',
type: 'array',
@ -234,7 +253,13 @@ export const configurationSchema = {
enum: [60, 600],
},
},
required: ['uuids'],
oneOf: [
{ required: ['uuids'] },
{
properties: { smartMode: { const: true } },
required: ['smartMode'],
},
],
},
},
srMonitors: {
@ -246,6 +271,12 @@ export const configurationSchema = {
items: {
type: 'object',
properties: {
smartMode: {
title: 'All SRs',
type: 'boolean',
description: 'When enabled, all SRs will be considered for the alert.',
default: 'false',
},
uuids: {
title: 'SRs',
type: 'array',
@ -271,7 +302,13 @@ export const configurationSchema = {
default: 80,
},
},
required: ['uuids'],
oneOf: [
{ required: ['uuids'] },
{
properties: { smartMode: { const: true } },
required: ['smartMode'],
},
],
},
},
toEmails: {
@ -373,8 +410,9 @@ ${monitorBodies.join('\n')}`
}
_parseDefinition(definition) {
const alarmId = `${definition.objectType}|${definition.variableName}|${definition.alarmTriggerLevel}`
const typeFunction = TYPE_FUNCTION_MAP[definition.objectType][definition.variableName]
const lcObjectType = definition.objectType.toLowerCase()
const alarmId = `${lcObjectType}|${definition.variableName}|${definition.alarmTriggerLevel}`
const typeFunction = TYPE_FUNCTION_MAP[lcObjectType][definition.variableName]
const parseData = (result, uuid) => {
const parsedLegend = result.meta.legend.map((l, index) => {
const [operation, type, uuid, name] = l.split(':')
@ -421,63 +459,65 @@ ${monitorBodies.join('\n')}`
title: `${typeFunction.name} ${definition.comparator} ${definition.alarmTriggerLevel}${typeFunction.unit}`,
snapshot: async () => {
return Promise.all(
map(definition.uuids, async uuid => {
try {
const result = {
uuid,
object: this._xo.getXapi(uuid).getObject(uuid),
}
map(
definition.smartMode
? map(this._xo.getObjects({ filter: { type: definition.objectType } }), obj => obj.uuid)
: definition.uuids,
async uuid => {
try {
const result = {
uuid,
object: this._xo.getXapi(uuid).getObject(uuid),
}
if (result.object === undefined) {
throw new Error('object not found')
}
if (result.object === undefined) {
throw new Error('object not found')
}
result.objectLink = `[${result.object.name_label}](${this._generateUrl(
definition.objectType,
result.object
)})`
result.objectLink = `[${result.object.name_label}](${this._generateUrl(lcObjectType, result.object)})`
if (typeFunction.createGetter === undefined) {
// Stats via RRD
result.rrd = await this.getRrd(result.object, observationPeriod)
if (result.rrd !== null) {
const data = parseData(result.rrd, result.object.uuid)
if (typeFunction.createGetter === undefined) {
// Stats via RRD
result.rrd = await this.getRrd(result.object, observationPeriod)
if (result.rrd !== null) {
const data = parseData(result.rrd, result.object.uuid)
Object.assign(result, {
data,
value: data.getDisplayableValue(),
shouldAlarm: data.shouldAlarm(),
threshold: data.threshold,
observationPeriod,
})
}
} else {
// Stats via XAPI
const getter = typeFunction.createGetter(definition.comparator, definition.alarmTriggerLevel)
const data = getter(result.object)
Object.assign(result, {
data,
value: data.getDisplayableValue(),
shouldAlarm: data.shouldAlarm(),
threshold: data.threshold,
observationPeriod,
})
}
} else {
// Stats via XAPI
const getter = typeFunction.createGetter(definition.comparator, definition.alarmTriggerLevel)
const data = getter(result.object)
Object.assign(result, {
value: data.getDisplayableValue(),
shouldAlarm: data.shouldAlarm(),
threshold: data.threshold,
observationPeriod,
})
}
result.listItem = ` * ${result.objectLink}: ${
result.value === undefined
? "**Can't read performance counters**"
: result.value.toFixed(1) + typeFunction.unit
}\n`
result.listItem = ` * ${result.objectLink}: ${
result.value === undefined
? "**Can't read performance counters**"
: result.value.toFixed(1) + typeFunction.unit
}\n`
return result
} catch (_) {
return {
uuid,
object: null,
objectLink: `cannot find object ${uuid}`,
listItem: ` * ${uuid}: **Can't read performance counters**\n`,
return result
} catch (_) {
return {
uuid,
object: null,
objectLink: `cannot find object ${uuid}`,
listItem: ` * ${uuid}: **Can't read performance counters**\n`,
}
}
}
})
)
)
},
}
@ -485,8 +525,8 @@ ${monitorBodies.join('\n')}`
_getMonitors() {
return map(this._configuration.hostMonitors, def => this._parseDefinition({ ...def, objectType: 'host' }))
.concat(map(this._configuration.vmMonitors, def => this._parseDefinition({ ...def, objectType: 'vm' })))
.concat(map(this._configuration.srMonitors, def => this._parseDefinition({ ...def, objectType: 'sr' })))
.concat(map(this._configuration.vmMonitors, def => this._parseDefinition({ ...def, objectType: 'VM' })))
.concat(map(this._configuration.srMonitors, def => this._parseDefinition({ ...def, objectType: 'SR' })))
}
// Sample of a monitor