1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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';
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 }>(),
24 export type ProcessLogsPanelAction = UnionOf<typeof processLogsPanelActions>;
26 export const setProcessLogsPanelFilter = (filter: string) =>
27 processLogsPanelActions.SET_PROCESS_LOGS_PANEL_FILTER(filter);
29 export const initProcessLogsPanel = (processUuid: string) =>
30 async (dispatch: Dispatch, getState: () => RootState, { logService }: ServiceRepository) => {
31 const process = await dispatch<any>(loadProcess(processUuid));
32 if (process.container) {
33 const logResources = await loadContainerLogs(process.container.uuid, logService);
34 const initialState = createInitialLogPanelState(logResources);
35 dispatch(processLogsPanelActions.INIT_PROCESS_LOGS_PANEL(initialState));
39 const loadContainerLogs = async (containerUuid: string, logService: LogService) => {
40 const requestFilters = new FilterBuilder()
41 .addEqual('objectUuid', containerUuid)
42 .addIn('eventType', PROCESS_PANEL_LOG_EVENT_TYPES)
44 const requestOrder = new OrderBuilder<LogResource>()
47 const requestParams = {
48 limit: MAX_AMOUNT_OF_LOGS,
49 filters: requestFilters,
52 const { items } = await logService.list(requestParams);
56 const createInitialLogPanelState = (logResources: LogResource[]) => {
57 const allLogs = logsToLines(logResources);
58 const groupedLogResources = groupBy(logResources, log => log.eventType);
59 const groupedLogs = Object
60 .keys(groupedLogResources)
61 .reduce((grouped, key) => ({
63 [key]: logsToLines(groupedLogResources[key])
65 const filters = [SUMMARIZED_FILTER_TYPE, ...Object.keys(groupedLogs)];
66 const logs = { [SUMMARIZED_FILTER_TYPE]: allLogs, ...groupedLogs };
67 return { filters, logs };
70 const logsToLines = (logs: LogResource[]) =>
71 logs.map(({properties}) => properties.text);
73 const MAX_AMOUNT_OF_LOGS = 10000;
75 const SUMMARIZED_FILTER_TYPE = 'Summarized';
77 const PROCESS_PANEL_LOG_EVENT_TYPES = [
78 LogEventType.ARV_MOUNT,
79 LogEventType.CRUNCH_RUN,
80 LogEventType.CRUNCHSTAT,
81 LogEventType.DISPATCH,
82 LogEventType.HOSTSTAT,
83 LogEventType.NODE_INFO,