Пример #1
0
def _get_chrome_infra_event(timestamp_kind, service_name=None):
  """Compute a basic event.

  Validates the inputs and returns a pre-filled ChromeInfraEvent or
  None if any check failed.

  The proto is filled using values provided in setup_monitoring() at
  initialization time, and args.

  Args:
    timestamp_kind (string): any of ('POINT', 'BEGIN', 'END').

  Returns:
    event (chrome_infra_log_pb2.ChromeInfraEvent):
  """
  # Testing for None because we want an error message when timestamp_kind == ''.
  if timestamp_kind is not None and timestamp_kind not in TIMESTAMP_KINDS:
    logging.error('Invalid value for timestamp_kind: %s', timestamp_kind)
    return None

  # We must accept unicode here.
  if service_name is not None and not isinstance(service_name, basestring):
    logging.error('Invalid type for service_name: %s', type(service_name))
    return None

  event = ChromeInfraEvent()
  event.CopyFrom(config._cache['default_event'])

  if timestamp_kind:
    event.timestamp_kind = ChromeInfraEvent.TimestampKind.Value(timestamp_kind)
  if service_name:
    event.event_source.service_name = service_name

  return event
Пример #2
0
def _get_chrome_infra_event(timestamp_kind, service_name=None):
  """Compute a basic event.

  Validates the inputs and returns a pre-filled ChromeInfraEvent or
  None if any check failed.

  The proto is filled using values provided in setup_monitoring() at
  initialization time, and args.

  Args:
    timestamp_kind (string): any of ('POINT', 'BEGIN', 'END').

  Returns:
    event (chrome_infra_log_pb2.ChromeInfraEvent):
  """
  # Testing for None because we want an error message when timestamp_kind == ''.
  if timestamp_kind is not None and timestamp_kind not in TIMESTAMP_KINDS:
    logging.error('Invalid value for timestamp_kind: %s', timestamp_kind)
    return None

  # We must accept unicode here.
  if service_name is not None and not isinstance(service_name, basestring):
    logging.error('Invalid type for service_name: %s', type(service_name))
    return None

  event = ChromeInfraEvent()
  event.CopyFrom(config._cache['default_event'])

  if timestamp_kind:
    event.timestamp_kind = ChromeInfraEvent.TimestampKind.Value(timestamp_kind)
  if service_name:
    event.event_source.service_name = service_name

  return event
Пример #3
0
def get_default_event():
    """Returns a copy of the default event."""

    # We return a copy here to tell people not to modify the event directly.
    ret = ChromeInfraEvent()
    ret.CopyFrom(_cache['default_event'])
    return ret
Пример #4
0
 def _send_to_endpoint(self, events):
     try:
         for ev in events.log_event:
             ev_str = str(ChromeInfraEvent.FromString(ev.source_extension))
             logging.log(self.severity,
                         'Sending event_mon event:\n%s' % ev_str)
     except Exception:
         logging.exception('Unable to log the events')
         return False
     return True
Пример #5
0
 def _send_to_endpoint(self, events):
     # Prints individual events because it's what we're usually interested in
     # in that case.
     infra_events = [
         str(ChromeInfraEvent.FromString(ev.source_extension))
         for ev in events.log_event
     ]
     try:
         self.stream.write('%s\n' % '\n'.join(infra_events))
     except Exception:
         logging.exception('Unable to write to provided stream')
         return False
     return True
Пример #6
0
    def test_stringio_stream(self):
        config._cache['default_event'] = ChromeInfraEvent()
        log_event = infra_libs.event_mon.monitoring._get_service_event(
            'START', timestamp_kind='POINT', event_timestamp=1234).log_event()

        stream = StringIO.StringIO()
        r = router._TextStreamRouter(stream=stream)
        self.assertTrue(r.push_event(log_event))
        stream.seek(0)
        output = stream.read()
        self.assertGreater(stream.len, 10)
        # Minimal checking because if this is printed the rest is printed as well
        # unless google.protobuf is completely broken.
        self.assertIn('timestamp_kind: POINT', output)
Пример #7
0
    def test_events_are_logged_correctly(self, log_mock):
        logger = router._LoggingStreamRouter()
        events = []
        for i in range(3):
            event = LogRequestLite.LogEventLite()
            event.event_time_ms = router.time_ms()
            event.event_code = 1
            event.event_flow_id = 2
            infra_event = ChromeInfraEvent()
            infra_event.cq_event.issue = str(i + 1)
            event.source_extension = infra_event.SerializeToString()
            events.append(event)

        self.assertTrue(logger.push_event(events))

        expected_calls = [
            ((logging.INFO,
              'Sending event_mon event:\ncq_event {\n  issue: "1"\n}\n'), ),
            ((logging.INFO,
              'Sending event_mon event:\ncq_event {\n  issue: "2"\n}\n'), ),
            ((logging.INFO,
              'Sending event_mon event:\ncq_event {\n  issue: "3"\n}\n'), )
        ]
        self.assertEqual(log_mock.call_args_list, expected_calls)
Пример #8
0
def process_argparse_options(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.
  """
    event_mon.process_argparse_options(args)
    _extra_argument_checking(args)

    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)
Пример #9
0
def setup_monitoring(run_type='dry',
                     hostname=None,
                     service_name=None,
                     appengine_name=None,
                     output_file=None,
                     dry_run=False,
                     http_timeout=10,
                     http_retry_backoff=2.):
    """Initializes event monitoring.

  This function is mainly used to provide default global values which are
  required for the module to work.

  If you're implementing a command-line tool, use process_argparse_options
  instead.

  Args:
    run_type (str): One of 'dry', 'test', or 'prod'. Do respectively nothing,
      hit the testing endpoint and the production endpoint.

    hostname (str): hostname as it should appear in the event. If not provided
      a default value is computed.

    service_name (str): logical name of the service that emits events. e.g.
      "commit_queue".

    appengine_name (str): name of the appengine app, if running on appengine.

    output_file (str): file where to write the output in run_type == 'file'
      mode.

    dry_run (bool): if True, the code has no side-effect, what would have been
      done is printed instead.

    http_timeout (int): timeout in seconds for HTTP requests to send events.

    http_retry_backoff (float): time in seconds before retrying POSTing to the
         HTTP endpoint. Randomized exponential backoff is applied on subsequent
         retries.
  """
    global _router
    logging.debug('event_mon: setting up monitoring.')

    if _router:
        return

    default_event = ChromeInfraEvent()

    hostname = hostname or socket.getfqdn()
    # hostname might be empty string or None on some systems, who knows.
    if hostname:  # pragma: no branch
        default_event.event_source.host_name = hostname
    else:  # pragma: no cover
        logging.warning('event_mon: unable to determine hostname.')

    if service_name:
        default_event.event_source.service_name = service_name
    if appengine_name:
        default_event.event_source.appengine_name = appengine_name

    _cache['default_event'] = default_event

    if run_type not in RUNTYPES:
        logging.error('Unknown run_type (%s). Setting to "dry"', run_type)
        run_type = 'dry'

    if run_type == 'dry':
        # If we are running on AppEngine or devserver, use logging module.
        server_software = os.environ.get('SERVER_SOFTWARE', '')
        if (server_software.startswith('Google App Engine')
                or server_software.startswith('Development')):
            _router = ev_router._LoggingStreamRouter()
        else:
            _router = ev_router._TextStreamRouter()
    elif run_type == 'file':
        _router = ev_router._LocalFileRouter(output_file, dry_run=dry_run)
    else:
        _router = ev_router._HttpRouter(_cache,
                                        ENDPOINTS.get(run_type),
                                        dry_run=dry_run,
                                        timeout=http_timeout,
                                        retry_backoff=http_retry_backoff)