Support --dry_run option in edit monitor

If --dry_run option is set, edit monitor runs without actually sending
the edit logs to clearcut

Test: atest edit_monitor_test
bug: 365617369
Change-Id: I793d9b0a2e16ffa70fe03d1d3f53d676a1d86cf3
diff --git a/tools/edit_monitor/edit_monitor.py b/tools/edit_monitor/edit_monitor.py
index 31115d4..ab528e8 100644
--- a/tools/edit_monitor/edit_monitor.py
+++ b/tools/edit_monitor/edit_monitor.py
@@ -43,6 +43,7 @@
       path: str,
       flush_interval_sec: int,
       single_events_size_threshold: int,
+      is_dry_run: bool = False,
       cclient: clearcut_client.Clearcut | None = None,
   ):
 
@@ -50,6 +51,7 @@
     self.root_monitoring_path = path
     self.flush_interval_sec = flush_interval_sec
     self.single_events_size_threshold = single_events_size_threshold
+    self.is_dry_run = is_dry_run
     self.cclient = cclient or clearcut_client.Clearcut(LOG_SOURCE)
 
     self.user_name = getpass.getuser()
@@ -164,6 +166,10 @@
       )
       edit_events = [(aggregated_event_proto, aggregated_event_time)]
 
+    if self.is_dry_run:
+      logging.info("Sent %d edit events in dry run.", len(edit_events))
+      return
+
     for event_proto, event_time in edit_events:
       log_event = clientanalytics_pb2.LogEvent(
           event_time_ms=int(event_time * 1000),
@@ -176,6 +182,7 @@
 
 def start(
     path: str,
+    is_dry_run: bool = False,
     flush_interval_sec: int = DEFAULT_FLUSH_INTERVAL_SECONDS,
     single_events_size_threshold: int = DEFAULT_SINGLE_EVENTS_SIZE_THRESHOLD,
     cclient: clearcut_client.Clearcut | None = None,
@@ -192,7 +199,7 @@
     conn: the sender of the pipe to communicate with the deamon manager.
   """
   event_handler = ClearcutEventHandler(
-      path, flush_interval_sec, single_events_size_threshold, cclient)
+      path, flush_interval_sec, single_events_size_threshold, is_dry_run, cclient)
   observer = Observer()
 
   logging.info("Starting observer on path %s.", path)
diff --git a/tools/edit_monitor/edit_monitor_test.py b/tools/edit_monitor/edit_monitor_test.py
index 4ec3284..64a3871 100644
--- a/tools/edit_monitor/edit_monitor_test.py
+++ b/tools/edit_monitor/edit_monitor_test.py
@@ -253,7 +253,7 @@
     # Start edit monitor in a subprocess.
     p = multiprocessing.Process(
         target=edit_monitor.start,
-        args=(str(self.root_monitoring_path.resolve()), 0.5, 5, cclient, sender),
+        args=(str(self.root_monitoring_path.resolve()), False, 0.5, 5, cclient, sender),
     )
     p.daemon = True
     p.start()
diff --git a/tools/edit_monitor/main.py b/tools/edit_monitor/main.py
index 9086ac8..6af421b 100644
--- a/tools/edit_monitor/main.py
+++ b/tools/edit_monitor/main.py
@@ -42,6 +42,12 @@
   )
 
   parser.add_argument(
+      '--dry_run',
+      action='store_true',
+      help='Dry run the edit monitor. This starts the edit monitor process without actually send the edit logs to clearcut.',
+  )
+
+  parser.add_argument(
       '--force_cleanup',
       action='store_true',
       help=(
@@ -76,11 +82,14 @@
 
 def main(argv: list[str]):
   args = create_arg_parser().parse_args(argv[1:])
+  if args.dry_run:
+    logging.info('This is a dry run.')
   dm = daemon_manager.DaemonManager(
       binary_path=argv[0],
       daemon_target=edit_monitor.start,
-      daemon_args=(args.path,),
+      daemon_args=(args.path, args.dry_run),
   )
+
   if args.force_cleanup:
     dm.cleanup()