Create actions and reducer for process logs panel
[arvados-workbench2.git] / src / store / process-logs-panel / process-logs-panel-actions.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { unionize, ofType, UnionOf } from "~/common/unionize";
6 import { ProcessLogs } from './process-logs-panel';
7 import { LogEventType } from '~/models/log';
8 import { RootState } from '~/store/store';
9 import { ServiceRepository } from '~/services/services';
10 import { Dispatch } from 'redux';
11 import { FilterBuilder } from '~/common/api/filter-builder';
12 import { groupBy } from 'lodash';
13 import { loadProcess } from '~/store/processes/processes-actions';
14 import { OrderBuilder } from '~/common/api/order-builder';
15 import { LogResource } from '~/models/log';
16 import { LogService } from '~/services/log-service/log-service';
17
18 export const processLogsPanelActions = unionize({
19     INIT_PROCESS_LOGS_PANEL: ofType<{ filters: string[], logs: ProcessLogs }>(),
20     SET_PROCESS_LOGS_PANEL_FILTER: ofType<string>(),
21     ADD_PROCESS_LOGS_PANEL_ITEM: ofType<{ logType: string, log: string }>(),
22 });
23
24 export type ProcessLogsPanelAction = UnionOf<typeof processLogsPanelActions>;
25
26 export const initProcessLogsPanel = (processUuid: string) =>
27     async (dispatch: Dispatch, getState: () => RootState, { logService }: ServiceRepository) => {
28         const process = await dispatch<any>(loadProcess(processUuid));
29         if (process.container) {
30             const logResources = await loadContainerLogs(process.container.uuid, logService);
31             const initialState = createInitialLogPanelState(logResources);
32             dispatch(processLogsPanelActions.INIT_PROCESS_LOGS_PANEL(initialState));
33         }
34     };
35
36 const loadContainerLogs = async (containerUuid: string, logService: LogService) => {
37     const requestFilters = new FilterBuilder()
38         .addEqual('objectUuid', containerUuid)
39         .addIn('eventType', PROCESS_PANEL_LOG_EVENT_TYPES)
40         .getFilters();
41     const requestOrder = new OrderBuilder<LogResource>()
42         .addAsc('eventAt')
43         .getOrder();
44     const requestParams = {
45         limit: 10000,
46         filters: requestFilters,
47         order: requestOrder,
48     };
49     const { items } = await logService.list(requestParams);
50     return items;
51 };
52
53 const createInitialLogPanelState = (logResources: LogResource[]) => {
54     const allLogs = logResources.map(({ properties }) => properties.text);
55     const groupedLogResources = groupBy(logResources, log => log.eventType);
56     const groupedLogs = Object
57         .keys(groupedLogResources)
58         .reduce((grouped, key) => ({
59             ...grouped,
60             [key]: groupedLogResources[key].map(({ properties }) => properties.text)
61         }), {});
62     const filters = [SUMMARIZED_FILTER_TYPE, ...Object.keys(groupedLogs)];
63     const logs = { [SUMMARIZED_FILTER_TYPE]: allLogs, ...groupedLogs };
64     return { filters, logs };
65 };
66
67
68 const SUMMARIZED_FILTER_TYPE = 'Summarized';
69
70 const PROCESS_PANEL_LOG_EVENT_TYPES = [
71     LogEventType.ARV_MOUNT,
72     LogEventType.CRUNCH_RUN,
73     LogEventType.CRUNCHSTAT,
74     LogEventType.DISPATCH,
75     LogEventType.HOSTSTAT,
76     LogEventType.NODE_INFO,
77     LogEventType.STDERR,
78     LogEventType.STDOUT,
79 ];