Chromium Code Reviews| Index: infra/tools/send_monitoring_event/send_event.py |
| diff --git a/infra/tools/send_monitoring_event/send_event.py b/infra/tools/send_monitoring_event/send_event.py |
| index 4f0d04b3ac666ee56968be2a7bf734ed5d68b63d..9f83e399875fceab32511743d3a4cb74f8927c7c 100644 |
| --- a/infra/tools/send_monitoring_event/send_event.py |
| +++ b/infra/tools/send_monitoring_event/send_event.py |
| @@ -10,9 +10,12 @@ import json |
| import sys |
| from infra_libs import event_mon |
| -import infra_libs.logs |
| from infra_libs import ts_mon |
| +import infra_libs.logs |
| +from infra_libs.event_mon.protos.log_request_lite_pb2 import LogRequestLite |
| +from infra_libs.event_mon.protos.chrome_infra_log_pb2 import ChromeInfraEvent |
| +from infra_libs.event_mon.protos.goma_stats_pb2 import GomaStats |
| LOGGER = logging.getLogger(__name__) |
| @@ -46,10 +49,7 @@ def get_arguments(argv): |
| # Common fields |
| common_group = parser.add_argument_group('Common event options') |
| common_group.add_argument('--event-mon-timestamp-kind', |
| - choices=[kind |
| - for kind in event_mon.TIMESTAMP_KINDS |
| - if kind], |
| - default='POINT', |
|
dsansome
2015/10/29 23:17:33
Should this still have the default? If not remove
pgervais
2015/11/02 19:38:58
Done.
|
| + choices=event_mon.TIMESTAMP_KINDS, |
| help='General kind of event. This value is used ' |
| 'e.g. to\nautomatically compute durations between ' |
| 'START and STOP\nevents. Default: %(default)s') |
| @@ -121,6 +121,11 @@ def get_arguments(argv): |
| 'list of strings or json-encoded list of string. ' |
| 'Each one must be less than 20 characters long.') |
| + build_group.add_argument('--build-event-goma-stats-path', |
| + metavar='FILENAME', |
| + help='File containing a serialized GomaStats ' |
| + 'protobuf.') |
| + |
| # Read events from file |
| file_group = parser.add_argument_group('Read events from file') |
| file_group.add_argument('--events-from-file', |
| @@ -129,13 +134,23 @@ def get_arguments(argv): |
| 'option\nis incompatible with --build-event-type and' |
| '\n--service-event-type.\nSee ' |
| 'send_event.read_events_from_file for details\n' |
| - 'on the format. This options can be passed multiple\n' |
| + 'on the format. This option can be passed multiple\n' |
| 'times, and wildcards can be used.') |
| file_group.add_argument('--delete-file-when-sent', |
| action='store_true', default=False, |
| help='If all events read from a file have been ' |
| 'successfully\nsent to the endpoint, delete the ' |
| - 'file. By default\nfiles are kept.') |
| + 'file. By default\nfiles are kept. This does not ' |
| + 'affect the file pointed to by ' |
| + '--event-logrequest-path') |
| + |
| + file_group.add_argument('--event-logrequest-path', |
| + metavar='FILENAME', |
| + help='File containing a serialized LogRequestLite' |
| + 'proto, containing a single ChromeInfraEvent that ' |
| + 'will be used as the default event. Such a file can ' |
| + 'be generated by passing "file" to ' |
| + '--event-mon-run-type.') |
| ts_mon.add_argparse_options(parser) |
| event_mon.add_argparse_options(parser) |
| @@ -173,10 +188,78 @@ def get_arguments(argv): |
| return args |
| +def _process_logrequest_path(args): |
| + """Sets the default event based on --event-logrequest-path. |
| + |
| + This function raises exceptions because if the base event is wrong, then it's |
| + not worth sending anything anyway. |
| + """ |
| + if args.event_logrequest_path: |
| + try: |
| + with open(args.event_logrequest_path, 'rb') as f: |
| + request = LogRequestLite.FromString(f.read()) |
| + |
| + if len(request.log_event) == 1: |
| + default_event = ChromeInfraEvent.FromString( |
| + request.log_event[0].source_extension) |
| + # Assume that the content is sane because we don't want to duplicate |
| + # any business logic here. |
| + # TODO(pgervais): find a better solution. |
| + event_mon.set_default_event(default_event) |
| + else: |
| + raise ValueError( |
| + 'Expected only one log_event in the LogRequestLite proto ' |
| + 'pointed by --event-logrequest-path. Found %d in %s', |
| + len(request.log_event), args.event_logrequest_path) |
| + except Exception: |
| + LOGGER.exception('Failure when reading/parsing file %s', |
| + args.event_logrequest_path) |
| + raise |
| + |
| + default_event = event_mon.get_default_event() |
| + |
| + # When the default event is set using --event-logrequest-path, passing |
| + # --build-event-type or --service-event-type is optional. These options |
| + # still takes precedence but they must keep the event type the same. |
| + if (default_event.build_event.HasField('type') and |
| + default_event.service_event.HasField('type')): |
| + msg = ('Default event contains both service_event_type and ' |
| + 'build_event_type which is incorrect. Make sure you passed ' |
| + 'a correct proto to --event-logrequest-path. Otherwise it\'s an ' |
| + 'internal error. Aborting.') |
| + LOGGER.error(msg) |
| + raise ValueError(msg) |
| + |
| + if default_event.build_event.HasField('type'): |
| + if args.service_event_type: |
| + msg = ('The default event contains a type for build_event, but a ' |
| + 'service_event type was provided on the command-line. At most ' |
| + 'one of them can be specified. Aborting.') |
| + LOGGER.error(msg) |
| + raise ValueError(msg) |
| + |
| + if not args.build_event_type: |
| + args.build_event_type = event_mon.BuildEvent.BuildEventType.Name( |
| + default_event.build_event.type) |
| + |
| + if default_event.service_event.HasField('type'): |
| + if args.build_event_type: |
| + msg = ('The default event contains a type for service_event, but a ' |
| + 'build_event type was provided on the command-line. At most ' |
| + 'one of them can be specified. Aborting.') |
| + LOGGER.error(msg) |
| + raise ValueError(msg) |
| + if not args.service_event_type: |
| + args.service_event_type = event_mon.ServiceEvent.ServiceEventType.Name( |
| + default_event.service_event.type) |
| + |
| + |
| def process_argparse_options(args): # pragma: no cover |
| infra_libs.logs.process_argparse_options(args) |
| event_mon.process_argparse_options(args) |
| + # Put here because we want to send the presence metric as late as possible. |
| ts_mon.process_argparse_options(args) |
| + _process_logrequest_path(args) |
| def send_service_event(args): |
| @@ -204,6 +287,16 @@ def send_service_event(args): |
| def send_build_event(args): |
| """Entry point when --build-event-type is passed.""" |
| + goma_stats = None |
| + if args.build_event_goma_stats_path: |
| + try: |
| + with open(args.build_event_goma_stats_path, 'rb') as f: |
| + goma_stats = GomaStats.FromString(f.read()) |
| + except Exception: |
| + LOGGER.exception('Failure when reading/parsing file %s', |
| + args.build_event_goma_stats_path) |
| + raise |
| + |
| return bool(event_mon.send_build_event( |
| args.build_event_type, |
| @@ -216,7 +309,8 @@ def send_build_event(args): |
| result=args.build_event_result, |
| extra_result_code=args.build_event_extra_result_code, |
| timestamp_kind=args.event_mon_timestamp_kind, |
| - event_timestamp=args.event_mon_event_timestamp)) |
| + event_timestamp=args.event_mon_event_timestamp, |
| + goma_stats=goma_stats)) |
| def send_events_from_file(args): |