diff options
-rw-r--r-- | src/components/AppHeader/AppHeader.vue | 6 | ||||
-rw-r--r-- | src/locales/en-US.json | 3 | ||||
-rw-r--r-- | src/store/modules/Health/EventLogStore.js | 113 | ||||
-rw-r--r-- | src/store/plugins/WebSocketPlugin.js | 20 | ||||
-rw-r--r-- | src/views/Overview/OverviewEvents.vue | 35 |
5 files changed, 60 insertions, 117 deletions
diff --git a/src/components/AppHeader/AppHeader.vue b/src/components/AppHeader/AppHeader.vue index 48a68fc3..c7b368bd 100644 --- a/src/components/AppHeader/AppHeader.vue +++ b/src/components/AppHeader/AppHeader.vue @@ -101,11 +101,11 @@ export default { }, healthStatusIcon() { switch (this.healthStatus) { - case 'good': + case 'OK': return 'success'; - case 'warning': + case 'Warning': return 'warning'; - case 'critical': + case 'Critical': return 'danger'; default: return 'secondary'; diff --git a/src/locales/en-US.json b/src/locales/en-US.json index b36a18e2..2ff98418 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -231,7 +231,8 @@ "description": "Description", "id": "ID", "noHighEventsMsg": "There are no high priority events to display at this time.", - "refCode": "Reference code", + "severity": "Severity", + "type": "Type", "viewAllButton": "View all event logs" }, "network": { diff --git a/src/store/modules/Health/EventLogStore.js b/src/store/modules/Health/EventLogStore.js index 418e4558..2f0b800f 100644 --- a/src/store/modules/Health/EventLogStore.js +++ b/src/store/modules/Health/EventLogStore.js @@ -1,117 +1,58 @@ import api from '../../api'; -const EVENT_SEVERITY = { - emergency: 'xyz.openbmc_project.Logging.Entry.Level.Emergency', - alert: 'xyz.openbmc_project.Logging.Entry.Level.Alert', - critical: 'xyz.openbmc_project.Logging.Entry.Level.Critical', - error: 'xyz.openbmc_project.Logging.Entry.Level.Error', - warning: 'xyz.openbmc_project.Logging.Entry.Level.Warning', - notice: 'xyz.openbmc_project.Logging.Entry.Level.Notice', - informational: 'xyz.openbmc_project.Logging.Entry.Level.Informational', - debug: 'xyz.openbmc_project.Logging.Entry.Level.Debug' -}; - -const priorityMapper = severity => { - switch (severity) { - case EVENT_SEVERITY.emergency: - case EVENT_SEVERITY.alert: - case EVENT_SEVERITY.critical: - case EVENT_SEVERITY.error: - return 'high'; - case EVENT_SEVERITY.warning: - return 'medium'; - case EVENT_SEVERITY.notice: - case EVENT_SEVERITY.debug: - case EVENT_SEVERITY.informational: - return 'low'; - default: - return ''; - } -}; - -const getHealthStatus = allEvents => { - let status = 'good'; - for (const event of allEvents) { - if (!event.Resolved && event.priority === 'medium') { - status = 'warning'; +const getHealthStatus = events => { + let status = 'OK'; + for (const event of events) { + if (event.severity === 'Warning') { + status = 'Warning'; } - if (!event.Resolved && event.priority === 'high') { - status = 'critical'; + if (event.severity === 'Critical') { + status = 'Critical'; break; } } return status; }; +// TODO: High priority events should also check if Log +// is resolved when the property is available in Redfish +const getHighPriorityEvents = events => + events.filter(({ severity }) => severity === 'Critical'); + const EventLogStore = { namespaced: true, state: { - allEvents: [], - highPriorityEvents: [], - healthStatus: null + allEvents: [] }, getters: { allEvents: state => state.allEvents, - highPriorityEvents: state => state.highPriorityEvents, - healthStatus: state => state.healthStatus + highPriorityEvents: state => getHighPriorityEvents(state.allEvents), + healthStatus: state => getHealthStatus(state.allEvents) }, mutations: { - setAllEvents: (state, allEvents) => (state.allEvents = allEvents), - setHighPriorityEvents: (state, highPriorityEvents) => - (state.highPriorityEvents = highPriorityEvents), - setHealthStatus: (state, status) => (state.healthStatus = status) + setAllEvents: (state, allEvents) => (state.allEvents = allEvents) }, actions: { async getEventLogData({ commit }) { return await api - .get('/xyz/openbmc_project/logging/enumerate') - .then(response => { - const responseData = response.data.data; - const eventLogs = []; - - for (const key in responseData) { - const event = responseData[key]; - const { Id } = event; - if (responseData.hasOwnProperty(key) && Id) { - const { EventID, Description, Timestamp, Severity } = event; - eventLogs.push({ - logId: Id, - priority: priorityMapper(Severity), - timestamp: new Date(Timestamp), - eventID: EventID, - description: Description, - ...event - }); + .get('/redfish/v1/Systems/system/LogServices/EventLog/Entries') + .then(({ data: { Members = [] } = {} }) => { + const eventLogs = Members.map( + ({ Id, Severity, Created, EntryType, Message }) => { + return { + id: Id, + severity: Severity, + date: new Date(Created), + type: EntryType, + description: Message + }; } - } - - const healthStatus = getHealthStatus(eventLogs); - const highPriorityEvents = eventLogs.filter( - ({ priority, Resolved }) => priority === 'high' && !Resolved ); - commit('setAllEvents', eventLogs); - commit('setHighPriorityEvents', highPriorityEvents); - commit('setHealthStatus', healthStatus); }) .catch(error => { console.log('Event Log Data:', error); }); - }, - checkHealth({ commit, getters }, interfaces) { - if (getters['healthStatus'] === 'critical') return; - for (const key in interfaces) { - const event = interfaces[key]; - const eventPriority = priorityMapper(event.Severity); - const isEventResolved = event.Resolved; - if (!isEventResolved) { - if (eventPriority === 'high') { - commit('setHealthStatus', 'critical'); - break; - } - if (eventPriority === 'medium') commit('setHealthStatus', 'warning'); - } - } } } }; diff --git a/src/store/plugins/WebSocketPlugin.js b/src/store/plugins/WebSocketPlugin.js index 965c32c9..400fdefa 100644 --- a/src/store/plugins/WebSocketPlugin.js +++ b/src/store/plugins/WebSocketPlugin.js @@ -1,3 +1,5 @@ +import { debounce } from 'lodash'; + /** * WebSocketPlugin will allow us to get new data from the server * without having to poll for changes on the frontend. @@ -26,23 +28,21 @@ const WebSocketPlugin = store => { ws.onerror = event => { console.error(event); }; - ws.onmessage = event => { + ws.onmessage = debounce(event => { const data = JSON.parse(event.data); const eventInterface = data.interface; + const path = data.path; if (eventInterface === 'xyz.openbmc_project.State.Host') { const { properties: { CurrentHostState } = {} } = data; store.commit('global/setHostStatus', CurrentHostState); - } else { - const { interfaces, event } = data; - if (event === 'InterfacesAdded' && interfaces) { - // Checking for 'InterfacesAdded' events - // since they have all properties needed to - // change health status - store.dispatch('eventLog/checkHealth', interfaces); - } + } else if (path === '/xyz/openbmc_project/logging') { + store.dispatch('eventLog/getEventLogData'); } - }; + // 2.5 sec debounce to avoid making multiple consecutive + // GET requests since log related server messages seem to + // come in clusters + }, 2500); }; store.subscribe(({ type }) => { diff --git a/src/views/Overview/OverviewEvents.vue b/src/views/Overview/OverviewEvents.vue index ff9c302a..64ba7fc6 100644 --- a/src/views/Overview/OverviewEvents.vue +++ b/src/views/Overview/OverviewEvents.vue @@ -9,19 +9,19 @@ {{ $t('pageOverview.events.viewAllButton') }} </b-button> <b-table - head-variant="dark" per-page="5" - sort-by="logId" + sort-by="date" sort-desc stacked="sm" :items="eventLogData" :fields="fields" > - <template v-slot:cell(timestamp)="data"> - <div class="date-column"> - {{ data.value | formatDate }} <br /> - {{ data.value | formatTime }} - </div> + <template v-slot:cell(severity)="{ value }"> + <status-icon status="danger" /> + {{ value }} + </template> + <template v-slot:cell(date)="{ value }"> + {{ value | formatDate }} {{ value | formatTime }} </template> </b-table> </div> @@ -29,21 +29,28 @@ </template> <script> +import StatusIcon from '@/components/Global/StatusIcon'; + export default { name: 'Events', + components: { StatusIcon }, data() { return { fields: [ { - key: 'logId', + key: 'id', label: this.$t('pageOverview.events.id') }, { - key: 'eventID', - label: this.$t('pageOverview.events.refCode') + key: 'severity', + label: this.$t('pageOverview.events.severity') }, { - key: 'timestamp', + key: 'type', + label: this.$t('pageOverview.events.type') + }, + { + key: 'date', label: this.$t('pageOverview.events.date') }, { @@ -65,9 +72,3 @@ export default { } }; </script> - -<style lang="scss" scoped> -.date-column { - min-width: 200px; -} -</style> |