parent
d2c5b52bf1
commit
9fe1069df0
@ -19,6 +19,7 @@
|
||||
- [Jobs] Fix `job.runSequence` method (PR [#5944](https://github.com/vatesfr/xen-orchestra/pull/5944))
|
||||
- [Netbox] Fix error when testing plugin on versions older than 2.10 (PR [#5963](https://github.com/vatesfr/xen-orchestra/pull/5963))
|
||||
- [Snapshot] Fix "Create VM from snapshot" creating a template instead of a VM (PR [#5955](https://github.com/vatesfr/xen-orchestra/pull/5955))
|
||||
- [Host/Logs] Improve the display of log content (PR [#5943](https://github.com/vatesfr/xen-orchestra/pull/5943))
|
||||
|
||||
### Packages to release
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
import fromCallback from 'promise-toolbox/fromCallback'
|
||||
import getStream from 'get-stream'
|
||||
import humanFormat from 'human-format'
|
||||
import React from 'react'
|
||||
import ReadableStream from 'readable-stream'
|
||||
import xml2js from 'xml2js'
|
||||
import { connect } from 'react-redux'
|
||||
import { createPredicate } from 'value-matcher'
|
||||
import { FormattedDate } from 'react-intl'
|
||||
@ -9,6 +11,7 @@ import {
|
||||
clone,
|
||||
every,
|
||||
forEach,
|
||||
get,
|
||||
isEmpty,
|
||||
isFunction,
|
||||
isPlainObject,
|
||||
@ -215,6 +218,28 @@ function safeHumanFormat(value, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
export const formatLogs = logs =>
|
||||
Promise.all(
|
||||
map(logs, ({ body }, id) => {
|
||||
const matches = /^value:\s*([0-9.]+)\s+config:\s*([^]*)$/.exec(body)
|
||||
if (matches === null) {
|
||||
return
|
||||
}
|
||||
|
||||
const [, value, xml] = matches
|
||||
return fromCallback(xml2js.parseString, xml).then((result = {}) => {
|
||||
const object = mapValues(result.variable, value => get(value, '[0].$.value'))
|
||||
if (object.name === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const { name, ...alarmAttributes } = object
|
||||
|
||||
return { name, value, alarmAttributes, id }
|
||||
}, noop)
|
||||
})
|
||||
)
|
||||
|
||||
export const formatSize = bytes => (bytes != null ? safeHumanFormat(bytes, { scale: 'binary', unit: 'B' }) : 'N/D')
|
||||
|
||||
export const formatSizeShort = bytes => safeHumanFormat(bytes, { scale: 'binary', unit: 'B', decimals: 0 })
|
||||
|
@ -1,7 +1,6 @@
|
||||
import _ from 'intl'
|
||||
import Component from 'base-component'
|
||||
import decorate from 'apply-decorators'
|
||||
import fromCallback from 'promise-toolbox/fromCallback'
|
||||
import { get as getDefined } from '@xen-orchestra/defined'
|
||||
import Icon from 'icon'
|
||||
import Link from 'link'
|
||||
@ -9,14 +8,13 @@ import NoObjects from 'no-objects'
|
||||
import React from 'react'
|
||||
import SortedTable from 'sorted-table'
|
||||
import Tooltip from 'tooltip'
|
||||
import xml2js from 'xml2js'
|
||||
import { Network, Sr, Vm } from 'render-xo-item'
|
||||
import { SelectPool } from 'select-objects'
|
||||
import { Container, Row, Col } from 'grid'
|
||||
import { Card, CardHeader, CardBlock } from 'card'
|
||||
import { FormattedRelative, FormattedTime } from 'react-intl'
|
||||
import { flatten, forEach, get, includes, isEmpty, map, mapValues } from 'lodash'
|
||||
import { connectStore, formatSize, noop, resolveIds } from 'utils'
|
||||
import { flatten, forEach, includes, isEmpty, map } from 'lodash'
|
||||
import { connectStore, formatLogs, formatSize, noop, resolveIds } from 'utils'
|
||||
import {
|
||||
deleteMessage,
|
||||
deleteMessages,
|
||||
@ -555,26 +553,7 @@ export default class Health extends Component {
|
||||
}
|
||||
|
||||
_updateAlarms = props => {
|
||||
Promise.all(
|
||||
map(props.alertMessages, ({ body }, id) => {
|
||||
const matches = /^value:\s*([0-9.]+)\s+config:\s*([^]*)$/.exec(body)
|
||||
if (!matches) {
|
||||
return
|
||||
}
|
||||
|
||||
const [, value, xml] = matches
|
||||
return fromCallback(xml2js.parseString, xml).then(result => {
|
||||
const object = mapValues(result && result.variable, value => get(value, '[0].$.value'))
|
||||
if (!object || !object.name) {
|
||||
return
|
||||
}
|
||||
|
||||
const { name, ...alarmAttributes } = object
|
||||
|
||||
return { name, value, alarmAttributes, id }
|
||||
}, noop)
|
||||
})
|
||||
).then(formattedMessages => {
|
||||
formatLogs(props.alertMessages).then(formattedMessages => {
|
||||
this.setState({
|
||||
messages: map(formattedMessages, ({ id, ...formattedMessage }) => ({
|
||||
formatted: formattedMessage,
|
||||
|
@ -6,7 +6,13 @@ import SortedTable from 'sorted-table'
|
||||
import { createPager } from 'selectors'
|
||||
import { Row, Col } from 'grid'
|
||||
import { deleteMessage, deleteMessages } from 'xo'
|
||||
import { formatLogs } from 'utils'
|
||||
import { FormattedRelative, FormattedTime } from 'react-intl'
|
||||
import { map } from 'lodash'
|
||||
|
||||
const LOG_BODY_STYLE = {
|
||||
whiteSpace: 'pre-wrap',
|
||||
}
|
||||
|
||||
const LOG_COLUMNS = [
|
||||
{
|
||||
@ -34,7 +40,26 @@ const LOG_COLUMNS = [
|
||||
},
|
||||
{
|
||||
name: _('logContent'),
|
||||
itemRenderer: log => log.body,
|
||||
itemRenderer: ({ formatted, body }) =>
|
||||
formatted !== undefined ? (
|
||||
<div>
|
||||
<Row>
|
||||
<Col mediumSize={6}>
|
||||
<strong>{formatted.name}</strong>
|
||||
</Col>
|
||||
<Col mediumSize={6}>{formatted.value}</Col>
|
||||
</Row>
|
||||
<br />
|
||||
{map(formatted.alarmAttributes, (value, label) => (
|
||||
<Row key={label}>
|
||||
<Col mediumSize={6}>{label}</Col>
|
||||
<Col mediumSize={6}>{value}</Col>
|
||||
</Row>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<pre style={LOG_BODY_STYLE}>{body}</pre>
|
||||
),
|
||||
sortCriteria: log => log.body,
|
||||
},
|
||||
]
|
||||
@ -55,7 +80,7 @@ export default class TabLogs extends Component {
|
||||
super()
|
||||
|
||||
this.getLogs = createPager(
|
||||
() => this.props.logs,
|
||||
() => this.state.logs,
|
||||
() => this.state.page,
|
||||
10
|
||||
)
|
||||
@ -65,6 +90,26 @@ export default class TabLogs extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._formatLogs(this.props.logs)
|
||||
}
|
||||
|
||||
componentDidUpdate(props) {
|
||||
if (props.logs !== this.props.logs) {
|
||||
this._formatLogs(this.props.logs)
|
||||
}
|
||||
}
|
||||
|
||||
_formatLogs = logs =>
|
||||
formatLogs(logs).then(formattedLogs => {
|
||||
this.setState({
|
||||
logs: map(formattedLogs, ({ id, ...formattedLogs }) => ({
|
||||
formatted: formattedLogs,
|
||||
...logs[id],
|
||||
})),
|
||||
})
|
||||
})
|
||||
|
||||
_nextPage = () => this.setState({ page: this.state.page + 1 })
|
||||
_previousPage = () => this.setState({ page: this.state.page - 1 })
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user