1*9e94795aSAndroid Build Coastguard Worker# Copyright 2024, The Android Open Source Project 2*9e94795aSAndroid Build Coastguard Worker# 3*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*9e94795aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*9e94795aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*9e94795aSAndroid Build Coastguard Worker# 7*9e94795aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*9e94795aSAndroid Build Coastguard Worker# 9*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*9e94795aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e94795aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*9e94795aSAndroid Build Coastguard Worker# limitations under the License. 14*9e94795aSAndroid Build Coastguard Worker 15*9e94795aSAndroid Build Coastguard Workerimport argparse 16*9e94795aSAndroid Build Coastguard Workerimport logging 17*9e94795aSAndroid Build Coastguard Workerimport os 18*9e94795aSAndroid Build Coastguard Workerimport signal 19*9e94795aSAndroid Build Coastguard Workerimport sys 20*9e94795aSAndroid Build Coastguard Workerimport tempfile 21*9e94795aSAndroid Build Coastguard Worker 22*9e94795aSAndroid Build Coastguard Workerfrom edit_monitor import daemon_manager 23*9e94795aSAndroid Build Coastguard Workerfrom edit_monitor import edit_monitor 24*9e94795aSAndroid Build Coastguard Worker 25*9e94795aSAndroid Build Coastguard Worker 26*9e94795aSAndroid Build Coastguard Workerdef create_arg_parser(): 27*9e94795aSAndroid Build Coastguard Worker """Creates an instance of the default arg parser.""" 28*9e94795aSAndroid Build Coastguard Worker 29*9e94795aSAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 30*9e94795aSAndroid Build Coastguard Worker description=( 31*9e94795aSAndroid Build Coastguard Worker 'Monitors edits in Android source code and uploads the edit logs.' 32*9e94795aSAndroid Build Coastguard Worker ), 33*9e94795aSAndroid Build Coastguard Worker add_help=True, 34*9e94795aSAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter, 35*9e94795aSAndroid Build Coastguard Worker ) 36*9e94795aSAndroid Build Coastguard Worker 37*9e94795aSAndroid Build Coastguard Worker parser.add_argument( 38*9e94795aSAndroid Build Coastguard Worker '--path', 39*9e94795aSAndroid Build Coastguard Worker type=str, 40*9e94795aSAndroid Build Coastguard Worker required=True, 41*9e94795aSAndroid Build Coastguard Worker help='Root path to monitor the edit events.', 42*9e94795aSAndroid Build Coastguard Worker ) 43*9e94795aSAndroid Build Coastguard Worker 44*9e94795aSAndroid Build Coastguard Worker parser.add_argument( 45*9e94795aSAndroid Build Coastguard Worker '--dry_run', 46*9e94795aSAndroid Build Coastguard Worker action='store_true', 47*9e94795aSAndroid Build Coastguard Worker help='Dry run the edit monitor. This starts the edit monitor process without actually send the edit logs to clearcut.', 48*9e94795aSAndroid Build Coastguard Worker ) 49*9e94795aSAndroid Build Coastguard Worker 50*9e94795aSAndroid Build Coastguard Worker parser.add_argument( 51*9e94795aSAndroid Build Coastguard Worker '--force_cleanup', 52*9e94795aSAndroid Build Coastguard Worker action='store_true', 53*9e94795aSAndroid Build Coastguard Worker help=( 54*9e94795aSAndroid Build Coastguard Worker 'Instead of start a new edit monitor, force stop all existing edit' 55*9e94795aSAndroid Build Coastguard Worker ' monitors in the system. This option is only used in emergent cases' 56*9e94795aSAndroid Build Coastguard Worker ' when we want to prevent user damage by the edit monitor.' 57*9e94795aSAndroid Build Coastguard Worker ), 58*9e94795aSAndroid Build Coastguard Worker ) 59*9e94795aSAndroid Build Coastguard Worker 60*9e94795aSAndroid Build Coastguard Worker parser.add_argument( 61*9e94795aSAndroid Build Coastguard Worker '--verbose', 62*9e94795aSAndroid Build Coastguard Worker action='store_true', 63*9e94795aSAndroid Build Coastguard Worker help=( 64*9e94795aSAndroid Build Coastguard Worker 'Log verbose info in the log file for debugging purpose.' 65*9e94795aSAndroid Build Coastguard Worker ), 66*9e94795aSAndroid Build Coastguard Worker ) 67*9e94795aSAndroid Build Coastguard Worker 68*9e94795aSAndroid Build Coastguard Worker return parser 69*9e94795aSAndroid Build Coastguard Worker 70*9e94795aSAndroid Build Coastguard Worker 71*9e94795aSAndroid Build Coastguard Workerdef configure_logging(verbose=False): 72*9e94795aSAndroid Build Coastguard Worker root_logging_dir = tempfile.mkdtemp(prefix='edit_monitor_') 73*9e94795aSAndroid Build Coastguard Worker _, log_path = tempfile.mkstemp(dir=root_logging_dir, suffix='.log') 74*9e94795aSAndroid Build Coastguard Worker 75*9e94795aSAndroid Build Coastguard Worker 76*9e94795aSAndroid Build Coastguard Worker log_fmt = '%(asctime)s.%(msecs)03d %(filename)s:%(lineno)s:%(levelname)s: %(message)s' 77*9e94795aSAndroid Build Coastguard Worker date_fmt = '%Y-%m-%d %H:%M:%S' 78*9e94795aSAndroid Build Coastguard Worker log_level = logging.DEBUG if verbose else logging.INFO 79*9e94795aSAndroid Build Coastguard Worker 80*9e94795aSAndroid Build Coastguard Worker logging.basicConfig( 81*9e94795aSAndroid Build Coastguard Worker filename=log_path, level=log_level, format=log_fmt, datefmt=date_fmt 82*9e94795aSAndroid Build Coastguard Worker ) 83*9e94795aSAndroid Build Coastguard Worker # Filter out logs from inotify_buff to prevent log pollution. 84*9e94795aSAndroid Build Coastguard Worker logging.getLogger('watchdog.observers.inotify_buffer').addFilter( 85*9e94795aSAndroid Build Coastguard Worker lambda record: record.filename != 'inotify_buffer.py') 86*9e94795aSAndroid Build Coastguard Worker print(f'logging to file {log_path}') 87*9e94795aSAndroid Build Coastguard Worker 88*9e94795aSAndroid Build Coastguard Worker 89*9e94795aSAndroid Build Coastguard Workerdef term_signal_handler(_signal_number, _frame): 90*9e94795aSAndroid Build Coastguard Worker logging.info('Process %d received SIGTERM, Terminating...', os.getpid()) 91*9e94795aSAndroid Build Coastguard Worker sys.exit(0) 92*9e94795aSAndroid Build Coastguard Worker 93*9e94795aSAndroid Build Coastguard Worker 94*9e94795aSAndroid Build Coastguard Workerdef main(argv: list[str]): 95*9e94795aSAndroid Build Coastguard Worker args = create_arg_parser().parse_args(argv[1:]) 96*9e94795aSAndroid Build Coastguard Worker configure_logging(args.verbose) 97*9e94795aSAndroid Build Coastguard Worker if args.dry_run: 98*9e94795aSAndroid Build Coastguard Worker logging.info('This is a dry run.') 99*9e94795aSAndroid Build Coastguard Worker dm = daemon_manager.DaemonManager( 100*9e94795aSAndroid Build Coastguard Worker binary_path=argv[0], 101*9e94795aSAndroid Build Coastguard Worker daemon_target=edit_monitor.start, 102*9e94795aSAndroid Build Coastguard Worker daemon_args=(args.path, args.dry_run), 103*9e94795aSAndroid Build Coastguard Worker ) 104*9e94795aSAndroid Build Coastguard Worker 105*9e94795aSAndroid Build Coastguard Worker try: 106*9e94795aSAndroid Build Coastguard Worker if args.force_cleanup: 107*9e94795aSAndroid Build Coastguard Worker dm.cleanup() 108*9e94795aSAndroid Build Coastguard Worker else: 109*9e94795aSAndroid Build Coastguard Worker dm.start() 110*9e94795aSAndroid Build Coastguard Worker dm.monitor_daemon() 111*9e94795aSAndroid Build Coastguard Worker except Exception: 112*9e94795aSAndroid Build Coastguard Worker logging.exception('Unexpected exception raised when run daemon.') 113*9e94795aSAndroid Build Coastguard Worker finally: 114*9e94795aSAndroid Build Coastguard Worker dm.stop() 115*9e94795aSAndroid Build Coastguard Worker 116*9e94795aSAndroid Build Coastguard Worker 117*9e94795aSAndroid Build Coastguard Workerif __name__ == '__main__': 118*9e94795aSAndroid Build Coastguard Worker signal.signal(signal.SIGTERM, term_signal_handler) 119*9e94795aSAndroid Build Coastguard Worker main(sys.argv) 120