Example #1
0
    def _process(self, create_task, task_name):
        task_id = default_cache.get(self.task_id_cache_key)
        json_response = None

        with self.sess:
            try:
                if task_id:
                    # Processing has already started and we need to poll
                    # symbolicator for an update. This in turn may put us back into
                    # the queue.
                    json_response = self.sess.query_task(task_id)

                if json_response is None:
                    # This is a new task, so we compute all request parameters
                    # (potentially expensive if we need to pull minidumps), and then
                    # upload all information to symbolicator. It will likely not
                    # have a response ready immediately, so we start polling after
                    # some timeout.
                    json_response = create_task()
            except ServiceUnavailable:
                # 503 can indicate that symbolicator is restarting. Wait for a
                # reboot, then try again. This overrides the default behavior of
                # retrying after just a second.
                #
                # If there is no response attached, it's a connection error.
                raise RetrySymbolication(
                    retry_after=settings.SYMBOLICATOR_MAX_RETRY_AFTER)

            metrics.incr(
                "events.symbolicator.response",
                tags={
                    "response": json_response.get("status") or "null",
                    "task_name": task_name
                },
            )

            # Symbolication is still in progress. Bail out and try again
            # after some timeout. Symbolicator keeps the response for the
            # first one to poll it.
            if json_response["status"] == "pending":
                default_cache.set(self.task_id_cache_key,
                                  json_response["request_id"],
                                  REQUEST_CACHE_TIMEOUT)
                raise RetrySymbolication(
                    retry_after=json_response["retry_after"])
            else:
                # Once we arrive here, we are done processing. Clean up the
                # task id from the cache.
                default_cache.delete(self.task_id_cache_key)
                metrics.timing("events.symbolicator.response.completed.size",
                               len(json.dumps(json_response)))
                reverse_source_aliases(json_response)
                redact_internal_sources(json_response)
                return json_response
Example #2
0
    def _process(self, create_task):
        task_id = default_cache.get(self.task_id_cache_key)
        json = None

        with self.sess:
            try:
                if task_id:
                    # Processing has already started and we need to poll
                    # symbolicator for an update. This in turn may put us back into
                    # the queue.
                    json = self.sess.query_task(task_id)

                if json is None:
                    # This is a new task, so we compute all request parameters
                    # (potentially expensive if we need to pull minidumps), and then
                    # upload all information to symbolicator. It will likely not
                    # have a response ready immediately, so we start polling after
                    # some timeout.
                    json = create_task()
            except ServiceUnavailable:
                # 503 can indicate that symbolicator is restarting. Wait for a
                # reboot, then try again. This overrides the default behavior of
                # retrying after just a second.
                #
                # If there is no response attached, it's a connection error.
                raise RetrySymbolication(retry_after=10)

            metrics.incr('events.symbolicator.response', tags={
                'response': json.get('status') or 'null',
                'project_id': self.sess.project_id,
            })

            # Symbolication is still in progress. Bail out and try again
            # after some timeout. Symbolicator keeps the response for the
            # first one to poll it.
            if json['status'] == 'pending':
                default_cache.set(
                    self.task_id_cache_key,
                    json['request_id'],
                    REQUEST_CACHE_TIMEOUT)
                raise RetrySymbolication(retry_after=json['retry_after'])
            else:
                # Once we arrive here, we are done processing. Clean up the
                # task id from the cache.
                default_cache.delete(self.task_id_cache_key)
                return json
Example #3
0
def run_symbolicator(stacktraces, modules, project, arch, signal,
                     request_id_cache_key):
    internal_url_prefix = options.get('system.internal-url-prefix') \
        or options.get('system.url-prefix')

    assert internal_url_prefix
    sentry_source_url = '%s%s' % (
        internal_url_prefix.rstrip('/'),
        reverse('sentry-api-0-dsym-files',
                kwargs={
                    'organization_slug': project.organization.slug,
                    'project_slug': project.slug
                }))

    symbolicator_options = options.get('symbolicator.options')
    base_url = symbolicator_options['url'].rstrip('/')
    assert base_url

    project_id = six.text_type(project.id)
    request_id = default_cache.get(request_id_cache_key)
    sess = Session()

    attempts = 0
    wait = 0.5

    with sess:
        while 1:
            try:

                if request_id:
                    rv = _poll_symbolication_task(sess=sess,
                                                  base_url=base_url,
                                                  request_id=request_id)
                else:
                    rv = _create_symbolication_task(
                        sess=sess,
                        base_url=base_url,
                        project_id=project_id,
                        sentry_source_url=sentry_source_url,
                        signal=signal,
                        stacktraces=stacktraces,
                        modules=modules)

                metrics.incr('events.symbolicator.status.%s' % rv.status_code,
                             tags={'project_id': project_id})

                if rv.status_code == 404 and request_id:
                    default_cache.delete(request_id_cache_key)
                    request_id = None
                    continue
                elif rv.status_code == 503:
                    raise RetrySymbolication(retry_after=10)

                rv.raise_for_status()
                json = rv.json()
                metrics.incr('events.symbolicator.response.%s' %
                             json['status'],
                             tags={'project_id': project_id})

                if json['status'] == 'pending':
                    default_cache.set(request_id_cache_key, json['request_id'],
                                      REQUEST_CACHE_TIMEOUT)
                    raise RetrySymbolication(retry_after=json['retry_after'])
                elif json['status'] == 'completed':
                    default_cache.delete(request_id_cache_key)
                    return rv.json()
                else:
                    logger.error("Unexpected status: %s", json['status'])
                    default_cache.delete(request_id_cache_key)
                    return

            except (IOError, RequestException):
                attempts += 1
                if attempts > MAX_ATTEMPTS:
                    logger.error('Failed to contact symbolicator',
                                 exc_info=True)
                    default_cache.delete(request_id_cache_key)
                    return

                time.sleep(wait)
                wait *= 2.0
Example #4
0
def run_symbolicator(stacktraces, modules, project, arch, signal,
                     request_id_cache_key):
    symbolicator_options = options.get('symbolicator.options')
    base_url = symbolicator_options['url'].rstrip('/')
    assert base_url

    project_id = six.text_type(project.id)
    request_id = default_cache.get(request_id_cache_key)
    sess = Session()

    # Will be set lazily when a symbolicator request is fired
    sources = None

    attempts = 0
    wait = 0.5

    with sess:
        while True:
            try:
                if request_id:
                    rv = _poll_symbolication_task(sess=sess,
                                                  base_url=base_url,
                                                  request_id=request_id)
                else:
                    if sources is None:
                        sources = get_sources_for_project(project)

                    rv = _create_symbolication_task(sess=sess,
                                                    base_url=base_url,
                                                    project_id=project_id,
                                                    sources=sources,
                                                    signal=signal,
                                                    stacktraces=stacktraces,
                                                    modules=modules)

                metrics.incr('events.symbolicator.status_code',
                             tags={
                                 'status_code': rv.status_code,
                                 'project_id': project_id,
                             })

                if rv.status_code == 404 and request_id:
                    default_cache.delete(request_id_cache_key)
                    request_id = None
                    continue
                elif rv.status_code == 503:
                    raise RetrySymbolication(retry_after=10)

                rv.raise_for_status()
                json = rv.json()
                metrics.incr('events.symbolicator.response',
                             tags={
                                 'response': json['status'],
                                 'project_id': project_id,
                             })

                if json['status'] == 'pending':
                    default_cache.set(request_id_cache_key, json['request_id'],
                                      REQUEST_CACHE_TIMEOUT)
                    raise RetrySymbolication(retry_after=json['retry_after'])
                elif json['status'] == 'completed':
                    default_cache.delete(request_id_cache_key)
                    return rv.json()
                else:
                    logger.error("Unexpected status: %s", json['status'])
                    default_cache.delete(request_id_cache_key)
                    return

            except (IOError, RequestException):
                attempts += 1
                if attempts > MAX_ATTEMPTS:
                    logger.error('Failed to contact symbolicator',
                                 exc_info=True)
                    default_cache.delete(request_id_cache_key)
                    return

                time.sleep(wait)
                wait *= 2.0