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