Skip to content

Commit 5808825

Browse files
dongjoon-hyunIvanK-db
authored andcommitted
[SPARK-49206][CORE][UI] Add Environment Variables table to Master EnvironmentPage
### What changes were proposed in this pull request? This PR aims to add `Environment Variables` table to Master `EnvironmentPage` via a new configuration, `spark.master.ui.visibleEnvVarPrefixes`. ### Why are the changes needed? To allow users to expose and show the environment variables of Spark Master. ### Does this PR introduce _any_ user-facing change? Yes, but this is a new table on `Spark Master` UI's `EnvironmentPage`. ### How was this patch tested? Pass the CIs with newly added test case. **DEFAULT** ``` $ sbin/start-master.sh ``` ![Screenshot 2024-08-12 at 00 53 26](https://github.com/user-attachments/assets/b7929536-a25d-4bd5-876d-908ed7403b92) **Expose `AWS_`** ``` $ AWS_CA_BUNDLE=/tmp/root-ca.pem \ AWS_ENDPOINT_URL=https://s3express-usw2-az1.us-west-2.amazonaws.com \ SPARK_MASTER_OPTS="-Dspark.master.ui.visibleEnvVarPrefixes=AWS_" \ sbin/start-master.sh ``` ![Screenshot 2024-08-12 at 01 05 25](https://github.com/user-attachments/assets/50a57ba1-8ed8-4827-ad51-b303da09a663) ### Was this patch authored or co-authored using generative AI tooling? No. Closes apache#47714 from dongjoon-hyun/SPARK-49206. Authored-by: Dongjoon Hyun <[email protected]> Signed-off-by: yangjie01 <[email protected]>
1 parent 6dcb66c commit 5808825

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

core/src/main/resources/org/apache/spark/ui/static/webui.js

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ $(function() {
7575
collapseTablePageLoad('collapse-aggregated-systemProperties','aggregated-systemProperties');
7676
collapseTablePageLoad('collapse-aggregated-metricsProperties','aggregated-metricsProperties');
7777
collapseTablePageLoad('collapse-aggregated-classpathEntries','aggregated-classpathEntries');
78+
collapseTablePageLoad('collapse-aggregated-environmentVariables','aggregated-environmentVariables');
7879
collapseTablePageLoad('collapse-aggregated-activeJobs','aggregated-activeJobs');
7980
collapseTablePageLoad('collapse-aggregated-completedJobs','aggregated-completedJobs');
8081
collapseTablePageLoad('collapse-aggregated-failedJobs','aggregated-failedJobs');

core/src/main/scala/org/apache/spark/deploy/master/ui/EnvironmentPage.scala

+18
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717

1818
package org.apache.spark.deploy.master.ui
1919

20+
import scala.jdk.CollectionConverters._
2021
import scala.xml.Node
2122

2223
import jakarta.servlet.http.HttpServletRequest
2324

2425
import org.apache.spark.{SparkConf, SparkEnv}
2526
import org.apache.spark.deploy.SparkHadoopUtil
27+
import org.apache.spark.internal.config.UI.MASTER_UI_VISIBLE_ENV_VAR_PREFIXES
2628
import org.apache.spark.ui._
2729
import org.apache.spark.util.Utils
2830

@@ -39,6 +41,9 @@ private[ui] class EnvironmentPage(
3941
val systemProperties = Utils.redact(conf, details("System Properties")).sorted
4042
val metricsProperties = Utils.redact(conf, details("Metrics Properties")).sorted
4143
val classpathEntries = details("Classpath Entries").sorted
44+
val prefixes = conf.get(MASTER_UI_VISIBLE_ENV_VAR_PREFIXES)
45+
val environmentVariables = System.getenv().asScala
46+
.filter { case (k, _) => prefixes.exists(k.startsWith(_)) }.toSeq.sorted
4247

4348
val runtimeInformationTable = UIUtils.listingTable(propertyHeader, propertyRow,
4449
jvmInformation, fixedWidth = true, headerClasses = headerClasses)
@@ -52,6 +57,8 @@ private[ui] class EnvironmentPage(
5257
metricsProperties, fixedWidth = true, headerClasses = headerClasses)
5358
val classpathEntriesTable = UIUtils.listingTable(classPathHeader, classPathRow,
5459
classpathEntries, fixedWidth = true, headerClasses = headerClasses)
60+
val environmentVariablesTable = UIUtils.listingTable(propertyHeader, propertyRow,
61+
environmentVariables, fixedWidth = true, headerClasses = headerClasses)
5562

5663
val content =
5764
<div>
@@ -124,6 +131,17 @@ private[ui] class EnvironmentPage(
124131
<div class="aggregated-classpathEntries collapsible-table collapsed">
125132
{classpathEntriesTable}
126133
</div>
134+
<span class="collapse-aggregated-environmentVariables collapse-table"
135+
onClick="collapseTable('collapse-aggregated-environmentVariables',
136+
'aggregated-environmentVariables')">
137+
<h4>
138+
<span class="collapse-table-arrow arrow-closed"></span>
139+
<a>Environment Variables</a>
140+
</h4>
141+
</span>
142+
<div class="aggregated-environmentVariables collapsible-table collapsed">
143+
{environmentVariablesTable}
144+
</div>
127145
</span>
128146
UIUtils.basicSparkPage(request, content, "Environment")
129147
}

core/src/main/scala/org/apache/spark/internal/config/UI.scala

+7
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@ private[spark] object UI {
251251
.stringConf
252252
.createOptional
253253

254+
val MASTER_UI_VISIBLE_ENV_VAR_PREFIXES = ConfigBuilder("spark.master.ui.visibleEnvVarPrefixes")
255+
.doc("Comma-separated list of key-prefix strings to show environment variables")
256+
.version("4.0.0")
257+
.stringConf
258+
.toSequence
259+
.createWithDefault(Seq.empty[String])
260+
254261
val UI_SQL_GROUP_SUB_EXECUTION_ENABLED = ConfigBuilder("spark.ui.groupSQLSubExecutionEnabled")
255262
.doc("Whether to group sub executions together in SQL UI when they belong to the same " +
256263
"root execution")

core/src/test/scala/org/apache/spark/deploy/master/ui/ReadOnlyMasterWebUISuite.scala

+11
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.apache.spark.{SecurityManager, SparkConf, SparkFunSuite}
2626
import org.apache.spark.deploy.master._
2727
import org.apache.spark.deploy.master.ui.MasterWebUISuite._
2828
import org.apache.spark.internal.config.DECOMMISSION_ENABLED
29+
import org.apache.spark.internal.config.UI.MASTER_UI_VISIBLE_ENV_VAR_PREFIXES
2930
import org.apache.spark.internal.config.UI.UI_KILL_ENABLED
3031
import org.apache.spark.rpc.{RpcEndpointRef, RpcEnv}
3132
import org.apache.spark.util.Utils
@@ -35,6 +36,7 @@ class ReadOnlyMasterWebUISuite extends SparkFunSuite {
3536
val conf = new SparkConf()
3637
.set(UI_KILL_ENABLED, false)
3738
.set(DECOMMISSION_ENABLED, false)
39+
.set(MASTER_UI_VISIBLE_ENV_VAR_PREFIXES.key, "SPARK_SCALA_")
3840
val securityMgr = new SecurityManager(conf)
3941
val rpcEnv = mock(classOf[RpcEnv])
4042
val master = mock(classOf[Master])
@@ -86,4 +88,13 @@ class ReadOnlyMasterWebUISuite extends SparkFunSuite {
8688
assert(result.contains("Spark Properties"))
8789
assert(result.contains("Hadoop Properties"))
8890
}
91+
92+
test("SPARK-49206: Add 'Environment Variables' table to Master 'EnvironmentPage'") {
93+
val url = s"http://${Utils.localHostNameForURI()}:${masterWebUI.boundPort}/environment/"
94+
val conn = sendHttpRequest(url, "GET", "")
95+
assert(conn.getResponseCode === SC_OK)
96+
val result = Source.fromInputStream(conn.getInputStream).mkString
97+
assert(result.contains("Environment Variables"))
98+
assert(result.contains("<tr><td>SPARK_SCALA_VERSION</td><td>2.1"))
99+
}
89100
}

0 commit comments

Comments
 (0)