def process_argparse_options(args):
    """Process command line arguments to initialize the global monitor.

  Also initializes the default target.

  Starts a background thread to automatically flush monitoring metrics if not
  disabled by command line arguments.

  Args:
    args (argparse.Namespace): the result of parsing the command line arguments
  """
    # Parse the config file if it exists.
    config = load_machine_config(args.ts_mon_config_file)
    endpoint = config.get('endpoint', '')
    credentials = config.get('credentials', '')
    autogen_hostname = config.get('autogen_hostname', False)

    # Command-line args override the values in the config file.
    if args.ts_mon_endpoint is not None:
        endpoint = args.ts_mon_endpoint
    if args.ts_mon_credentials is not None:
        credentials = args.ts_mon_credentials

    if args.ts_mon_target_type == 'device':
        hostname = args.ts_mon_device_hostname
        if args.ts_mon_autogen_hostname or autogen_hostname:
            hostname = 'autogen:' + hostname
        interface.state.target = targets.DeviceTarget(
            args.ts_mon_device_region, args.ts_mon_device_role,
            args.ts_mon_device_network, hostname)
    if args.ts_mon_target_type == 'task':
        # Reimplement ArgumentParser.error, since we don't have access to the parser
        if not args.ts_mon_task_service_name:
            print >> sys.stderr, (
                'Argument --ts-mon-task-service-name must be '
                'provided when the target type is "task".')
            sys.exit(2)
        if not args.ts_mon_task_job_name:
            print >> sys.stderr, (
                'Argument --ts-mon-task-job-name must be provided '
                'when the target type is "task".')
            sys.exit(2)
        hostname = args.ts_mon_task_hostname
        if args.ts_mon_autogen_hostname or autogen_hostname:
            hostname = 'autogen:' + hostname
        interface.state.target = targets.TaskTarget(
            args.ts_mon_task_service_name, args.ts_mon_task_job_name,
            args.ts_mon_task_region, hostname, args.ts_mon_task_number)

    interface.state.metric_name_prefix = args.ts_mon_metric_name_prefix
    interface.state.global_monitor = monitors.NullMonitor()

    if endpoint.startswith('file://'):
        interface.state.global_monitor = monitors.DebugMonitor(
            endpoint[len('file://'):])
    elif endpoint.startswith('https://'):
        interface.state.global_monitor = monitors.HttpsMonitor(
            endpoint,
            monitors.CredentialFactory.from_string(credentials),
            ca_certs=args.ts_mon_ca_certs)
    elif endpoint.lower() == 'none' or not endpoint:
        logging.info('ts_mon monitoring has been explicitly disabled')
    else:
        logging.error(
            'ts_mon monitoring is disabled because the endpoint provided'
            ' is invalid or not supported: %s', endpoint)

    interface.state.flush_mode = args.ts_mon_flush

    if args.ts_mon_flush == 'auto':
        interface.state.flush_thread = interface._FlushThread(
            args.ts_mon_flush_interval_secs)
        interface.state.flush_thread.start()

    standard_metrics.init()
Beispiel #2
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)
Beispiel #3
0
def process_argparse_options(args):
  """Process command line arguments to initialize the global monitor.

  Also initializes the default target.

  Starts a background thread to automatically flush monitoring metrics if not
  disabled by command line arguments.

  Args:
    args (argparse.Namespace): the result of parsing the command line arguments
  """
  # Parse the config file if it exists.
  config = load_machine_config(args.ts_mon_config_file)
  endpoint = config.get('endpoint', '')
  credentials = config.get('credentials', '')

  # Command-line args override the values in the config file.
  if args.ts_mon_endpoint is not None:
    endpoint = args.ts_mon_endpoint
  if args.ts_mon_credentials is not None:
    credentials = args.ts_mon_credentials

  if args.ts_mon_target_type == 'device':
    hostname = args.ts_mon_device_hostname
    if args.ts_mon_autogen_hostname:
      hostname = 'autogen:' + hostname
    interface.state.target = targets.DeviceTarget(
        args.ts_mon_device_region,
        args.ts_mon_device_role,
        args.ts_mon_device_network,
        hostname)
  if args.ts_mon_target_type == 'task':
    # Reimplement ArgumentParser.error, since we don't have access to the parser
    if not args.ts_mon_task_service_name:
      print >> sys.stderr, ('Argument --ts-mon-task-service-name must be '
                            'provided when the target type is "task".')
      sys.exit(2)
    if not args.ts_mon_task_job_name:
      print >> sys.stderr, ('Argument --ts-mon-task-job-name must be provided '
                            'when the target type is "task".')
      sys.exit(2)
    hostname = args.ts_mon_task_hostname
    if args.ts_mon_autogen_hostname:
      hostname = 'autogen:' + hostname
    interface.state.target = targets.TaskTarget(
        args.ts_mon_task_service_name,
        args.ts_mon_task_job_name,
        args.ts_mon_task_region,
        hostname,
        args.ts_mon_task_number)

  interface.state.global_monitor = monitors.NullMonitor()

  if endpoint.startswith('file://'):
    interface.state.global_monitor = monitors.DebugMonitor(
        endpoint[len('file://'):])
  elif endpoint.startswith('pubsub://'):
    if credentials:
      url = urlparse.urlparse(endpoint)
      project = url.netloc
      topic = url.path.strip('/')
      interface.state.global_monitor = monitors.PubSubMonitor(
          credentials, project, topic, use_instrumented_http=True)
    else:
      logging.error('ts_mon monitoring is disabled because credentials are not '
                    'available')
  elif endpoint.lower() == 'none':
    logging.info('ts_mon monitoring has been explicitly disabled')
  else:
    logging.error('ts_mon monitoring is disabled because the endpoint provided'
                  ' is invalid or not supported: %s', endpoint)

  interface.state.flush_mode = args.ts_mon_flush

  if args.ts_mon_flush == 'auto':
    interface.state.flush_thread = interface._FlushThread(
        args.ts_mon_flush_interval_secs)
    interface.state.flush_thread.start()

  standard_metrics.init()
Beispiel #4
0
def process_argparse_options(args):
  """Process command line arguments to initialize the global monitor.

  Also initializes the default target if sufficient arguments are supplied.
  If they aren't, all created metrics will have to supply their own target.
  This is generally a bad idea, as many libraries rely on the default target
  being set up.

  Starts a background thread to automatically flush monitoring metrics if not
  disabled by command line arguments.

  Args:
    args (argparse.Namespace): the result of parsing the command line arguments
  """

  # Parse the config file if it exists.
  config = load_machine_config(args.ts_mon_config_file)
  endpoint = config.get('endpoint', '')
  credentials = config.get('credentials', '')

  # Command-line args override the values in the config file.
  if args.ts_mon_endpoint is not None:
    endpoint = args.ts_mon_endpoint
  if args.ts_mon_credentials is not None:
    credentials = args.ts_mon_credentials

  interface.state.global_monitor = monitors.NullMonitor()

  if endpoint.startswith('file://'):
    interface.state.global_monitor = monitors.DebugMonitor(
        endpoint[len('file://'):])
  elif credentials:
    if endpoint.startswith('pubsub://'):
      url = urlparse.urlparse(endpoint)
      project = url.netloc
      topic = url.path.strip('/')
      interface.state.global_monitor = monitors.PubSubMonitor(
          credentials, project, topic, use_instrumented_http=True)
    else:
      logging.error('Monitoring is disabled because the endpoint provided is '
                    'invalid or not supported: %s', endpoint)
  else:
    logging.error('Monitoring is disabled because credentials are not '
                  'available')

  if args.ts_mon_target_type == 'device':
    interface.state.target = targets.DeviceTarget(
        args.ts_mon_device_region,
        args.ts_mon_device_role,
        args.ts_mon_device_network,
        args.ts_mon_device_hostname)
  if args.ts_mon_target_type == 'task':  # pragma: no cover
    # Reimplement ArgumentParser.error, since we don't have access to the parser
    if not args.ts_mon_task_service_name:
      print >> sys.stderr, ('Argument --ts-mon-task-service-name must be '
                            'provided when the target type is "task".')
      sys.exit(2)
    if not args.ts_mon_task_job_name:  # pragma: no cover
      print >> sys.stderr, ('Argument --ts-mon-task-job-name must be provided '
                            'when the target type is "task".')
      sys.exit(2)
    interface.state.target = targets.TaskTarget(
        args.ts_mon_task_service_name,
        args.ts_mon_task_job_name,
        args.ts_mon_task_region,
        args.ts_mon_task_hostname,
        args.ts_mon_task_number)

  interface.state.flush_mode = args.ts_mon_flush

  if args.ts_mon_flush == 'auto':
    interface.state.flush_thread = interface._FlushThread(
        args.ts_mon_flush_interval_secs)
    interface.state.flush_thread.start()

  standard_metrics.init()
Beispiel #5
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)
 def test_up(self):
     standard_metrics.init()
     self.assertTrue(standard_metrics.up.get())
 def test_up(self):
   standard_metrics.init()
   self.assertTrue(standard_metrics.up.get())
Beispiel #8
0
def process_argparse_options(args):
    """Process command line arguments to initialize the global monitor.

  Also initializes the default target if sufficient arguments are supplied.
  If they aren't, all created metrics will have to supply their own target.
  This is generally a bad idea, as many libraries rely on the default target
  being set up.

  Starts a background thread to automatically flush monitoring metrics if not
  disabled by command line arguments.

  Args:
    args (argparse.Namespace): the result of parsing the command line arguments
  """

    # Parse the config file if it exists.
    config = load_machine_config(args.ts_mon_config_file)
    endpoint = config.get("endpoint", "")
    credentials = config.get("credentials", "")

    # Command-line args override the values in the config file.
    if args.ts_mon_endpoint:
        endpoint = args.ts_mon_endpoint
    if args.ts_mon_credentials:
        credentials = args.ts_mon_credentials

    if endpoint.startswith("file://"):
        interface.state.global_monitor = monitors.DiskMonitor(endpoint[len("file://") :])
    elif credentials:
        # If the flush mode is 'all' metrics will be sent immediately as they are
        # updated.  If this is the case, we mustn't set metrics while we're
        # sending metrics.
        use_instrumented_http = args.ts_mon_flush != "all"

        if endpoint.startswith("pubsub://"):
            url = urlparse.urlparse(endpoint)
            project = url.netloc
            topic = url.path.strip("/")
            interface.state.global_monitor = monitors.PubSubMonitor(
                credentials, project, topic, use_instrumented_http=use_instrumented_http
            )
        else:
            interface.state.global_monitor = monitors.ApiMonitor(
                credentials, endpoint, use_instrumented_http=use_instrumented_http
            )
    else:
        logging.error("Monitoring is disabled because --ts-mon-credentials was not " "set")
        interface.state.global_monitor = monitors.NullMonitor()

    if args.ts_mon_target_type == "device":
        interface.state.default_target = targets.DeviceTarget(
            args.ts_mon_device_region, args.ts_mon_device_network, args.ts_mon_device_hostname
        )
    if args.ts_mon_target_type == "task":  # pragma: no cover
        # Reimplement ArgumentParser.error, since we don't have access to the parser
        if not args.ts_mon_task_service_name:
            print >>sys.stderr, (
                "Argument --ts-mon-task-service-name must be " 'provided when the target type is "task".'
            )
            sys.exit(2)
        if not args.ts_mon_task_job_name:  # pragma: no cover
            print >>sys.stderr, ("Argument --ts-mon-task-job-name must be provided " 'when the target type is "task".')
            sys.exit(2)
        interface.state.default_target = targets.TaskTarget(
            args.ts_mon_task_service_name,
            args.ts_mon_task_job_name,
            args.ts_mon_task_region,
            args.ts_mon_task_hostname,
            args.ts_mon_task_number,
        )

    interface.state.flush_mode = args.ts_mon_flush

    if args.ts_mon_flush == "auto":
        interface.state.flush_thread = interface._FlushThread(args.ts_mon_flush_interval_secs)
        interface.state.flush_thread.start()

    standard_metrics.init()