blob: 7ca0daa7c539364b86719dadcac1db8d106857a2 [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(
Zhuoyao Zhang7f22db82024-10-17 17:40:34 +000045 '--dry_run',
46 action='store_true',
47 help='Dry run the edit monitor. This starts the edit monitor process without actually send the edit logs to clearcut.',
48 )
49
50 parser.add_argument(
Zhuoyao Zhangc0190662024-10-03 22:03:47 +000051 '--force_cleanup',
52 action='store_true',
53 help=(
54 'Instead of start a new edit monitor, force stop all existing edit'
55 ' monitors in the system. This option is only used in emergent cases'
56 ' when we want to prevent user damage by the edit monitor.'
57 ),
58 )
59
Zhuoyao Zhang64ad75f2024-10-25 00:21:45 +000060 parser.add_argument(
61 '--verbose',
62 action='store_true',
63 help=(
64 'Log verbose info in the log file for debugging purpose.'
65 ),
66 )
67
Zhuoyao Zhangc0190662024-10-03 22:03:47 +000068 return parser
69
70
Zhuoyao Zhang64ad75f2024-10-25 00:21:45 +000071def configure_logging(verbose=False):
Zhuoyao Zhangc0190662024-10-03 22:03:47 +000072 root_logging_dir = tempfile.mkdtemp(prefix='edit_monitor_')
73 _, log_path = tempfile.mkstemp(dir=root_logging_dir, suffix='.log')
74
Zhuoyao Zhanga7107912024-12-04 17:39:54 +000075
76 log_fmt = '%(asctime)s.%(msecs)03d %(filename)s:%(lineno)s:%(levelname)s: %(message)s'
Zhuoyao Zhangc0190662024-10-03 22:03:47 +000077 date_fmt = '%Y-%m-%d %H:%M:%S'
Zhuoyao Zhang64ad75f2024-10-25 00:21:45 +000078 log_level = logging.DEBUG if verbose else logging.INFO
79
Zhuoyao Zhangc0190662024-10-03 22:03:47 +000080 logging.basicConfig(
Zhuoyao Zhang64ad75f2024-10-25 00:21:45 +000081 filename=log_path, level=log_level, format=log_fmt, datefmt=date_fmt
Zhuoyao Zhangc0190662024-10-03 22:03:47 +000082 )
Zhuoyao Zhang0597a9d2024-10-04 21:11:18 +000083 # Filter out logs from inotify_buff to prevent log pollution.
84 logging.getLogger('watchdog.observers.inotify_buffer').addFilter(
85 lambda record: record.filename != 'inotify_buffer.py')
Zhuoyao Zhangc0190662024-10-03 22:03:47 +000086 print(f'logging to file {log_path}')
87
88
89def term_signal_handler(_signal_number, _frame):
90 logging.info('Process %d received SIGTERM, Terminating...', os.getpid())
91 sys.exit(0)
92
93
94def main(argv: list[str]):
95 args = create_arg_parser().parse_args(argv[1:])
Zhuoyao Zhang64ad75f2024-10-25 00:21:45 +000096 configure_logging(args.verbose)
Zhuoyao Zhang7f22db82024-10-17 17:40:34 +000097 if args.dry_run:
98 logging.info('This is a dry run.')
Zhuoyao Zhangc0190662024-10-03 22:03:47 +000099 dm = daemon_manager.DaemonManager(
100 binary_path=argv[0],
101 daemon_target=edit_monitor.start,
Zhuoyao Zhang7f22db82024-10-17 17:40:34 +0000102 daemon_args=(args.path, args.dry_run),
Zhuoyao Zhangc0190662024-10-03 22:03:47 +0000103 )
Zhuoyao Zhang7f22db82024-10-17 17:40:34 +0000104
Zhuoyao Zhangc0190662024-10-03 22:03:47 +0000105 if args.force_cleanup:
106 dm.cleanup()
107
108 try:
109 dm.start()
110 dm.monitor_daemon()
111 except Exception:
112 logging.exception('Unexpected exception raised when run daemon.')
113 finally:
114 dm.stop()
115
116
117if __name__ == '__main__':
118 signal.signal(signal.SIGTERM, term_signal_handler)
Zhuoyao Zhangc0190662024-10-03 22:03:47 +0000119 main(sys.argv)