summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshie Muranaka <yoshiemuranaka@gmail.com>2020-05-07 00:33:22 +0300
committerDerick Montague <derick.montague@ibm.com>2020-05-21 15:38:56 +0300
commitce9a3ef3036923cb4c0f28240c8bb37a6b4540fc (patch)
tree80b08017b82e19a4dc8ea4b537a13eaa2f861ed6
parent9055d9880b35b8c076f2ff12e726f1cf22f237fc (diff)
downloadwebui-vue-ce9a3ef3036923cb4c0f28240c8bb37a6b4540fc.tar.xz
Update EventLogStore request to use Redfish
Changes to WebSocketPlugin to dispatch event log GET request when new event interfaces are received. By re-fetching the Redfish logs the health status icon in the application header will always reflect the visible event logs. The plugin was previously only updating the header status, so it was possible for the header status and event logs to be out of sync. - Changed to use Redfish endpoint for event log GET request /redfish/v1/Systems/system/LogServices/EventLog/Entries - Update AppHeader Health status icon to reflect changes made with Redfish log Severity property Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com> Change-Id: I73a3a441dcbbb3a29ef9a51f961c062689cb5add
-rw-r--r--src/components/AppHeader/AppHeader.vue6
-rw-r--r--src/locales/en-US.json3
-rw-r--r--src/store/modules/Health/EventLogStore.js113
-rw-r--r--src/store/plugins/WebSocketPlugin.js20
-rw-r--r--src/views/Overview/OverviewEvents.vue35
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>