
webapp.src.components.QueryDetail.jsx Maven / Gradle / Ivy
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from "react";
import Reactable from "reactable";
import {
addToHistory,
computeRate,
formatCount,
formatDataSize,
formatDataSizeBytes,
formatDuration,
formatShortDateTime,
getFirstParameter,
getHostAndPort,
getHostname,
getPort,
getStageNumber,
getStageStateColor,
getTaskIdSuffix,
getTaskNumber,
GLYPHICON_HIGHLIGHT,
parseAndFormatDataSize,
parseDataSize,
parseDuration,
precisionRound
} from "../utils";
import {QueryHeader} from "./QueryHeader";
const Table = Reactable.Table,
Thead = Reactable.Thead,
Th = Reactable.Th,
Tr = Reactable.Tr,
Td = Reactable.Td;
class TaskList extends React.Component {
static removeQueryId(id) {
const pos = id.indexOf('.');
if (pos !== -1) {
return id.substring(pos + 1);
}
return id;
}
static compareTaskId(taskA, taskB) {
const taskIdArrA = TaskList.removeQueryId(taskA).split(".");
const taskIdArrB = TaskList.removeQueryId(taskB).split(".");
if (taskIdArrA.length > taskIdArrB.length) {
return 1;
}
for (let i = 0; i < taskIdArrA.length; i++) {
const anum = Number.parseInt(taskIdArrA[i]);
const bnum = Number.parseInt(taskIdArrB[i]);
if (anum !== bnum) {
return anum > bnum ? 1 : -1;
}
}
return 0;
}
static showPortNumbers(tasks) {
// check if any host has multiple port numbers
const hostToPortNumber = {};
for (let i = 0; i < tasks.length; i++) {
const taskUri = tasks[i].taskStatus.self;
const hostname = getHostname(taskUri);
const port = getPort(taskUri);
if ((hostname in hostToPortNumber) && (hostToPortNumber[hostname] !== port)) {
return true;
}
hostToPortNumber[hostname] = port;
}
return false;
}
static formatState(state, fullyBlocked) {
if (fullyBlocked && state === "RUNNING") {
return "BLOCKED";
}
else {
return state;
}
}
render() {
const tasks = this.props.tasks;
const taskRetriesEnabled = this.props.taskRetriesEnabled;
if (tasks === undefined || tasks.length === 0) {
return (
No threads in the selected group
);
}
const showPortNumbers = TaskList.showPortNumbers(tasks);
const renderedTasks = tasks.map(task => {
let elapsedTime = parseDuration(task.stats.elapsedTime);
if (elapsedTime === 0) {
elapsedTime = Date.now() - Date.parse(task.stats.createTime);
}
return (
{getTaskIdSuffix(task.taskStatus.taskId)}
{showPortNumbers ? getHostAndPort(task.taskStatus.self) : getHostname(task.taskStatus.self)}
{TaskList.formatState(task.taskStatus.state, task.stats.fullyBlocked)}
{formatCount(task.stats.rawInputPositions)}
{formatCount(computeRate(task.stats.rawInputPositions, elapsedTime))}
{formatDataSizeBytes(parseDataSize(task.stats.rawInputDataSize))}
{formatDataSizeBytes(computeRate(parseDataSize(task.stats.rawInputDataSize), elapsedTime))}
{task.stats.queuedDrivers}
{task.stats.runningDrivers}
{task.stats.blockedDrivers}
{task.stats.completedDrivers}
{task.stats.elapsedTime}
{task.stats.totalCpuTime}
{formatDataSizeBytes(task.outputBuffers.totalBufferedBytes)}
{parseAndFormatDataSize(task.stats.userMemoryReservation)}
{parseAndFormatDataSize(task.stats.peakUserMemoryReservation)}
{taskRetriesEnabled &&
{parseAndFormatDataSize(task.estimatedMemory)}
}
);
});
return (
ID
Host
State
Rows
Rows/s
Bytes
Bytes/s
Elapsed
CPU Time
Mem
Peak Mem
{taskRetriesEnabled &&
Est Mem
}
{renderedTasks}
);
}
}
const BAR_CHART_WIDTH = 800;
const BAR_CHART_PROPERTIES = {
type: 'bar',
barSpacing: '0',
height: '80px',
barColor: '#747F96',
zeroColor: '#8997B3',
chartRangeMin: 0,
tooltipClassname: 'sparkline-tooltip',
tooltipFormat: 'Task {{offset:offset}} - {{value}}',
disableHiddenCheck: true,
};
const HISTOGRAM_WIDTH = 175;
const HISTOGRAM_PROPERTIES = {
type: 'bar',
barSpacing: '0',
height: '80px',
barColor: '#747F96',
zeroColor: '#747F96',
zeroAxis: true,
chartRangeMin: 0,
tooltipClassname: 'sparkline-tooltip',
tooltipFormat: '{{offset:offset}} -- {{value}} tasks',
disableHiddenCheck: true,
};
class StageSummary extends React.Component {
constructor(props) {
super(props);
this.state = {
expanded: false,
lastRender: null,
taskFilter: TASK_FILTER.ALL
};
}
getExpandedIcon() {
return this.state.expanded ? "glyphicon-chevron-up" : "glyphicon-chevron-down";
}
getExpandedStyle() {
return this.state.expanded ? {} : {display: "none"};
}
toggleExpanded() {
this.setState({
expanded: !this.state.expanded,
})
}
static renderHistogram(histogramId, inputData, numberFormatter) {
const numBuckets = Math.min(HISTOGRAM_WIDTH, Math.sqrt(inputData.length));
const dataMin = Math.min.apply(null, inputData);
const dataMax = Math.max.apply(null, inputData);
const bucketSize = (dataMax - dataMin) / numBuckets;
let histogramData = [];
if (bucketSize === 0) {
histogramData = [inputData.length];
}
else {
for (let i = 0; i < numBuckets + 1; i++) {
histogramData.push(0);
}
for (let i in inputData) {
const dataPoint = inputData[i];
const bucket = Math.floor((dataPoint - dataMin) / bucketSize);
histogramData[bucket] = histogramData[bucket] + 1;
}
}
const tooltipValueLookups = {'offset': {}};
for (let i = 0; i < histogramData.length; i++) {
tooltipValueLookups['offset'][i] = numberFormatter(dataMin + (i * bucketSize)) + "-" + numberFormatter(dataMin + ((i + 1) * bucketSize));
}
const stageHistogramProperties = $.extend({}, HISTOGRAM_PROPERTIES, {barWidth: (HISTOGRAM_WIDTH / histogramData.length), tooltipValueLookups: tooltipValueLookups});
$(histogramId).sparkline(histogramData, stageHistogramProperties);
}
componentDidUpdate() {
const stage = this.props.stage;
const numTasks = stage.tasks.length;
// sort the x-axis
stage.tasks.sort((taskA, taskB) => getTaskNumber(taskA.taskStatus.taskId) - getTaskNumber(taskB.taskStatus.taskId));
const scheduledTimes = stage.tasks.map(task => parseDuration(task.stats.totalScheduledTime));
const cpuTimes = stage.tasks.map(task => parseDuration(task.stats.totalCpuTime));
// prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts
if (this.state.lastRender === null || (Date.now() - this.state.lastRender) >= 1000) {
const renderTimestamp = Date.now();
const stageId = getStageNumber(stage.stageId);
StageSummary.renderHistogram('#scheduled-time-histogram-' + stageId, scheduledTimes, formatDuration);
StageSummary.renderHistogram('#cpu-time-histogram-' + stageId, cpuTimes, formatDuration);
if (this.state.expanded) {
// this needs to be a string otherwise it will also be passed to numberFormatter
const tooltipValueLookups = {'offset': {}};
for (let i = 0; i < numTasks; i++) {
tooltipValueLookups['offset'][i] = getStageNumber(stage.stageId) + "." + i;
}
const stageBarChartProperties = $.extend({}, BAR_CHART_PROPERTIES, {barWidth: BAR_CHART_WIDTH / numTasks, tooltipValueLookups: tooltipValueLookups});
$('#scheduled-time-bar-chart-' + stageId).sparkline(scheduledTimes, $.extend({}, stageBarChartProperties, {numberFormatter: formatDuration}));
$('#cpu-time-bar-chart-' + stageId).sparkline(cpuTimes, $.extend({}, stageBarChartProperties, {numberFormatter: formatDuration}));
}
this.setState({
lastRender: renderTimestamp
});
}
}
renderTaskList(taskRetriesEnabled) {
let tasks = this.state.expanded ? this.props.stage.tasks : [];
tasks = tasks.filter(task => this.state.taskFilter(task.taskStatus.state), this);
return ();
}
handleTaskFilterClick(filter, event) {
this.setState({
taskFilter: filter
});
event.preventDefault();
}
renderTaskFilterListItem(taskFilter, taskFilterText) {
return (
{taskFilterText}
);
}
renderTaskFilter() {
return (
Tasks
{this.renderTaskFilterListItem(TASK_FILTER.ALL, "All")}
{this.renderTaskFilterListItem(TASK_FILTER.PLANNED, "Planned")}
{this.renderTaskFilterListItem(TASK_FILTER.RUNNING, "Running")}
{this.renderTaskFilterListItem(TASK_FILTER.FINISHED, "Finished")}
{this.renderTaskFilterListItem(TASK_FILTER.FAILED, "Aborted/Canceled/Failed")}
);
}
render() {
const stage = this.props.stage;
const taskRetriesEnabled = this.props.taskRetriesEnabled;
if (stage === undefined || !stage.hasOwnProperty('plan')) {
return (
Information about this stage is unavailable.
);
}
const totalBufferedBytes = stage.tasks
.map(task => task.outputBuffers.totalBufferedBytes)
.reduce((a, b) => a + b, 0);
const stageId = getStageNumber(stage.stageId);
return (
{stageId}
);
}
}
class StageList extends React.Component {
getStages(stage) {
if (stage === undefined || !stage.hasOwnProperty('subStages')) {
return []
}
return [].concat.apply(stage, stage.subStages.map(this.getStages, this));
}
render() {
const stages = this.getStages(this.props.outputStage);
const taskRetriesEnabled = this.props.taskRetriesEnabled;
if (stages === undefined || stages.length === 0) {
return (
No stage information available.
);
}
const renderedStages = stages.map(stage => );
return (
{renderedStages}
);
}
}
const SMALL_SPARKLINE_PROPERTIES = {
width: '100%',
height: '57px',
fillColor: '#3F4552',
lineColor: '#747F96',
spotColor: '#1EDCFF',
tooltipClassname: 'sparkline-tooltip',
disableHiddenCheck: true,
};
const TASK_FILTER = {
ALL: function () { return true },
PLANNED: function (state) { return state === 'PLANNED' },
RUNNING: function (state) { return state === 'RUNNING' },
FINISHED: function (state) { return state === 'FINISHED' },
FAILED: function (state) { return state === 'FAILED' || state === 'ABORTED' || state === 'CANCELED' },
};
export class QueryDetail extends React.Component {
constructor(props) {
super(props);
this.state = {
query: null,
lastSnapshotStages: null,
lastSnapshotTasks: null,
lastScheduledTime: 0,
lastCpuTime: 0,
lastRowInput: 0,
lastByteInput: 0,
lastPhysicalInput: 0,
lastPhysicalTime: 0,
scheduledTimeRate: [],
cpuTimeRate: [],
rowInputRate: [],
byteInputRate: [],
physicalInputRate: [],
reservedMemory: [],
initialized: false,
queryEnded: false,
renderingEnded: false,
lastRefresh: null,
lastRender: null,
stageRefresh: true,
taskRefresh: true,
taskFilter: TASK_FILTER.ALL,
};
this.refreshLoop = this.refreshLoop.bind(this);
}
static formatStackTrace(info) {
return QueryDetail.formatStackTraceHelper(info, [], "", "");
}
static formatStackTraceHelper(info, parentStack, prefix, linePrefix) {
let s = linePrefix + prefix + QueryDetail.failureInfoToString(info) + "\n";
if (info.stack) {
let sharedStackFrames = 0;
if (parentStack !== null) {
sharedStackFrames = QueryDetail.countSharedStackFrames(info.stack, parentStack);
}
for (let i = 0; i < info.stack.length - sharedStackFrames; i++) {
s += linePrefix + "\tat " + info.stack[i] + "\n";
}
if (sharedStackFrames !== 0) {
s += linePrefix + "\t... " + sharedStackFrames + " more" + "\n";
}
}
if (info.suppressed) {
for (let i = 0; i < info.suppressed.length; i++) {
s += QueryDetail.formatStackTraceHelper(info.suppressed[i], info.stack, "Suppressed: ", linePrefix + "\t");
}
}
if (info.cause) {
s += QueryDetail.formatStackTraceHelper(info.cause, info.stack, "Caused by: ", linePrefix);
}
return s;
}
static countSharedStackFrames(stack, parentStack) {
let n = 0;
const minStackLength = Math.min(stack.length, parentStack.length);
while (n < minStackLength && stack[stack.length - 1 - n] === parentStack[parentStack.length - 1 - n]) {
n++;
}
return n;
}
static failureInfoToString(t) {
return (t.message !== null) ? (t.type + ": " + t.message) : t.type;
}
resetTimer() {
clearTimeout(this.timeoutId);
// stop refreshing when query finishes or fails
if (this.state.query === null || !this.state.queryEnded) {
// task.info-update-interval is set to 3 seconds by default
this.timeoutId = setTimeout(this.refreshLoop, 3000);
}
}
refreshLoop() {
clearTimeout(this.timeoutId); // to stop multiple series of refreshLoop from going on simultaneously
const queryId = getFirstParameter(window.location.search);
$.get('/ui/api/query/' + queryId, function (query) {
let lastSnapshotStages = this.state.lastSnapshotStage;
if (this.state.stageRefresh) {
lastSnapshotStages = query.outputStage;
}
let lastSnapshotTasks = this.state.lastSnapshotTasks;
if (this.state.taskRefresh) {
lastSnapshotTasks = query.outputStage;
}
let lastRefresh = this.state.lastRefresh;
const lastScheduledTime = this.state.lastScheduledTime;
const lastCpuTime = this.state.lastCpuTime;
const lastRowInput = this.state.lastRowInput;
const lastByteInput = this.state.lastByteInput;
const lastPhysicalInput = this.state.lastPhysicalInput;
const lastPhysicalTime = this.state.lastPhysicalTime;
const alreadyEnded = this.state.queryEnded;
const nowMillis = Date.now();
this.setState({
query: query,
lastSnapshotStage: lastSnapshotStages,
lastSnapshotTasks: lastSnapshotTasks,
lastPhysicalTime: parseDuration(query.queryStats.physicalInputReadTime),
lastScheduledTime: parseDuration(query.queryStats.totalScheduledTime),
lastCpuTime: parseDuration(query.queryStats.totalCpuTime),
lastRowInput: query.queryStats.processedInputPositions,
lastByteInput: parseDataSize(query.queryStats.processedInputDataSize),
lastPhysicalInput: parseDataSize(query.queryStats.physicalInputDataSize),
initialized: true,
queryEnded: !!query.finalQueryInfo,
lastRefresh: nowMillis,
});
// i.e. don't show sparklines if we've already decided not to update or if we don't have one previous measurement
if (alreadyEnded || (lastRefresh === null && query.state === "RUNNING")) {
this.resetTimer();
return;
}
if (lastRefresh === null) {
lastRefresh = nowMillis - parseDuration(query.queryStats.elapsedTime);
}
const elapsedSecsSinceLastRefresh = (nowMillis - lastRefresh) / 1000.0;
if (elapsedSecsSinceLastRefresh >= 0) {
const currentScheduledTimeRate = (parseDuration(query.queryStats.totalScheduledTime) - lastScheduledTime) / (elapsedSecsSinceLastRefresh * 1000);
const currentCpuTimeRate = (parseDuration(query.queryStats.totalCpuTime) - lastCpuTime) / (elapsedSecsSinceLastRefresh * 1000);
const currentPhysicalReadTime = (parseDuration(query.queryStats.physicalInputReadTime) - lastPhysicalTime) / 1000;
const currentRowInputRate = (query.queryStats.processedInputPositions - lastRowInput) / elapsedSecsSinceLastRefresh;
const currentByteInputRate = (parseDataSize(query.queryStats.processedInputDataSize) - lastByteInput) / elapsedSecsSinceLastRefresh;
const currentPhysicalInputRate = currentPhysicalReadTime > 0 ? (parseDataSize(query.queryStats.physicalInputDataSize) - lastPhysicalInput) / currentPhysicalReadTime : 0;
this.setState({
scheduledTimeRate: addToHistory(currentScheduledTimeRate, this.state.scheduledTimeRate),
cpuTimeRate: addToHistory(currentCpuTimeRate, this.state.cpuTimeRate),
rowInputRate: addToHistory(currentRowInputRate, this.state.rowInputRate),
byteInputRate: addToHistory(currentByteInputRate, this.state.byteInputRate),
reservedMemory: addToHistory(parseDataSize(query.queryStats.totalMemoryReservation), this.state.reservedMemory),
physicalInputRate: addToHistory(currentPhysicalInputRate, this.state.physicalInputRate),
});
}
this.resetTimer();
}.bind(this))
.fail(() => {
this.setState({
initialized: true,
});
this.resetTimer();
});
}
handleStageRefreshClick() {
if (this.state.stageRefresh) {
this.setState({
stageRefresh: false,
lastSnapshotStages: this.state.query.outputStage,
});
}
else {
this.setState({
stageRefresh: true,
});
}
}
renderStageRefreshButton() {
if (this.state.stageRefresh) {
return
}
else {
return
}
}
componentDidMount() {
this.refreshLoop();
}
componentDidUpdate() {
// prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts
if (this.state.lastRender === null || (Date.now() - this.state.lastRender) >= 1000 || (this.state.ended && !this.state.renderingEnded)) {
const renderTimestamp = Date.now();
$('#scheduled-time-rate-sparkline').sparkline(this.state.scheduledTimeRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {
chartRangeMin: 0,
numberFormatter: precisionRound
}));
$('#cpu-time-rate-sparkline').sparkline(this.state.cpuTimeRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {chartRangeMin: 0, numberFormatter: precisionRound}));
$('#row-input-rate-sparkline').sparkline(this.state.rowInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {numberFormatter: formatCount}));
$('#byte-input-rate-sparkline').sparkline(this.state.byteInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {numberFormatter: formatDataSize}));
$('#reserved-memory-sparkline').sparkline(this.state.reservedMemory, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {numberFormatter: formatDataSize}));
$('#physical-input-rate-sparkline').sparkline(this.state.physicalInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {numberFormatter: formatDataSize}));
if (this.state.lastRender === null) {
$('#query').each((i, block) => {
hljs.highlightBlock(block);
});
$('#prepared-query').each((i, block) => {
hljs.highlightBlock(block);
});
}
this.setState({
renderingEnded: this.state.ended,
lastRender: renderTimestamp,
});
}
$('[data-toggle="tooltip"]').tooltip();
new window.ClipboardJS('.copy-button');
}
renderStages(taskRetriesEnabled) {
if (this.state.lastSnapshotStage === null) {
return;
}
return (
Stages
{this.renderStageRefreshButton()}
);
}
renderPreparedQuery() {
const query = this.state.query;
if (!query.hasOwnProperty('preparedQuery') || query.preparedQuery === null) {
return;
}
return (
);
}
renderSessionProperties() {
const query = this.state.query;
const properties = [];
for (let property in query.session.systemProperties) {
if (query.session.systemProperties.hasOwnProperty(property)) {
properties.push(
- {property + "=" + query.session.systemProperties[property]}
);
}
}
for (let catalog in query.session.catalogProperties) {
if (query.session.catalogProperties.hasOwnProperty(catalog)) {
for (let property in query.session.catalogProperties[catalog]) {
if (query.session.catalogProperties[catalog].hasOwnProperty(property)) {
properties.push(
- {catalog + "." + property + "=" + query.session.catalogProperties[catalog][property]}
);
}
}
}
}
return properties;
}
renderResourceEstimates() {
const query = this.state.query;
const estimates = query.session.resourceEstimates;
const renderedEstimates = [];
for (let resource in estimates) {
if (estimates.hasOwnProperty(resource)) {
const upperChars = resource.match(/([A-Z])/g) || [];
let snakeCased = resource;
for (let i = 0, n = upperChars.length; i < n; i++) {
snakeCased = snakeCased.replace(new RegExp(upperChars[i]), '_' + upperChars[i].toLowerCase());
}
renderedEstimates.push(
- {snakeCased + "=" + query.session.resourceEstimates[resource]}
)
}
}
return renderedEstimates;
}
renderWarningInfo() {
const query = this.state.query;
if (query.warnings.length > 0) {
return (
Warnings
{query.warnings.map((warning) =>
{warning.warningCode.name}
{warning.message}
)}
);
}
else {
return null;
}
}
renderFailureInfo() {
const query = this.state.query;
if (query.failureInfo) {
return (
);
}
else {
return "";
}
}
render() {
const query = this.state.query;
if (query === null || this.state.initialized === false) {
let label = (Loading...);
if (this.state.initialized) {
label = "Query not found";
}
return (
{label}
);
}
const taskRetriesEnabled = query.retryPolicy == "TASK";
return (
Session
User
{query.session.user}
Principal
{query.session.principal}
Source
{query.session.source}
Catalog
{query.session.catalog}
Schema
{query.session.schema}
Time zone
{query.session.timeZone}
Client Address
{query.session.remoteUserAddress}
Client Tags
{query.session.clientTags.join(", ")}
Session Properties
{this.renderSessionProperties()}
Resource Estimates
{this.renderResourceEstimates()}
Execution
Resource Group
{query.resourceGroupId ? query.resourceGroupId.join(".") : "n/a"}
Submission Time
{formatShortDateTime(new Date(query.queryStats.createTime))}
Completion Time
{query.queryStats.endTime ? formatShortDateTime(new Date(query.queryStats.endTime)) : ""}
Elapsed Time
{query.queryStats.elapsedTime}
Queued Time
{query.queryStats.queuedTime}
Analysis Time
{query.queryStats.analysisTime}
Planning Time
{query.queryStats.planningTime}
Execution Time
{query.queryStats.executionTime}
Resource Utilization Summary
CPU Time
{query.queryStats.totalCpuTime}
{taskRetriesEnabled &&
{query.queryStats.failedCpuTime}
}
Planning CPU Time
{query.queryStats.planningCpuTime}
Scheduled Time
{query.queryStats.totalScheduledTime}
{taskRetriesEnabled &&
{query.queryStats.failedScheduledTime}
}
Input Rows
{formatCount(query.queryStats.processedInputPositions)}
{taskRetriesEnabled &&
{query.queryStats.failedProcessedInputPositions}
}
Input Data
{parseAndFormatDataSize(query.queryStats.processedInputDataSize)}
{taskRetriesEnabled &&
{query.queryStats.failedProcessedInputDataSize}
}
Physical Input Rows
{formatCount(query.queryStats.physicalInputPositions)}
{taskRetriesEnabled &&
{formatCount(query.queryStats.failedPhysicalInputPositions)}
}
Physical Input Data
{parseAndFormatDataSize(query.queryStats.physicalInputDataSize)}
{taskRetriesEnabled &&
{parseAndFormatDataSize(query.queryStats.failedPhysicalInputDataSize)}
}
Physical Input Read Time
{query.queryStats.physicalInputReadTime}
{taskRetriesEnabled &&
{query.queryStats.failedPhysicalInputReadTime}
}
Internal Network Rows
{formatCount(query.queryStats.internalNetworkInputPositions)}
{taskRetriesEnabled &&
{formatCount(query.queryStats.failedInternalNetworkInputPositions)}
}
Internal Network Data
{parseAndFormatDataSize(query.queryStats.internalNetworkInputDataSize)}
{taskRetriesEnabled &&
{parseAndFormatDataSize(query.queryStats.failedInternalNetworkInputDataSize)}
}
Peak User Memory
{parseAndFormatDataSize(query.queryStats.peakUserMemoryReservation)}
{parseDataSize(query.queryStats.peakRevocableMemoryReservation) > 0 &&
Peak Revocable Memory
{parseAndFormatDataSize(query.queryStats.peakRevocableMemoryReservation)}
}
Peak Total Memory
{parseAndFormatDataSize(query.queryStats.peakTotalMemoryReservation)}
Cumulative User Memory
{formatDataSize(query.queryStats.cumulativeUserMemory / 1000.0) + "*seconds"}
{taskRetriesEnabled &&
{formatDataSize(query.queryStats.failedCumulativeUserMemory / 1000.0) + "*seconds"}
}
Output Rows
{formatCount(query.queryStats.outputPositions)}
{taskRetriesEnabled &&
{formatCount(query.queryStats.failedOutputPositions)}
}
Output Data
{parseAndFormatDataSize(query.queryStats.outputDataSize)}
{taskRetriesEnabled &&
{parseAndFormatDataSize(query.queryStats.failedOutputDataSize)}
}
Written Rows
{formatCount(query.queryStats.writtenPositions)}
Logical Written Data
{parseAndFormatDataSize(query.queryStats.logicalWrittenDataSize)}
Physical Written Data
{parseAndFormatDataSize(query.queryStats.physicalWrittenDataSize)}
{taskRetriesEnabled &&
{parseAndFormatDataSize(query.queryStats.failedPhysicalWrittenDataSize)}
}
{parseDataSize(query.queryStats.spilledDataSize) > 0 &&
Spilled Data
{parseAndFormatDataSize(query.queryStats.spilledDataSize)}
}
Timeline
Parallelism
Loading ...
{formatCount(this.state.cpuTimeRate[this.state.cpuTimeRate.length - 1])}
Scheduled Time/s
Loading ...
{formatCount(this.state.scheduledTimeRate[this.state.scheduledTimeRate.length - 1])}
Input Rows/s
Loading ...
{formatCount(this.state.rowInputRate[this.state.rowInputRate.length - 1])}
Input Bytes/s
Loading ...
{formatDataSize(this.state.byteInputRate[this.state.byteInputRate.length - 1])}
Physical Input Bytes/s
Loading ...
{formatDataSize(this.state.physicalInputRate[this.state.physicalInputRate.length - 1])}
Memory Utilization
Loading ...
{formatDataSize(this.state.reservedMemory[this.state.reservedMemory.length - 1])}
{this.renderWarningInfo()}
{this.renderFailureInfo()}
{this.renderStages(taskRetriesEnabled)}
);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy