diff --git a/apps/xprof_core/src/xprof_core_trace_handler.erl b/apps/xprof_core/src/xprof_core_trace_handler.erl index 23888a97..83e11751 100644 --- a/apps/xprof_core/src/xprof_core_trace_handler.erl +++ b/apps/xprof_core/src/xprof_core_trace_handler.erl @@ -224,16 +224,16 @@ get_current_hist_stats(HistRef, Time) -> [{time, Time}, {min, hdr_histogram:min(HistRef)}, {mean, hdr_histogram:mean(HistRef)}, - {median, hdr_histogram:median(HistRef)}, + %%{median, hdr_histogram:median(HistRef)}, {max, hdr_histogram:max(HistRef)}, - {stddev, hdr_histogram:stddev(HistRef)}, - {p25, hdr_histogram:percentile(HistRef,25.0)}, + %%{stddev, hdr_histogram:stddev(HistRef)}, + %%{p25, hdr_histogram:percentile(HistRef,25.0)}, {p50, hdr_histogram:percentile(HistRef,50.0)}, {p75, hdr_histogram:percentile(HistRef,75.0)}, {p90, hdr_histogram:percentile(HistRef,90.0)}, {p99, hdr_histogram:percentile(HistRef,99.0)}, - {p9999999, hdr_histogram:percentile(HistRef,99.9999)}, - {memsize, hdr_histogram:get_memory_size(HistRef)}, + %%{p9999999, hdr_histogram:percentile(HistRef,99.9999)}, + %%{memsize, hdr_histogram:get_memory_size(HistRef)}, {count, hdr_histogram:get_total_count(HistRef)}]. remove_outdated_snapshots(Name, TS) -> diff --git a/apps/xprof_gui/priv/src/actions/CollectingActions.js b/apps/xprof_gui/priv/src/actions/CollectingActions.js index eef75156..61bc4c8b 100644 --- a/apps/xprof_gui/priv/src/actions/CollectingActions.js +++ b/apps/xprof_gui/priv/src/actions/CollectingActions.js @@ -28,6 +28,11 @@ const updateData = data => ({ data, }); +export const addY = y => ({ + type: types.ADD_Y, + y, +}); + const updateCalls = calls => ({ type: types.UPDATE_CALLS, calls, diff --git a/apps/xprof_gui/priv/src/actions/index.js b/apps/xprof_gui/priv/src/actions/index.js index bf707166..55e1f83c 100644 --- a/apps/xprof_gui/priv/src/actions/index.js +++ b/apps/xprof_gui/priv/src/actions/index.js @@ -5,6 +5,7 @@ export { getFunctionsCalls, setIDs, setSize, + addY, } from './CollectingActions'; export { stopMonitoringFunction, diff --git a/apps/xprof_gui/priv/src/components/monitoring/Graph/Graph.jsx b/apps/xprof_gui/priv/src/components/monitoring/Graph/Graph.jsx index 1ff1a8ac..a832d2af 100644 --- a/apps/xprof_gui/priv/src/components/monitoring/Graph/Graph.jsx +++ b/apps/xprof_gui/priv/src/components/monitoring/Graph/Graph.jsx @@ -10,6 +10,7 @@ const defaultProps = { const propTypes = { dps: PropTypes.arrayOf(PropTypes.object).isRequired, + y: PropTypes.arrayOf(PropTypes.string).isRequired, type: PropTypes.string.isRequired, monitoredID: PropTypes.string.isRequired, setSize: PropTypes.func.isRequired, @@ -17,11 +18,7 @@ const propTypes = { }; const Graph = ({ - dps, - type, - monitoredID, - setSize, - size, + dps, y, type, monitoredID, setSize, size, }) => { switch (type) { case GRAPH_TYPE.GRID: @@ -31,9 +28,10 @@ const Graph = ({ monitoredID={monitoredID} setSize={setSize} size={size} - />); + /> + ); case GRAPH_TYPE.LINE: - return ; + return ; default: return null; } diff --git a/apps/xprof_gui/priv/src/components/monitoring/GraphPanel/GraphPanel.jsx b/apps/xprof_gui/priv/src/components/monitoring/GraphPanel/GraphPanel.jsx index f4175399..1e8b648c 100644 --- a/apps/xprof_gui/priv/src/components/monitoring/GraphPanel/GraphPanel.jsx +++ b/apps/xprof_gui/priv/src/components/monitoring/GraphPanel/GraphPanel.jsx @@ -5,6 +5,7 @@ import { GRAPH_INITIAL_SIZE } from '../../../constants'; const defaultProps = { dps: [], + y: [], callees: [], calleesVisibility: false, panelVisibility: true, @@ -18,6 +19,7 @@ const propTypes = { query: PropTypes.string, }).isRequired, dps: PropTypes.arrayOf(PropTypes.object), + y: PropTypes.arrayOf(PropTypes.string), stopMonitoringFunction: PropTypes.func.isRequired, callees: PropTypes.arrayOf(PropTypes.string), calleesVisibility: PropTypes.bool, @@ -36,6 +38,7 @@ const propTypes = { const GraphPanel = ({ monitored, dps, + y, stopMonitoringFunction, callees, calleesVisibility, @@ -70,6 +73,7 @@ const GraphPanel = ({
( +const LineGraph = ({ dps, y }) => (
{ functionClick: jest.fn(), setPositionOnFunction: jest.fn(), isConnection: true, + switchGrid: jest.fn(), }; it('renders', () => { const wrapper = shallow(); diff --git a/apps/xprof_gui/priv/src/constants/ActionTypes.js b/apps/xprof_gui/priv/src/constants/ActionTypes.js index 4c80ae50..922036ff 100644 --- a/apps/xprof_gui/priv/src/constants/ActionTypes.js +++ b/apps/xprof_gui/priv/src/constants/ActionTypes.js @@ -19,6 +19,7 @@ export const SAVE_DIRTY_INPUT = 'SAVE_DIRTY_INPUT'; // monitoring export const UPDATE_MONITORED_FUNCTIONS = 'UPDATE_MONITORED_FUNCTIONS'; export const UPDATE_DATA = 'UPDATE_DATA'; +export const ADD_Y = 'ADD_Y'; export const STOP_MONITORING_FUNCTION = 'STOP_MONITORING_FUNCTION'; export const STOP_MONITORING_FUNCTION_ERROR = 'STOP_MONITORING_FUNCTION_ERROR'; export const EXPAND_GRAPH_PANEL = 'EXPAND_GRAPH_PANEL'; diff --git a/apps/xprof_gui/priv/src/constants/GraphConstants.js b/apps/xprof_gui/priv/src/constants/GraphConstants.js index dd3b6d25..2d9b0c4a 100644 --- a/apps/xprof_gui/priv/src/constants/GraphConstants.js +++ b/apps/xprof_gui/priv/src/constants/GraphConstants.js @@ -3,6 +3,8 @@ import { format } from 'd3'; export const COLUMNS = { time: 'time', count: 'count', + total_count: 'total_count', + match_rate: 'match_rate', max: 'max', p99: 'p99', p90: 'p90', @@ -19,24 +21,27 @@ export const DATA = { json: [], keys: { x: COLUMNS.time, - value: [ - COLUMNS.min, - COLUMNS.mean, - // COLUMNS.median, - COLUMNS.max, - // COLUMNS.stddev, - // COLUMNS.p25, - COLUMNS.p50, - COLUMNS.p75, - COLUMNS.p90, - COLUMNS.p99, - // COLUMNS.memsize, - COLUMNS.count, - ], + // value: [ + // COLUMNS.min, + // COLUMNS.mean, + // // COLUMNS.median, + // COLUMNS.max, + // // COLUMNS.stddev, + // // COLUMNS.p25, + // COLUMNS.p50, + // COLUMNS.p75, + // COLUMNS.p90, + // COLUMNS.p99, + // // COLUMNS.memsize, + // COLUMNS.count, + // ], }, - hide: [COLUMNS.max, COLUMNS.p90, COLUMNS.p75, COLUMNS.p50], + hide: [COLUMNS.max, COLUMNS.p90, COLUMNS.p75, COLUMNS.p50, + COLUMNS.total_count, COLUMNS.match_rate], axes: { count: 'y2', + total_count: 'y2', + match_rate: 'y2', }, names: { count: 'count', @@ -48,12 +53,10 @@ export const DATA = { p25: '25th perc', mean: 'mean', min: 'min', - median: 'median', - memsize: 'memsize', - stddev: 'stddev', }, colors: { count: '#98FB98', + total_count: '44AA44', max: '#8C2A04', p99: '#E24806', p90: '#E24806', @@ -102,7 +105,7 @@ export const AXIS = { show: true, min: 0, padding: { bottom: 2 }, - label: { text: 'Call count', position: 'outer-middle' }, + label: { text: 'Call count / Match rate %', position: 'outer-middle' }, tick: { outer: false, }, diff --git a/apps/xprof_gui/priv/src/containers/MonitoringContainer/MonitoringContainer.jsx b/apps/xprof_gui/priv/src/containers/MonitoringContainer/MonitoringContainer.jsx index fca70a32..9720b211 100644 --- a/apps/xprof_gui/priv/src/containers/MonitoringContainer/MonitoringContainer.jsx +++ b/apps/xprof_gui/priv/src/containers/MonitoringContainer/MonitoringContainer.jsx @@ -20,6 +20,7 @@ import { isConnection, getSize, getIDs, + getFunctionY, } from '../../selectors'; const MonitoringContainer = props => ; @@ -27,6 +28,7 @@ const MonitoringContainer = props => ; const mapStateToProps = (state, ownProps) => ({ monitored: ownProps.monitored, data: getFunctionData(state, ownProps.monitored.query), + y: getFunctionY(state, ownProps.monitored.query), callees: getFunctionCallees(state, ownProps.monitored.query), calleesVisibility: getFunctionCalleesVisibility( state, diff --git a/apps/xprof_gui/priv/src/reducers/monitoring.js b/apps/xprof_gui/priv/src/reducers/monitoring.js index e3fb1231..572cb60b 100644 --- a/apps/xprof_gui/priv/src/reducers/monitoring.js +++ b/apps/xprof_gui/priv/src/reducers/monitoring.js @@ -3,6 +3,7 @@ import * as types from '../constants/ActionTypes'; const initialState = { monitoredCollection: [], data: {}, + y: {}, panel: {}, callees: {}, ids: {}, @@ -43,6 +44,14 @@ const monitoring = (state = initialState, action) => { ...state, ids: action.ids, }; + case types.ADD_Y: + return { + ...state, + y: { + ...state.y, + ...action.y, + }, + }; default: return state; } diff --git a/apps/xprof_gui/priv/src/selectors/Selectors.js b/apps/xprof_gui/priv/src/selectors/Selectors.js index 55549c88..127e9e34 100644 --- a/apps/xprof_gui/priv/src/selectors/Selectors.js +++ b/apps/xprof_gui/priv/src/selectors/Selectors.js @@ -18,6 +18,7 @@ export const getData = state => state.monitoring.data; export const getFunctionData = (state, fun) => state.monitoring.data[fun]; export const getIDs = state => state.monitoring.ids; export const getSize = state => state.monitoring.size; +export const getFunctionY = (state, fun) => state.monitoring.y[fun]; // navigation export const getQuery = state => state.navigation.query; diff --git a/apps/xprof_gui/priv/src/utils/ActionUtils.spec.js b/apps/xprof_gui/priv/src/utils/ActionUtils.spec.js index ea85396a..6636433a 100644 --- a/apps/xprof_gui/priv/src/utils/ActionUtils.spec.js +++ b/apps/xprof_gui/priv/src/utils/ActionUtils.spec.js @@ -423,7 +423,7 @@ describe('Action utils', () => { }; // when const result = await ActionUtils.determineNextData( - null, + dispatch, mockMonitoredCollection, data, ); @@ -436,7 +436,7 @@ describe('Action utils', () => { XProf.getFunctionsSamples.mockReturnValue({ json: [{ time: 13 }] }); // when const result = await ActionUtils.determineNextData( - null, + dispatch, mockMonitoredCollection, {}, ); @@ -448,7 +448,11 @@ describe('Action utils', () => { // given XProf.getFunctionsSamples.mockReturnValue({ json: [{ time: 13 }] }); // when - await ActionUtils.determineNextData(null, mockMonitoredCollection, {}); + await ActionUtils.determineNextData( + dispatch, + mockMonitoredCollection, + {}, + ); // then expect(XProf.getFunctionsSamples).toHaveBeenCalledTimes(2); }); diff --git a/apps/xprof_gui/priv/src/utils/ActionsUtils.js b/apps/xprof_gui/priv/src/utils/ActionsUtils.js index 54a08a64..78bfa398 100644 --- a/apps/xprof_gui/priv/src/utils/ActionsUtils.js +++ b/apps/xprof_gui/priv/src/utils/ActionsUtils.js @@ -8,8 +8,9 @@ import { CALLS_COLUMNS, SORT, NOTIFICATIONS, + COLUMNS, } from '../constants'; -import { setCallsControl, addNotification } from '../actions'; +import { setCallsControl, addNotification, addY } from '../actions'; import * as XProf from '../api'; export const determineNextCallsForFun = (json, lastCalls, calls, name) => { @@ -154,6 +155,8 @@ export const determineIncomingDps = (dps, ts) => { })); }; +const isFirstDps = (dps, ts) => dpsDecision(dps, ts) === DPS_ACTION.FIRST_DPS; + export const determineNextData = async ( dispatch, monitoredCollection, @@ -180,7 +183,15 @@ export const determineNextData = async ( NOTIFICATIONS.SAMPLES.MESSAGE(monitored.query), )); } else if (json.length) { - const incomingDpsSorted = sortBy(json, 'time'); + const incomingDpsSorted = sortBy(json, COLUMNS.time); + + if (isFirstDps(incomingDpsSorted, lastTs)) { + // eslint-disable-next-line + const y = Object.keys(incomingDpsSorted[0]).filter( + f => f !== COLUMNS.time); + dispatch(addY({ [completeFunName]: y })); + } + const incomingDps = determineIncomingDps(incomingDpsSorted, lastTs); const concatenatedDps = currentDps ? [...currentDps, ...incomingDps]