blob: 0951cfc66df5624926f371510f852b2d4ccd359b [file] [log] [blame]
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
-->
<nz-tabset
*ngIf="checkPointStats"
[nzSize]="'small'"
[nzAnimated]="{ inkBar: true, tabPane: false }"
[nzTabBarExtraContent]="extraTemplate"
>
<nz-tab nzTitle="Overview">
<nz-table
class="no-border small"
[nzData]="checkPointStats['latest'] ? [''] : []"
[nzSize]="'small'"
[nzFrontPagination]="false"
[nzShowPagination]="false"
>
<tbody>
<ng-container *ngIf="checkPointStats['latest'] && checkPointStats['counts']">
<tr>
<td><strong>Checkpoint Counts</strong></td>
<td>
<span>
<strong>Triggered:</strong>
{{ checkPointStats['counts']['total'] }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>In Progress:</strong>
{{ checkPointStats['counts']['in_progress'] }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Completed:</strong>
{{ checkPointStats['counts']['completed'] }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Failed:</strong>
{{ checkPointStats['counts']['failed'] }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Restored:</strong>
{{ checkPointStats['counts']['restored'] }}
</span>
</td>
</tr>
<tr>
<td><strong>Latest Completed Checkpoint</strong></td>
<td *ngIf="checkPointStats['latest']['completed']">
<span>
<strong>ID:</strong>
{{ checkPointStats['latest']['completed']['id'] }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Completion Time:</strong>
{{
checkPointStats['latest']['completed']['latest_ack_timestamp']
| date: 'yyyy-MM-dd HH:mm:ss'
}}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>End to End Duration:</strong>
{{
checkPointStats['latest']['completed']['end_to_end_duration'] | humanizeDuration
}}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Checkpointed Data Size:</strong>
{{ checkPointStats['latest']['completed']['checkpointed_size'] | humanizeBytes }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Full Checkpoint Data Size:</strong>
{{ checkPointStats['latest']['completed']['state_size'] | humanizeBytes }}
</span>
</td>
<td *ngIf="!checkPointStats['latest']['completed']">None</td>
</tr>
<tr *ngIf="checkPointStats['latest']['completed']">
<td colspan="2" class="collapse-td">
<flink-job-checkpoints-detail
[checkPoint]="checkPointStats['latest']['completed']"
></flink-job-checkpoints-detail>
</td>
</tr>
<tr>
<td><strong>Latest Failed Checkpoint</strong></td>
<td *ngIf="checkPointStats['latest']['failed']">
<span>
<strong>ID:</strong>
{{ checkPointStats['latest']['failed']['id'] }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Failure Time:</strong>
{{
checkPointStats['latest']['failed']['failure_timestamp']
| date: 'yyyy-MM-dd HH:mm:ss'
}}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong *ngIf="checkPointStats['latest']['failed']['failure_message']">
Cause:
</strong>
{{ checkPointStats['latest']['failed']['failure_message'] }}
</span>
<span *ngIf="!checkPointStats['latest']['failed']['failure_message']">
<strong>Cause:</strong>
n/a
</span>
</td>
<td *ngIf="!checkPointStats['latest']['failed']">None</td>
</tr>
<tr *ngIf="checkPointStats['latest']['failed']">
<td colspan="2" class="collapse-td">
<flink-job-checkpoints-detail
[checkPoint]="checkPointStats['latest']['failed']"
></flink-job-checkpoints-detail>
</td>
</tr>
<tr>
<td><strong>Latest Savepoint</strong></td>
<td *ngIf="checkPointStats['latest']['savepoint']">
<span>
<strong>ID:</strong>
{{ checkPointStats['latest']['savepoint']['id'] }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Completion Time:</strong>
{{
checkPointStats['latest']['savepoint']['latest_ack_timestamp']
| date: 'yyyy-MM-dd HH:mm:ss'
}}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Checkpointed Data Size:</strong>
{{ checkPointStats['latest']['completed']['checkpointed_size'] | humanizeBytes }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Full Checkpoint Data Size:</strong>
{{ checkPointStats['latest']['savepoint']['state_size'] | humanizeBytes }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Path:</strong>
{{ checkPointStats['latest']['savepoint']['external_path'] }}
</span>
</td>
<td *ngIf="!checkPointStats['latest']['savepoint']">None</td>
</tr>
<tr *ngIf="checkPointStats['latest']['savepoint']">
<td colspan="2" class="collapse-td">
<flink-job-checkpoints-detail
[checkPoint]="checkPointStats['latest']['savepoint']"
></flink-job-checkpoints-detail>
</td>
</tr>
<tr>
<td><strong>Latest Restore</strong></td>
<td *ngIf="checkPointStats['latest']['restored']">
<span>
<strong>ID:</strong>
{{ checkPointStats['latest']['restored']['id'] }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong>Restore Time:</strong>
{{
checkPointStats['latest']['restored']['restore_timestamp']
| date: 'yyyy-MM-dd HH:mm:ss'
}}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span *ngIf="checkPointStats['latest']['restored']['is_savepoint']">
<strong>Type:</strong>
Savepoint
</span>
<span *ngIf="!checkPointStats['latest']['restored']['is_savepoint']">
<strong>Type:</strong>
Checkpoint
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
<strong *ngIf="checkPointStats['latest']['restored']['external_path']">
Path:
</strong>
{{ checkPointStats['latest']['restored']['external_path'] }}
</span>
</td>
<td *ngIf="!checkPointStats['latest']['restored']">None</td>
</tr>
</ng-container>
</tbody>
</nz-table>
</nz-tab>
<nz-tab nzTitle="History">
<nz-table
class="no-border small"
[nzSize]="'small'"
[nzData]="checkPointStats['history'] || []"
[nzFrontPagination]="false"
[nzShowPagination]="false"
>
<thead>
<tr>
<th nzWidth="70px"></th>
<th><strong>ID</strong></th>
<th><strong>Status</strong></th>
<th><strong>Acknowledged</strong></th>
<th><strong>Trigger Time</strong></th>
<th><strong>Latest Acknowledgement</strong></th>
<th><strong>End to End Duration</strong></th>
<th>
<strong>
Checkpointed Data Size
<i
class="header-icon"
nz-icon
nz-tooltip
nzTooltipTitle="The size of data persisted during the sync and async phases of a checkpoint. It's usually smaller than Full checkpoint data size if incremental checkpoints or changelog is enabled."
nzType="info-circle"
></i>
</strong>
</th>
<th><strong>Full Checkpoint Data Size</strong></th>
<th><strong>Processed (persisted) in-flight data</strong></th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let checkpoint of checkPointStats['history']; trackBy: trackById">
<tr>
<td nzShowExpand [(nzExpand)]="checkpoint.expand"></td>
<td>{{ checkpoint['id'] }}</td>
<td>
<flink-checkpoint-badge [state]="checkpoint['status']">
{{ checkpoint['status'] }}
<em *ngIf="checkpoint['is_savepoint']">[Savepoint]</em>
</flink-checkpoint-badge>
</td>
<td>
{{ checkpoint['num_acknowledged_subtasks'] }}/{{ checkpoint['num_subtasks'] }}
<span *ngIf="checkpoint['status'] === 'IN_PROGRESS'">
({{
checkpoint['num_acknowledged_subtasks'] / checkpoint['num_subtasks'] | percent
}})
</span>
</td>
<td>{{ checkpoint['trigger_timestamp'] | date: 'yyyy-MM-dd HH:mm:ss' }}</td>
<td *ngIf="checkpoint['latest_ack_timestamp'] >= 0">
{{ checkpoint['latest_ack_timestamp'] | date: 'yyyy-MM-dd HH:mm:ss' }}
</td>
<td *ngIf="checkpoint['latest_ack_timestamp'] < 0">n/a</td>
<td *ngIf="checkpoint['end_to_end_duration'] >= 0">
{{ checkpoint['end_to_end_duration'] | humanizeDuration }}
</td>
<td *ngIf="checkpoint['end_to_end_duration'] < 0">n/a</td>
<td>{{ checkpoint['checkpointed_size'] | humanizeBytes }}</td>
<td>{{ checkpoint['state_size'] | humanizeBytes }}</td>
<td>
{{ checkpoint['processed_data'] | humanizeBytes }} ({{
checkpoint['persisted_data'] | humanizeBytes
}})
</td>
</tr>
<tr [nzExpand]="checkpoint.expand">
<td colspan="11" *ngIf="checkpoint.expand" class="collapse-td">
<flink-job-checkpoints-detail
[checkPoint]="checkpoint"
></flink-job-checkpoints-detail>
</td>
</tr>
</ng-container>
</tbody>
</nz-table>
</nz-tab>
<nz-tab nzTitle="Summary">
<nz-table
*ngIf="checkPointStats"
class="no-border small"
[nzData]="checkPointStats && checkPointStats['summary'] ? [''] : []"
[nzSize]="'small'"
[nzFrontPagination]="false"
[nzShowPagination]="false"
>
<thead>
<tr>
<th></th>
<th><strong>End to End Duration</strong></th>
<th>
<strong>
Checkpointed Data Size
<i
class="header-icon"
nz-icon
nz-tooltip
nzTooltipTitle="The size of data persisted during the sync and async phases of a checkpoint. It's usually smaller than Full checkpoint data size if incremental checkpoints or changelog is enabled"
nzType="info-circle"
></i>
</strong>
</th>
<th><strong>Full Checkpoint Data Size</strong></th>
<th><strong>Processed (persisted) in-flight data</strong></th>
</tr>
</thead>
<tbody>
<ng-container *ngIf="checkPointStats['summary']">
<tr>
<td><strong>Minimum</strong></td>
<td>
{{ checkPointStats['summary']['end_to_end_duration']['min'] | humanizeDuration }}
</td>
<td>
{{ checkPointStats['summary']['checkpointed_size']['min'] | humanizeBytes }}
</td>
<td>{{ checkPointStats['summary']['state_size']['min'] | humanizeBytes }}</td>
<td>
{{ checkPointStats['summary']['processed_data']['min'] | humanizeBytes }} ({{
checkPointStats['summary']['persisted_data']['min'] | humanizeBytes
}})
</td>
</tr>
<tr>
<td><strong>Average</strong></td>
<td>
{{ checkPointStats['summary']['end_to_end_duration']['avg'] | humanizeDuration }}
</td>
<td>
{{ checkPointStats['summary']['checkpointed_size']['avg'] | humanizeBytes }}
</td>
<td>{{ checkPointStats['summary']['state_size']['avg'] | humanizeBytes }}</td>
<td>
{{ checkPointStats['summary']['processed_data']['avg'] | humanizeBytes }} ({{
checkPointStats['summary']['persisted_data']['avg'] | humanizeBytes
}})
</td>
</tr>
<tr>
<td><strong>Maximum</strong></td>
<td>
{{ checkPointStats['summary']['end_to_end_duration']['max'] | humanizeDuration }}
</td>
<td>
{{ checkPointStats['summary']['checkpointed_size']['max'] | humanizeBytes }}
</td>
<td>{{ checkPointStats['summary']['state_size']['max'] | humanizeBytes }}</td>
<td>
{{ checkPointStats['summary']['processed_data']['max'] | humanizeBytes }} ({{
checkPointStats['summary']['persisted_data']['max'] | humanizeBytes
}})
</td>
</tr>
</ng-container>
</tbody>
</nz-table>
<nz-collapse>
<nz-collapse-panel
[nzHeader]="'Percentiles'"
[nzActive]="moreDetailsPanel.active"
[nzDisabled]="moreDetailsPanel.disabled"
>
<nz-table
*ngIf="checkPointStats"
class="no-border small"
[nzData]="checkPointStats && checkPointStats['summary'] ? [''] : []"
[nzSize]="'small'"
[nzFrontPagination]="false"
[nzShowPagination]="false"
>
<thead>
<tr>
<th></th>
<th><strong>End to End Duration</strong></th>
<th><strong>Checkpointed Data Size</strong></th>
<th><strong>Full Checkpoint Data Size</strong></th>
<th><strong>Processed (persisted) in-flight data</strong></th>
</tr>
</thead>
<tbody>
<ng-container *ngIf="checkPointStats['summary']">
<tr>
<td><strong>50% percentile</strong></td>
<td>
{{ checkPointStats['summary']['end_to_end_duration']['p50'] | humanizeDuration }}
</td>
<td>
{{ checkPointStats['summary']['checkpointed_size']['p50'] | humanizeBytes }}
</td>
<td>{{ checkPointStats['summary']['state_size']['p50'] | humanizeBytes }}</td>
<td>
{{ checkPointStats['summary']['processed_data']['p50'] | humanizeBytes }} ({{
checkPointStats['summary']['persisted_data']['p50'] | humanizeBytes
}})
</td>
</tr>
<tr>
<td><strong>90% percentile</strong></td>
<td>
{{ checkPointStats['summary']['end_to_end_duration']['p90'] | humanizeDuration }}
</td>
<td>
{{ checkPointStats['summary']['checkpointed_size']['p90'] | humanizeBytes }}
</td>
<td>{{ checkPointStats['summary']['state_size']['p90'] | humanizeBytes }}</td>
<td>
{{ checkPointStats['summary']['processed_data']['p90'] | humanizeBytes }} ({{
checkPointStats['summary']['persisted_data']['p90'] | humanizeBytes
}})
</td>
</tr>
<tr>
<td><strong>99% percentile</strong></td>
<td>
{{ checkPointStats['summary']['end_to_end_duration']['p99'] | humanizeDuration }}
</td>
<td>
{{ checkPointStats['summary']['checkpointed_size']['p99'] | humanizeBytes }}
</td>
<td>{{ checkPointStats['summary']['state_size']['p99'] | humanizeBytes }}</td>
<td>
{{ checkPointStats['summary']['processed_data']['p99'] | humanizeBytes }} ({{
checkPointStats['summary']['persisted_data']['p99'] | humanizeBytes
}})
</td>
</tr>
<tr>
<td><strong>99.9% percentile</strong></td>
<td>
{{ checkPointStats['summary']['end_to_end_duration']['p999'] | humanizeDuration }}
</td>
<td>
{{ checkPointStats['summary']['checkpointed_size']['p999'] | humanizeBytes }}
</td>
<td>{{ checkPointStats['summary']['state_size']['p999'] | humanizeBytes }}</td>
<td>
{{ checkPointStats['summary']['processed_data']['p999'] | humanizeBytes }} ({{
checkPointStats['summary']['persisted_data']['p999'] | humanizeBytes
}})
</td>
</tr>
</ng-container>
</tbody>
</nz-table>
</nz-collapse-panel>
</nz-collapse>
</nz-tab>
<nz-tab nzTitle="Configuration">
<nz-table
class="no-border small"
[nzData]="checkPointConfig ? [''] : []"
[nzSize]="'small'"
[nzFrontPagination]="false"
[nzShowPagination]="false"
>
<thead>
<tr>
<th><strong>Option</strong></th>
<th><strong>Value</strong></th>
</tr>
</thead>
<tbody>
<ng-container *ngIf="checkPointConfig">
<tr>
<td>Checkpointing Mode</td>
<td *ngIf="checkPointConfig['mode'] === 'exactly_once'">Exactly Once</td>
<td *ngIf="checkPointConfig['mode'] !== 'exactly_once'">At Least Once</td>
</tr>
<tr>
<td>Checkpoint Storage</td>
<td>{{ checkPointConfig['checkpoint_storage'] }}</td>
</tr>
<tr>
<td>State Backend</td>
<td>{{ checkPointConfig['state_backend'] }}</td>
</tr>
<tr>
<td>Interval</td>
<td *ngIf="checkPointConfig['interval'] === disabledInterval">
Periodic checkpoints disabled
</td>
<td *ngIf="checkPointConfig['interval'] !== disabledInterval">
{{ checkPointConfig['interval'] | humanizeDuration }}
</td>
</tr>
<tr>
<td>Timeout</td>
<td>{{ checkPointConfig['timeout'] | humanizeDuration }}</td>
</tr>
<tr>
<td>Minimum Pause Between Checkpoints</td>
<td>{{ checkPointConfig['min_pause'] | humanizeDuration }}</td>
</tr>
<tr>
<td>Maximum Concurrent Checkpoints</td>
<td>{{ checkPointConfig['max_concurrent'] }}</td>
</tr>
<tr>
<td>Unaligned Checkpoints</td>
<td>{{ checkPointConfig['unaligned_checkpoints'] ? 'Enabled' : 'Disabled' }}</td>
</tr>
<tr *ngIf="checkPointConfig['unaligned_checkpoints']">
<td>Aligned checkpoint timeout</td>
<td>{{ checkPointConfig['aligned_checkpoint_timeout'] | humanizeDuration }}</td>
</tr>
<tr *ngIf="checkPointConfig['externalization']">
<td>Persist Checkpoints Externally</td>
<td *ngIf="checkPointConfig['externalization']['enabled']">
Enabled
<span *ngIf="checkPointConfig['externalization']['delete_on_cancellation']">
(delete on cancellation)
</span>
<span *ngIf="!checkPointConfig['externalization']['delete_on_cancellation']">
(retain on cancellation)
</span>
</td>
<td *ngIf="!checkPointConfig['externalization']['enabled']">Disabled</td>
</tr>
<tr>
<td>Tolerable Failed Checkpoints</td>
<td>{{ checkPointConfig['tolerable_failed_checkpoints'] }}</td>
</tr>
<tr>
<td>Checkpoints With Finished Tasks</td>
<td>
{{ checkPointConfig['checkpoints_after_tasks_finish'] ? 'Enabled' : 'Disabled' }}
</td>
</tr>
</ng-container>
</tbody>
</nz-table>
</nz-tab>
</nz-tabset>
<ng-template #extraTemplate>
<button nz-button nzType="primary" class="refresh" nzSize="small" (click)="refresh()">
<i nz-icon nzType="sync"></i>
Refresh
</button>
</ng-template>
<nz-empty *ngIf="!checkPointStats"></nz-empty>