예제 #1
0
    def test_initialized(self):
        def callback():  # pragma: no cover
            pass

        callback_mock = mock.Mock(callback, set_auto=True)
        interface.register_global_metrics_callback('cb', callback_mock)

        request = webapp2.Request.blank('/internal/cron/ts_mon/send')
        request.headers['X-Appengine-Cron'] = 'true'
        self.mock_state.global_monitor = mock.Mock()
        response = request.get_response(handlers.app)

        self.assertEqual(response.status_int, 200)
        callback_mock.assert_called_once_with()
예제 #2
0
 def test_register_global_metrics_callback(self):
   interface.register_global_metrics_callback('test', 'callback')
   self.assertEqual(['test'], list(interface.state.global_metrics_callbacks))
   interface.register_global_metrics_callback('nonexistent', None)
   self.assertEqual(['test'], list(interface.state.global_metrics_callbacks))
   interface.register_global_metrics_callback('test', None)
   self.assertEqual([], list(interface.state.global_metrics_callbacks))
예제 #3
0
 def test_callbacks_not_called_if_disabled(self):
     interface.state.invoke_global_callbacks_on_flush = False
     cb = mock.Mock()
     interface.register_global_metrics_callback('test', cb)
     interface.flush()
     self.assertFalse(cb.called)
예제 #4
0
 def test_flush_continues_after_exception(self):
     cb = mock.Mock(side_effect=[Exception, None])
     interface.register_global_metrics_callback('cb1', cb)
     interface.register_global_metrics_callback('cb2', cb)
     interface.flush()
     self.assertEqual(2, cb.call_count)
예제 #5
0
 def test_callbacks_called_on_flush(self):
     cb = mock.Mock()
     interface.register_global_metrics_callback('test', cb)
     interface.flush()
     cb.assert_called_once_with()
예제 #6
0
def initialize(app=None,
               is_enabled_fn=None,
               cron_module='default',
               is_local_unittest=None):
    """Instruments webapp2 `app` with gae_ts_mon metrics.

  Instruments all the endpoints in `app` with basic metrics.

  Args:
    app (webapp2 app): the app to instrument.
    is_enabled_fn (function or None): a function returning bool if ts_mon should
      send the actual metrics. None (default) is equivalent to lambda: True.
      This allows apps to turn monitoring on or off dynamically, per app.
    cron_module (str): the name of the module handling the
      /internal/cron/ts_mon/send endpoint. This allows moving the cron job
      to any module the user wants.
    is_local_unittest (bool or None): whether we are running in a unittest.
  """
    if is_local_unittest is None:  # pragma: no cover
        # Since gae_ts_mon.initialize is called at module-scope by appengine apps,
        # AppengineTestCase.setUp() won't have run yet and none of the appengine
        # stubs will be initialized, so accessing Datastore or even getting the
        # application ID will fail.
        is_local_unittest = ('expect_tests' in sys.argv[0])

    if is_enabled_fn is not None:
        interface.state.flush_enabled_fn = is_enabled_fn

    if app is not None:
        instrument_wsgi_application(app)
        if is_local_unittest or modules.get_current_module_name(
        ) == cron_module:
            instrument_wsgi_application(handlers.app)

    # Use the application ID as the service name and the module name as the job
    # name.
    if is_local_unittest:  # pragma: no cover
        service_name = 'unittest'
        job_name = 'unittest'
        hostname = 'unittest'
    else:
        service_name = app_identity.get_application_id()
        job_name = modules.get_current_module_name()
        hostname = modules.get_current_version_name()
        runtime.set_shutdown_hook(_shutdown_hook)

    interface.state.target = targets.TaskTarget(service_name,
                                                job_name,
                                                shared.REGION,
                                                hostname,
                                                task_num=-1)
    interface.state.flush_mode = 'manual'
    interface.state.last_flushed = datetime.datetime.utcnow()

    # Don't send metrics when running on the dev appserver.
    if (is_local_unittest or os.environ.get('SERVER_SOFTWARE',
                                            '').startswith('Development')):
        logging.info('Using debug monitor')
        interface.state.global_monitor = monitors.DebugMonitor()
    else:
        logging.info('Using https monitor %s with %s',
                     shared.PRODXMON_ENDPOINT,
                     shared.PRODXMON_SERVICE_ACCOUNT_EMAIL)
        interface.state.global_monitor = monitors.HttpsMonitor(
            shared.PRODXMON_ENDPOINT,
            monitors.DelegateServiceAccountCredentials(
                shared.PRODXMON_SERVICE_ACCOUNT_EMAIL,
                monitors.AppengineCredentials()))
        interface.state.use_new_proto = True

    interface.register_global_metrics([shared.appengine_default_version])
    interface.register_global_metrics_callback(shared.INTERNAL_CALLBACK_NAME,
                                               _internal_callback)

    # We invoke global callbacks once for the whole application in the cron
    # handler.  Leaving this set to True would invoke them once per task.
    interface.state.invoke_global_callbacks_on_flush = False

    standard_metrics.init()

    logging.info(
        'Initialized ts_mon with service_name=%s, job_name=%s, '
        'hostname=%s', service_name, job_name, hostname)
예제 #7
0
def initialize(app=None, is_enabled_fn=None, cron_module='default',
               is_local_unittest=None):
  """Instruments webapp2 `app` with gae_ts_mon metrics.

  Instruments all the endpoints in `app` with basic metrics.

  Args:
    app (webapp2 app): the app to instrument.
    is_enabled_fn (function or None): a function returning bool if ts_mon should
      send the actual metrics. None (default) is equivalent to lambda: True.
      This allows apps to turn monitoring on or off dynamically, per app.
    cron_module (str): the name of the module handling the
      /internal/cron/ts_mon/send endpoint. This allows moving the cron job
      to any module the user wants.
    is_local_unittest (bool or None): whether we are running in a unittest.
  """
  if is_local_unittest is None:  # pragma: no cover
    # Since gae_ts_mon.initialize is called at module-scope by appengine apps,
    # AppengineTestCase.setUp() won't have run yet and none of the appengine
    # stubs will be initialized, so accessing Datastore or even getting the
    # application ID will fail.
    is_local_unittest = ('expect_tests' in sys.argv[0])

  if is_enabled_fn is not None:
    interface.state.flush_enabled_fn = is_enabled_fn

  if app is not None:
    instrument_wsgi_application(app)
    if is_local_unittest or modules.get_current_module_name() == cron_module:
      instrument_wsgi_application(handlers.app)

  # Use the application ID as the service name and the module name as the job
  # name.
  if is_local_unittest:  # pragma: no cover
    service_name = 'unittest'
    job_name = 'unittest'
    hostname = 'unittest'
  else:
    service_name = app_identity.get_application_id()
    job_name = modules.get_current_module_name()
    hostname = modules.get_current_version_name()
    runtime.set_shutdown_hook(_shutdown_hook)

  interface.state.target = targets.TaskTarget(
      service_name, job_name, shared.REGION, hostname, task_num=-1)
  interface.state.flush_mode = 'manual'
  interface.state.last_flushed = datetime.datetime.utcnow()

  # Don't send metrics when running on the dev appserver.
  if (is_local_unittest or
      os.environ.get('SERVER_SOFTWARE', '').startswith('Development')):
    logging.info('Using debug monitor')
    interface.state.global_monitor = monitors.DebugMonitor()
  else:
    logging.info('Using https monitor %s with %s', shared.PRODXMON_ENDPOINT,
                 shared.PRODXMON_SERVICE_ACCOUNT_EMAIL)
    interface.state.global_monitor = monitors.HttpsMonitor(
        shared.PRODXMON_ENDPOINT,
        monitors.DelegateServiceAccountCredentials(
            shared.PRODXMON_SERVICE_ACCOUNT_EMAIL,
            monitors.AppengineCredentials()))
    interface.state.use_new_proto = True

  interface.register_global_metrics([shared.appengine_default_version])
  interface.register_global_metrics_callback(
      shared.INTERNAL_CALLBACK_NAME, _internal_callback)

  # We invoke global callbacks once for the whole application in the cron
  # handler.  Leaving this set to True would invoke them once per task.
  interface.state.invoke_global_callbacks_on_flush = False

  standard_metrics.init()

  logging.info('Initialized ts_mon with service_name=%s, job_name=%s, '
               'hostname=%s', service_name, job_name, hostname)