Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/layouts/shortcodes/generated/cluster_configuration.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
<td>Duration</td>
<td>The shutdown timeout for cluster services like executors.</td>
</tr>
<tr>
<td><h5>cluster.thread-dump.default-mode</h5></td>
<td style="word-wrap: break-word;">FULL</td>
<td><p>Enum</p></td>
<td>Default granularity of the JobManager/TaskManager thread-dump REST endpoint when no explicit <code class="highlighter-rouge">mode</code> query parameter is supplied. The default is <code class="highlighter-rouge">FULL</code> to preserve historical behavior; operators of large clusters are strongly encouraged to switch to <code class="highlighter-rouge">LITE</code> to avoid heartbeat timeouts caused by long safepoint pauses.<br /><br />Possible values:<ul><li>"LITE": Stack traces only, without lock information. Negligible JVM pause.</li><li>"FULL": Additionally collects locked monitors and j.u.c. synchronizers, equivalent to jstack -l. Pauses the JVM in a safepoint for a duration that scales with heap size and thread count, which can take seconds on large TaskManagers.</li></ul></td>
</tr>
<tr>
<td><h5>cluster.thread-dump.stacktrace-max-depth</h5></td>
<td style="word-wrap: break-word;">50</td>
Expand Down
6 changes: 6 additions & 0 deletions docs/layouts/shortcodes/generated/expert_cluster_section.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
<td>Boolean</td>
<td>Whether processes should halt on fatal errors instead of performing a graceful shutdown. In some environments (e.g. Java 8 with the G1 garbage collector), a regular graceful shutdown can lead to a JVM deadlock. See <a href="https://issues.apache.org/jira/browse/FLINK-16510">FLINK-16510</a> for details.</td>
</tr>
<tr>
<td><h5>cluster.thread-dump.default-mode</h5></td>
<td style="word-wrap: break-word;">FULL</td>
<td><p>Enum</p></td>
<td>Default granularity of the JobManager/TaskManager thread-dump REST endpoint when no explicit <code class="highlighter-rouge">mode</code> query parameter is supplied. The default is <code class="highlighter-rouge">FULL</code> to preserve historical behavior; operators of large clusters are strongly encouraged to switch to <code class="highlighter-rouge">LITE</code> to avoid heartbeat timeouts caused by long safepoint pauses.<br /><br />Possible values:<ul><li>"LITE": Stack traces only, without lock information. Negligible JVM pause.</li><li>"FULL": Additionally collects locked monitors and j.u.c. synchronizers, equivalent to jstack -l. Pauses the JVM in a safepoint for a duration that scales with heap size and thread count, which can take seconds on large TaskManagers.</li></ul></td>
</tr>
<tr>
<td><h5>cluster.thread-dump.stacktrace-max-depth</h5></td>
<td style="word-wrap: break-word;">50</td>
Expand Down
20 changes: 20 additions & 0 deletions docs/layouts/shortcodes/generated/rest_v1_dispatcher.html
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,16 @@
<tr>
<td colspan="2">Returns the thread dump of the JobManager.</td>
</tr>
<tr>
<td colspan="2">Query parameters</td>
</tr>
<tr>
<td colspan="2">
<ul>
<li><code>mode</code> (optional): Controls how much lock information is collected. Supported values: [LITE, FULL]. When omitted, cluster.thread-dump.default-mode is used.</li>
</ul>
</td>
</tr>
<tr>
<td colspan="2">
<label>
Expand Down Expand Up @@ -7121,6 +7131,16 @@
</ul>
</td>
</tr>
<tr>
<td colspan="2">Query parameters</td>
</tr>
<tr>
<td colspan="2">
<ul>
<li><code>mode</code> (optional): Controls how much lock information is collected. Supported values: [LITE, FULL]. When omitted, cluster.thread-dump.default-mode is used.</li>
</ul>
</td>
</tr>
<tr>
<td colspan="2">
<label>
Expand Down
22 changes: 22 additions & 0 deletions docs/static/generated/rest_v1_dispatcher.yml
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,15 @@ paths:
get:
description: Returns the thread dump of the JobManager.
operationId: getJobManagerThreadDump
parameters:
- name: mode
in: query
description: "Controls how much lock information is collected. Supported values:\
\ [LITE, FULL]. When omitted, cluster.thread-dump.default-mode is used."
required: false
style: form
schema:
$ref: "#/components/schemas/ThreadDumpMode"
responses:
"200":
description: The request was successful.
Expand Down Expand Up @@ -1863,6 +1872,14 @@ paths:
required: true
schema:
$ref: "#/components/schemas/ResourceID"
- name: mode
in: query
description: "Controls how much lock information is collected. Supported values:\
\ [LITE, FULL]. When omitted, cluster.thread-dump.default-mode is used."
required: false
style: form
schema:
$ref: "#/components/schemas/ThreadDumpMode"
responses:
"200":
description: The request was successful.
Expand Down Expand Up @@ -3911,6 +3928,11 @@ components:
type: array
items:
$ref: "#/components/schemas/ThreadInfo"
ThreadDumpMode:
type: string
enum:
- LITE
- FULL
ThreadInfo:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@ public class ClusterOptions {
.withDescription(
"The maximum stacktrace depth of TaskManager and JobManager's thread dump web-frontend displayed.");

@Documentation.Section(Documentation.Sections.EXPERT_CLUSTER)
public static final ConfigOption<ThreadDumpMode> THREAD_DUMP_DEFAULT_MODE =
key("cluster.thread-dump.default-mode")
.enumType(ThreadDumpMode.class)
.defaultValue(ThreadDumpMode.FULL)
.withDescription(
Description.builder()
.text(
"Default granularity of the JobManager/TaskManager thread-dump REST endpoint "
+ "when no explicit %s query parameter is supplied. ",
code("mode"))
.text(
"The default is %s to preserve historical behavior; operators of large "
+ "clusters are strongly encouraged to switch to %s to avoid "
+ "heartbeat timeouts caused by long safepoint pauses.",
code("FULL"), code("LITE"))
.build());

@Documentation.Section(Documentation.Sections.EXPERT_CLUSTER)
public static final ConfigOption<UncaughtExceptionHandleMode> UNCAUGHT_EXCEPTION_HANDLING =
ConfigOptions.key("cluster.uncaught-exception-handling")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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.
*/

package org.apache.flink.configuration;

import org.apache.flink.annotation.PublicEvolving;
import org.apache.flink.configuration.description.InlineElement;

import static org.apache.flink.configuration.description.TextElement.text;

/**
* Granularity of the thread dump collected via {@link
* java.lang.management.ThreadMXBean#dumpAllThreads(boolean, boolean)}. Information about the lock
* each thread is currently waiting on ({@link java.lang.management.ThreadInfo#getLockInfo()}) is
* populated in both modes.
*
* @see ClusterOptions#THREAD_DUMP_DEFAULT_MODE
*/
@PublicEvolving
public enum ThreadDumpMode implements DescribedEnum {

/**
* {@code dumpAllThreads(false, false)}: stack traces only, no lock info (jstack without {@code
* -l}). Negligible JVM pause.
*/
LITE(false, false, text("Stack traces only, without lock information. Negligible JVM pause.")),

/**
* {@code dumpAllThreads(true, true)}: also collects locked monitors and j.u.c. synchronizers
* (equivalent to {@code jstack -l}). Pauses the JVM in a safepoint for a duration that scales
* with heap size and thread count -- seconds on large TaskManagers.
*/
FULL(
true,
true,
text(
"Additionally collects locked monitors and j.u.c. synchronizers, equivalent to jstack -l. "
+ "Pauses the JVM in a safepoint for a duration that scales with heap size and "
+ "thread count, which can take seconds on large TaskManagers."));

private final boolean lockedMonitors;
private final boolean lockedSynchronizers;
private final InlineElement description;

ThreadDumpMode(boolean lockedMonitors, boolean lockedSynchronizers, InlineElement description) {
this.lockedMonitors = lockedMonitors;
this.lockedSynchronizers = lockedSynchronizers;
this.description = description;
}

public boolean isLockedMonitors() {
return lockedMonitors;
}

public boolean isLockedSynchronizers() {
return lockedSynchronizers;
}

@Override
public InlineElement getDescription() {
return description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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.
*/

package org.apache.flink.configuration;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

/** Tests for {@link ClusterOptions}. */
class ClusterOptionsTest {

@Test
void testThreadDumpDefaultModeDefaultsToFull() {
assertThat(new Configuration().get(ClusterOptions.THREAD_DUMP_DEFAULT_MODE))
.isEqualTo(ThreadDumpMode.FULL);
}

@ParameterizedTest
@ValueSource(strings = {"LITE", "lite", "Lite"})
void testThreadDumpDefaultModeIsCaseInsensitive(String value) {
final Configuration configuration = new Configuration();
configuration.setString(ClusterOptions.THREAD_DUMP_DEFAULT_MODE.key(), value);

assertThat(configuration.get(ClusterOptions.THREAD_DUMP_DEFAULT_MODE))
.isEqualTo(ThreadDumpMode.LITE);
}

/**
* An unparsable value must fail fast instead of silently falling back to {@link
* ThreadDumpMode#FULL}, which is the mode operators configure this option to avoid.
*/
@ParameterizedTest
@ValueSource(strings = {"Ltie", "", " ", "none"})
void testThreadDumpDefaultModeRejectsUnknownValue(String value) {
final Configuration configuration = new Configuration();
configuration.setString(ClusterOptions.THREAD_DUMP_DEFAULT_MODE.key(), value);

assertThatThrownBy(() -> configuration.get(ClusterOptions.THREAD_DUMP_DEFAULT_MODE))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(ClusterOptions.THREAD_DUMP_DEFAULT_MODE.key())
.cause()
.hasMessageContaining(ThreadDumpMode.LITE.name())
.hasMessageContaining(ThreadDumpMode.FULL.name());
}
}
10 changes: 8 additions & 2 deletions flink-runtime-web/src/test/resources/rest_api_v1.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,10 @@
"pathParameters" : [ ]
},
"query-parameters" : {
"queryParameters" : [ ]
"queryParameters" : [ {
"key" : "mode",
"mandatory" : false
} ]
},
"request" : {
"type" : "object",
Expand Down Expand Up @@ -5429,7 +5432,10 @@
} ]
},
"query-parameters" : {
"queryParameters" : [ ]
"queryParameters" : [ {
"key" : "mode",
"mandatory" : false
} ]
},
"request" : {
"type" : "object",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,34 @@
[ngModel]="dump"
[nzEditorOption]="editorOptions"
></nz-code-editor>
<flink-addon-compact
[downloadHref]="downloadUrl"
[downloadName]="downloadName"
(reload)="reload()"
></flink-addon-compact>
<div class="thread-dump-toolbar">
<nz-space-compact class="thread-dump-mode-group">
<a
nz-button
nzSize="small"
[nzType]="mode === 'lite' ? 'primary' : 'default'"
nz-tooltip
nzTooltipTitle="Stack traces only, no lock info (jstack without -l). Negligible JVM pause."
(click)="selectMode('lite')"
>
Lite
</a>
<a
nz-button
nzSize="small"
[nzType]="mode === 'full' ? 'primary' : 'default'"
[nzDanger]="true"
nz-tooltip
nzTooltipTitle="Adds locked monitors and j.u.c. synchronizers (jstack -l). Pauses the JVM in a safepoint for a duration that scales with heap size and thread count — seconds on large JMs."
(click)="selectMode('full')"
>
Full
<i nz-icon nzType="exclamation-circle" nzTheme="fill" class="thread-dump-mode-warn"></i>
</a>
</nz-space-compact>
<flink-addon-compact
[downloadHref]="downloadUrl"
[downloadName]="downloadName"
(reload)="reload()"
></flink-addon-compact>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,25 @@
inset: 0;
}
}

.thread-dump-toolbar {
position: absolute;
top: 8px;
right: 32px;
z-index: 1;
display: flex;
gap: 8px;
align-items: center;

flink-addon-compact {
position: static;
top: auto;
right: auto;
}
}

.thread-dump-mode-group {
.thread-dump-mode-warn {
margin-left: 4px;
}
}
Loading