11"""Script for fetch and filtering Spark application logs.
22"""
33from typing import Optional
4+ from pathlib import Path
45import re
56from argparse import ArgumentParser , Namespace
67import subprocess as sp
@@ -54,6 +55,58 @@ def fetch(args):
5455 filter_ (args )
5556
5657
58+ def status (args ):
59+ """Get status of a Spark application.
60+
61+ :param args: A Namespace object containing command-line options.
62+ """
63+ if "app_id" in args :
64+ cmd = ["yarn" , "application" , "-status" , args .app_id ]
65+ sp .run (cmd , check = True )
66+ return
67+ report = """Application Report :
68+ Application-Id : {APP_ID}
69+ Application-Name : {APP_NAME}
70+ Application-Type : {APP_TYPE}
71+ User : {USER}
72+ Queue : {QUEUE}
73+ Application Priority : {PRIORITY}
74+ Start-Time : {START_TIME}
75+ Finish-Time : {FINISH_TIME}
76+ Progress : {PROGRESS}
77+ State : {STATE}
78+ Final-State : {STATUS}
79+ Tracking-URL : {URL}
80+ RPC Port : {PORT}
81+ AM Host : {HOST}
82+ Aggregate Resource Allocation : {RESOURCE}
83+ Log Aggregation Status : {LOG_STATUS}
84+ Diagnostics :
85+ Unmanaged Application : {UNMANAGED}
86+ Application Node Label Expression : {APP_NODE_LABEL}
87+ AM container Node Label Expression : {CON_NODE_LABEL}
88+ """
89+ with args .log_file .open () as fin :
90+ for line in fin :
91+ if "{APP_ID}" in report :
92+ match = re .search (r"(application_\d+_\d+)" , line )
93+ if match :
94+ report = report .replace ("{APP_ID}" , match .group ())
95+ if "{APP_NAME}" in report :
96+ match = re .search (r"--primary-py-file (.*) " , line )
97+ if match :
98+ report = report .replace ("{APP_NAME}" , match .group ())
99+ if "{USER}" in report :
100+ match = re .search (r"local/usercache/(.*)/" , line )
101+ if match :
102+ report = report .replace ("{USER}" , match .group ())
103+ if "{STATUS}" in report :
104+ match = re .search (r"Final app status: (.*)," , line )
105+ if match :
106+ report = report .replace ("{STATUS}" , match .group ())
107+ print (report )
108+
109+
57110def parse_args (args = None , namespace = None ) -> Namespace :
58111 """Parse command-line arguments.
59112
@@ -66,9 +119,24 @@ def parse_args(args=None, namespace=None) -> Namespace:
66119 subparsers = parser .add_subparsers (help = "Sub commands." )
67120 _subparser_fetch (subparsers )
68121 _subparser_filter (subparsers )
122+ _subparser_status (subparsers )
69123 return parser .parse_args (args = args , namespace = namespace )
70124
71125
126+ def _subparser_status (subparsers ):
127+ subparser_status = subparsers .add_parser (
128+ "status" , help = "filter key information from a Spark/Hive application log."
129+ )
130+ mutex_group = subparser_status .add_mutually_exclusive_group (required = True )
131+ mutex_group .add_argument (
132+ "-i" , "--id" , "--app-id" , dest = "app_id" , type = str , help = "An application ID."
133+ )
134+ mutex_group .add_argument (
135+ "-l" , "-f" , "--log-file" , dest = "log_file" , type = Path , help = "An application ID."
136+ )
137+ subparser_status .set_defaults (func = status )
138+
139+
72140def _option_filter (subparser ) -> None :
73141 subparser .add_argument (
74142 "-k" ,
0 commit comments