File tree Expand file tree Collapse file tree 3 files changed +65
-1
lines changed Expand file tree Collapse file tree 3 files changed +65
-1
lines changed Original file line number Diff line number Diff line change 88# pyre-strict
99
1010import argparse
11+ import json
1112import logging
1213import sys
1314from typing import List , Optional
@@ -46,6 +47,11 @@ def add_arguments(self, subparser: argparse.ArgumentParser) -> None:
4647 subparser .add_argument (
4748 "--roles" , type = str , default = "" , help = "comma separated roles to filter"
4849 )
50+ subparser .add_argument (
51+ "--json" ,
52+ action = "store_true" ,
53+ help = "output the status in JSON format" ,
54+ )
4955
5056 def run (self , args : argparse .Namespace ) -> None :
5157 app_handle = args .app_handle
@@ -54,7 +60,10 @@ def run(self, args: argparse.Namespace) -> None:
5460 app_status = runner .status (app_handle )
5561 filter_roles = parse_list_arg (args .roles )
5662 if app_status :
57- print (app_status .format (filter_roles ))
63+ if args .json :
64+ print (json .dumps (app_status .to_json (filter_roles )))
65+ else :
66+ print (app_status .format (filter_roles ))
5867 else :
5968 logger .error (
6069 f"AppDef: { app_id } ,"
Original file line number Diff line number Diff line change @@ -538,6 +538,12 @@ class RoleStatus:
538538 role : str
539539 replicas : List [ReplicaStatus ]
540540
541+ def to_json (self ) -> Dict [str , Any ]:
542+ return {
543+ "role" : self .role ,
544+ "replicas" : [asdict (replica ) for replica in self .replicas ],
545+ }
546+
541547
542548@dataclass
543549class AppStatus :
@@ -657,6 +663,18 @@ def _format_role_status(
657663 replica_data += self ._format_replica_status (replica )
658664 return f"{ replica_data } "
659665
666+ def to_json (self , filter_roles : Optional [List [str ]] = None ) -> Dict [str , Any ]:
667+ roles = self ._get_role_statuses (self .roles , filter_roles )
668+
669+ return {
670+ "state" : str (self .state ),
671+ "num_restarts" : self .num_restarts ,
672+ "roles" : [role_status .to_json () for role_status in roles ],
673+ "msg" : self .msg ,
674+ "structured_error_msg" : self .structured_error_msg ,
675+ "url" : self .ui_url ,
676+ }
677+
660678 def format (
661679 self ,
662680 filter_roles : Optional [List [str ]] = None ,
@@ -672,6 +690,7 @@ def format(
672690 """
673691 roles_data = ""
674692 roles = self ._get_role_statuses (self .roles , filter_roles )
693+
675694 for role_status in roles :
676695 roles_data += self ._format_role_status (role_status )
677696 return Template (_APP_STATUS_FORMAT_TEMPLATE ).substitute (
Original file line number Diff line number Diff line change @@ -176,6 +176,42 @@ def test_format_app_status(self) -> None:
176176 # Split and compare to aviod AssertionError.
177177 self .assertEqual (expected_message .split (), actual_message .split ())
178178
179+ def test_app_status_in_json (self ) -> None :
180+ app_status = self ._get_test_app_status ()
181+ result = app_status .to_json ()
182+ error_msg = '{"message":{"message":"error","errorCode":-1,"extraInfo":{"timestamp":1293182}}}'
183+ self .assertDictEqual (
184+ result ,
185+ {
186+ "state" : "RUNNING" ,
187+ "num_restarts" : 0 ,
188+ "roles" : [
189+ {
190+ "role" : "worker" ,
191+ "replicas" : [
192+ {
193+ "id" : 0 ,
194+ "state" : 5 ,
195+ "role" : "worker" ,
196+ "hostname" : "localhost" ,
197+ "structured_error_msg" : error_msg ,
198+ },
199+ {
200+ "id" : 1 ,
201+ "state" : 3 ,
202+ "role" : "worker" ,
203+ "hostname" : "localhost" ,
204+ "structured_error_msg" : "<NONE>" ,
205+ },
206+ ],
207+ }
208+ ],
209+ "msg" : "" ,
210+ "structured_error_msg" : "<NONE>" ,
211+ "url" : None ,
212+ },
213+ )
214+
179215
180216class ResourceTest (unittest .TestCase ):
181217 def test_copy_resource (self ) -> None :
You can’t perform that action at this time.
0 commit comments