Spark Web UI integration for monitoring thrift server sessions, queries, performance metrics, and comprehensive operational visibility.
Main web UI tab providing thrift server overview and session management interface.
/**
* Spark Web UI tab for thrift server monitoring
* Provides overview of sessions, queries, and server statistics
*/
class ThriftServerTab(
store: HiveThriftServer2AppStatusStore,
sparkUI: SparkUI
) extends SparkUITab(sparkUI, "sqlserver") {
/**
* Detach the tab from the Spark UI
* Called during server shutdown for cleanup
*/
def detach(): Unit
/**
* Get the Spark UI instance for a given SparkContext
* @param sparkContext The SparkContext to get UI for
* @return SparkUI instance if available
*/
def getSparkUI(sparkContext: SparkContext): SparkUI
}UI Tab Features:
Main overview page displaying thrift server statistics and session list.
/**
* Main thrift server page showing overview and active sessions
*/
class ThriftServerPage(parent: ThriftServerTab) extends WebUIPage("") {
/**
* Render the main thrift server page
* @param request HTTP request object
* @return Sequence of HTML nodes representing the page content
*/
def render(request: HttpServletRequest): Seq[Node]
}Page Content:
<!-- Server Overview Section -->
<div id="server-overview">
<h4>Thrift Server Information</h4>
<table>
<tr><td>Server Version</td><td>Spark 3.5.6</td></tr>
<tr><td>Start Time</td><td>2023-01-15 10:30:00</td></tr>
<tr><td>Active Sessions</td><td>5</td></tr>
<tr><td>Total Sessions</td><td>127</td></tr>
<tr><td>Port</td><td>10000</td></tr>
<tr><td>Transport Mode</td><td>Binary</td></tr>
</table>
</div>
<!-- Active Sessions Table -->
<table id="active-sessions">
<thead>
<tr>
<th>Session ID</th>
<th>User</th>
<th>IP Address</th>
<th>Start Time</th>
<th>Last Access</th>
<th>Total Statements</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<!-- Session rows populated dynamically -->
</tbody>
</table>Detailed session view showing individual session information and query history.
/**
* Detailed session page showing session info and statement history
*/
class ThriftServerSessionPage(parent: ThriftServerTab) extends WebUIPage("session") {
/**
* Render the session detail page
* @param request HTTP request containing session ID parameter
* @return Sequence of HTML nodes representing the session details
*/
def render(request: HttpServletRequest): Seq[Node]
}Session Detail Content:
<!-- Session Information -->
<div id="session-info">
<h4>Session Details</h4>
<table>
<tr><td>Session ID</td><td>abc123-session-456</td></tr>
<tr><td>User Name</td><td>analytics_user</td></tr>
<tr><td>Client IP</td><td>192.168.1.100</td></tr>
<tr><td>Protocol Version</td><td>HIVE_CLI_SERVICE_PROTOCOL_V10</td></tr>
<tr><td>Start Time</td><td>2023-01-15 10:45:23</td></tr>
<tr><td>Last Activity</td><td>2023-01-15 14:30:15</td></tr>
<tr><td>Total Statements</td><td>23</td></tr>
<tr><td>Current Database</td><td>sales_analytics</td></tr>
</table>
</div>
<!-- Statement History -->
<table id="statement-history">
<thead>
<tr>
<th>Statement ID</th>
<th>Statement</th>
<th>State</th>
<th>Start Time</th>
<th>Duration</th>
<th>Exception</th>
</tr>
</thead>
<tbody>
<!-- Statement history rows -->
</tbody>
</table>Event listener that captures thrift server events for UI display and metrics collection.
/**
* Event listener for thrift server events
* Captures session and statement events for UI display
*/
class HiveThriftServer2Listener(
kvStore: ElementTrackingStore,
conf: SparkConf,
server: Option[HiveThriftServer2]
) extends SparkListener {
/**
* Handle session opened events
* @param event Session opened event details
*/
def onSessionOpened(event: SparkListenerThriftServerSessionCreated): Unit
/**
* Handle session closed events
* @param event Session closed event details
*/
def onSessionClosed(event: SparkListenerThriftServerSessionClosed): Unit
/**
* Handle statement start events
* @param event Statement start event details
*/
def onStatementStart(event: SparkListenerThriftServerStatementStart): Unit
/**
* Handle statement finish events
* @param event Statement finish event details
*/
def onStatementFinish(event: SparkListenerThriftServerStatementFinish): Unit
/**
* Handle statement parsing events
* @param event Statement parsing event details
*/
def onStatementParsed(event: SparkListenerThriftServerStatementParsed): Unit
}Event Processing Examples:
// Session lifecycle events
case class SparkListenerThriftServerSessionCreated(
sessionId: String,
userName: String,
ipAddress: String,
creationTime: Long
)
case class SparkListenerThriftServerSessionClosed(
sessionId: String,
closureTime: Long
)
// Statement execution events
case class SparkListenerThriftServerStatementStart(
statementId: String,
sessionId: String,
statement: String,
startTime: Long
)
case class SparkListenerThriftServerStatementFinish(
statementId: String,
finishTime: Long,
executionTime: Long,
exception: Option[String]
)Application status store managing thrift server data for UI display.
/**
* Status store for thrift server application data
* Manages session and statement information for UI display
*/
class HiveThriftServer2AppStatusStore(store: ElementTrackingStore) {
/**
* Get session information by session ID
* @param sessionId Session identifier
* @return Optional session information
*/
def getSession(sessionId: String): Option[SessionInfo]
/**
* Get all active sessions
* @return Sequence of active session information
*/
def getActiveSessions(): Seq[SessionInfo]
/**
* Get statement information for a session
* @param sessionId Session identifier
* @return Sequence of statement information
*/
def getStatements(sessionId: String): Seq[StatementInfo]
/**
* Get server statistics
* @return Server statistics including session counts and timing
*/
def getServerStats(): ServerStats
}Event manager coordinating thrift server events and UI updates.
/**
* Event manager for thrift server events
* Coordinates event processing and UI updates
*/
class HiveThriftServer2EventManager(sparkContext: SparkContext) {
/**
* Post session creation event
* @param sessionId Session identifier
* @param userName User name
* @param ipAddress Client IP address
*/
def onSessionCreated(sessionId: String, userName: String, ipAddress: String): Unit
/**
* Post session closure event
* @param sessionId Session identifier
*/
def onSessionClosed(sessionId: String): Unit
/**
* Post statement execution start event
* @param statementId Statement identifier
* @param sessionId Session identifier
* @param statement SQL statement text
*/
def onStatementStart(statementId: String, sessionId: String, statement: String): Unit
/**
* Post statement execution finish event
* @param statementId Statement identifier
* @param exception Optional exception if statement failed
*/
def onStatementFinish(statementId: String, exception: Option[String]): Unit
}Comprehensive data models for UI display and event tracking.
/**
* Session information for UI display
*/
case class SessionInfo(
sessionId: String,
userName: String,
ipAddress: String,
creationTime: Long,
lastAccessTime: Long,
totalStatements: Int,
isActive: Boolean
) {
def duration: Long = System.currentTimeMillis() - creationTime
def idleTime: Long = System.currentTimeMillis() - lastAccessTime
}
/**
* Statement information for UI display
*/
case class StatementInfo(
statementId: String,
sessionId: String,
statement: String,
state: String,
startTime: Long,
finishTime: Option[Long],
exception: Option[String]
) {
def duration: Option[Long] = finishTime.map(_ - startTime)
def isComplete: Boolean = finishTime.isDefined
}
/**
* Server statistics for overview display
*/
case class ServerStats(
startTime: Long,
totalSessions: Int,
activeSessions: Int,
totalStatements: Long,
avgSessionDuration: Double,
avgStatementDuration: Double
)Integration with Spark History Server for historical thrift server data analysis.
/**
* History server plugin for thrift server data
* Enables analysis of historical thrift server usage
*/
class HiveThriftServer2HistoryServerPlugin extends AppHistoryServerPlugin {
/**
* Create UI components for history server
* @param store Application status store
* @param appId Application identifier
* @param attemptId Application attempt identifier
* @return Sequence of UI tabs for history display
*/
def createAppUI(
store: ApplicationStatusStore,
appId: String,
attemptId: Option[String]
): Seq[SparkUITab]
/**
* Get display name for the plugin
* @return Plugin display name
*/
def displayName: String = "Thrift Server"
}Configuration options for customizing the thrift server UI behavior.
// UI configuration parameters
val UI_ENABLED = "spark.ui.enabled" // Enable/disable Spark UI
val THRIFT_SERVER_UI_PORT = "spark.ui.port" // UI port (default: 4040)
val THRIFT_SERVER_UI_RETAINED_SESSIONS = "spark.sql.thriftServer.ui.retainedSessions" // Number of sessions to retain
val THRIFT_SERVER_UI_RETAINED_STATEMENTS = "spark.sql.thriftServer.ui.retainedStatements" // Number of statements to retain per session
// Default configuration values
spark.sql.thriftServer.ui.retainedSessions = 200
spark.sql.thriftServer.ui.retainedStatements = 200
spark.ui.retainedJobs = 1000
spark.ui.retainedStages = 1000Configuration Examples:
# Start thrift server with custom UI settings
spark-submit --class org.apache.spark.sql.hive.thriftserver.HiveThriftServer2 \
--conf spark.ui.port=4041 \
--conf spark.sql.thriftServer.ui.retainedSessions=500 \
--conf spark.sql.thriftServer.ui.retainedStatements=1000 \
spark-hive-thriftserver_2.12-3.5.6.jarAccess to comprehensive monitoring data through the UI and programmatic interfaces.
// Metrics available through UI
case class ThriftServerMetrics(
// Session metrics
activeSessionCount: Int,
totalSessionCount: Long,
sessionCreationRate: Double,
avgSessionDuration: Duration,
// Statement metrics
activeStatementCount: Int,
totalStatementCount: Long,
statementExecutionRate: Double,
avgStatementDuration: Duration,
// Error metrics
failedStatementCount: Long,
failedStatementRate: Double,
// Resource metrics
peakConcurrentSessions: Int,
peakConcurrentStatements: Int
)
// Access metrics programmatically
val metrics = uiTab.store.getServerStats()
println(s"Active sessions: ${metrics.activeSessions}")
println(s"Average statement duration: ${metrics.avgStatementDuration}ms")UI Access Examples:
# Access thrift server UI
http://localhost:4040/sqlserver/
# View specific session details
http://localhost:4040/sqlserver/session?id=session-123
# Access through history server
http://localhost:18080/history/app-20230115-104500/sqlserver/