Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Improve logging #579

Merged
merged 54 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
0f318a9
Setup logger for package.
Mar 4, 2020
5e4b710
Add job submission logging messages.
Mar 5, 2020
43480d4
revise log message
Mar 5, 2020
d679496
Merge branch 'master' into improve-logging
Mar 5, 2020
461fa95
review comments
Mar 5, 2020
3b55797
update docstring.
Mar 6, 2020
742aee2
seperate console and file logging.
Mar 9, 2020
4eec085
remove logging from rest endpoints.
Mar 9, 2020
ce535ce
add logging to session.request
Mar 9, 2020
c16b442
refactor setup_logger
Mar 9, 2020
3a10fb9
update docstring
Mar 9, 2020
df7d67f
resolve merge conflicts
Mar 9, 2020
678b8b0
censor the apiToken
Mar 9, 2020
a0f397b
use appropriate formatting for logging
Mar 9, 2020
8ff3823
resolve merge conflicts.
Mar 10, 2020
0f8dff9
review comments
Mar 10, 2020
e3b6045
write tests for logger.
Mar 10, 2020
a867df2
fix lint
Mar 10, 2020
42fed5c
update docstrings.
Mar 11, 2020
c14b699
add response data
Mar 11, 2020
a38d0ed
Merge branch 'master' into improve-logging
Mar 11, 2020
7aa0541
update changelog
Mar 11, 2020
6ee98e2
style fixes
Mar 11, 2020
6364d6b
update changelog
Mar 11, 2020
4ed6177
review comments for tests.
Mar 11, 2020
7654786
move log level setting placement.
Mar 11, 2020
2e66d4e
update docs
Mar 11, 2020
f0831c2
add chained exception logging.
Mar 12, 2020
0e216d7
Use NamedTemporaryFile for log file test.
Mar 12, 2020
c7ec836
fix style.
Mar 12, 2020
9f55308
cleanup methods.
Mar 12, 2020
0da5791
fiter websocket response for logging.
Mar 12, 2020
7eeef24
filter session request information.
Mar 12, 2020
0a3f75b
Merge branch 'master' into improve-logging
Mar 12, 2020
2617b73
filter device name from job sumission response data
Mar 12, 2020
d30f24c
update docstrings.
Mar 12, 2020
88de18b
change param name
Mar 13, 2020
7c855a8
make substring test subTest
Mar 13, 2020
668ece4
Fix regex and add more context
Mar 13, 2020
ec8e988
resolve merge conflicts.
Mar 16, 2020
325e4f9
review changes
Mar 16, 2020
5d9aa36
Avoid making multiple status calls least_busy
Mar 16, 2020
2d46528
only log job submission for post requests
Mar 16, 2020
9e1adbc
Merge branch 'master' into improve-logging
Mar 16, 2020
c93d1dd
remove duplicate retrieve_job
Mar 16, 2020
cbfd71e
filter out GET request data.
Mar 17, 2020
5275631
change level to getEffectiveLevel.
Mar 17, 2020
2cc0873
Refactor log filtering in session.
Mar 17, 2020
8fc350d
reuse LOG_LEVEL if provider logger not set
Mar 17, 2020
b458f95
fix lint
Mar 17, 2020
57af448
Do not log request_data for certain urls.
Mar 17, 2020
7def1f1
refactor logging filtering in session.
Mar 17, 2020
33e0a10
review comments.
Mar 17, 2020
b9606bb
move log messages before object storage requests.
Mar 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions qiskit/providers/ibmq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@
IBMQ = IBMQFactory()
"""A global instance of an account manager that is used as the entry point for convenience."""

# Constants used by the IBM Quantum logger.
IBMQ_PROVIDER_LOGGER_NAME = 'qiskit.providers.ibmq'
"""The name of the IBM Quantum logger."""
QISKIT_IBMQ_PROVIDER_LOG_LEVEL = 'QISKIT_IBMQ_PROVIDER_LOG_LEVEL'
"""The environment variable name that is used to set the level for the IBM Quantum logger."""
QISKIT_IBMQ_PROVIDER_LOG_FILE = 'QISKIT_IBMQ_PROVIDER_LOG_FILE'
"""The environment variable name that is used to set the file for the IBM Quantum logger."""


def least_busy(backends: List[BaseBackend]) -> BaseBackend:
"""Return the least busy backend from a list.
Expand All @@ -121,13 +129,8 @@ def least_busy(backends: List[BaseBackend]) -> BaseBackend:
does not have the ``pending_jobs`` attribute in its status.
"""
try:
backends_to_filter = {}
for backend in backends:
backend_status = backend.status()
if backend_status.operational:
backends_to_filter[backend] = backend_status

return min(backends_to_filter.keys(), key=lambda b: backends_to_filter[b].pending_jobs)
return min([b for b in backends if b.status().operational],
key=lambda b: b.status().pending_jobs)
except (ValueError, TypeError):
raise IBMQError('Unable to find the least_busy '
'backend from an empty list.') from None
Expand Down
8 changes: 7 additions & 1 deletion qiskit/providers/ibmq/api/rest/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

"""Job REST adapter."""

import logging
import pprint
import json
from json.decoder import JSONDecodeError
Expand All @@ -28,6 +29,8 @@
from ..session import RetrySession
from ..exceptions import ApiIBMQProtocolError

logger = logging.getLogger(__name__)


class Job(RestAdapterBase):
"""Rest adapter for job related endpoints."""
Expand Down Expand Up @@ -170,6 +173,7 @@ def put_object_storage(self, url: str, qobj_dict: Dict[str, Any]) -> str:
"""
data = json.dumps(qobj_dict, cls=json_encoder.IQXJsonEconder)
response = self.session.put(url, data=data, bare=True)
logger.debug('Uploading Qobj to object storage.')
lgarc15 marked this conversation as resolved.
Show resolved Hide resolved
return response.text

def get_object_storage(self, url: str) -> Dict[str, Any]:
Expand All @@ -181,4 +185,6 @@ def get_object_storage(self, url: str) -> Dict[str, Any]:
Returns:
JSON response.
"""
return self.session.get(url, bare=True).json()
response = self.session.get(url, bare=True).json()
logger.debug('Downloading Qobj from object storage.')
return response
23 changes: 9 additions & 14 deletions qiskit/providers/ibmq/api/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def request( # type: ignore[override]
try:
response = super().request(method, final_url, **kwargs)
response.raise_for_status()
self._log_request_info(url, bare, method, kwargs)
self._log_request_info(url, method, kwargs)
except RequestException as ex:
# Wrap the requests exceptions into a IBM Q custom one, for
# compatibility.
Expand Down Expand Up @@ -272,7 +272,6 @@ def _modify_chained_exception_messages(self, exc: BaseException) -> None:
def _log_request_info(
self,
url: str,
bare: bool,
method: str,
request_data: Dict[str, Any]
) -> None:
Expand All @@ -290,7 +289,6 @@ def _log_request_info(

Args:
url: URL for the new request.
bare: Whether the input `url` is modified.
method: Method for the new request (e.g. ``POST``)
request_data:Additional arguments for the request.

Expand All @@ -311,36 +309,33 @@ def _log_request_info(
logger.debug('Endpoint: %s. Method: %s. Request Data: %s.',
filtered_url, method, request_data)
else:
if bare:
if method == 'PUT':
logger.debug('Uploading Qobj to object storage.')
elif method == 'GET':
logger.debug('Downloading Qobj from object storage.')
else:
logger.debug('Endpoint: %s. Method: %s.', filtered_url, method)
logger.debug('Endpoint: %s. Method: %s.', filtered_url, method)
except Exception as ex: # pylint: disable=broad-except
# Catch general exception so as not to disturb the program if filtering fails.
logger.info('Filtering failed when logging request information: %s', str(ex))

def _is_worth_logging(self, endpoint_url: str) -> bool:
"""Returns whether the endpoint URL should be logged.

The checks in place help filter out logs that would add noise and no helpful information.
The checks in place help filter out endpoint URL logs that would add noise
and no helpful information.

Note:
The following endpoint URLs are not logged: ``/devices/v/1`` and
``/devices/<device_name>/queue/status``. Likewise, the endpoint URLs that start
with ``/users`` and ``/version`` are not logged.
with ``/users`` or ``/version``, or contain 'objectstorage', are not logged.

Args:
endpoint_url: The endpoint URL to log.
endpoint_url: The endpoint URL that will be logged.

Returns:
Whether the endpoint URL should be logged.
"""
if endpoint_url in ('/devices/.../queue/status', '/devices/v/1'):
return False
if endpoint_url.startswith(('/users', '/version')):
return False
if endpoint_url in ('/devices/.../queue/status', '/devices/v/1'):
if 'objectstorage' in endpoint_url:
return False

return True
5 changes: 1 addition & 4 deletions test/ibmq/test_ibmq_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,11 @@
from tempfile import NamedTemporaryFile
from unittest import skipIf, mock

from qiskit.providers.ibmq import (QISKIT_IBMQ_PROVIDER_LOG_LEVEL, QISKIT_IBMQ_PROVIDER_LOG_FILE)
from qiskit.providers.ibmq.utils.utils import setup_logger

from ..ibmqtestcase import IBMQTestCase

# Constants used by `TestLogger`.
QISKIT_IBMQ_PROVIDER_LOG_LEVEL = 'QISKIT_IBMQ_PROVIDER_LOG_LEVEL'
QISKIT_IBMQ_PROVIDER_LOG_FILE = 'QISKIT_IBMQ_PROVIDER_LOG_FILE'


class TestLogger(IBMQTestCase):
"""Tests related to logger setup via ``setup_logger()``."""
Expand Down
3 changes: 1 addition & 2 deletions test/ibmqtestcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@

from qiskit.test import QiskitTestCase

# Name of the ibmq provider modules logger.
IBMQ_PROVIDER_LOGGER_NAME = 'qiskit.providers.ibmq'
from qiskit.providers.ibmq import IBMQ_PROVIDER_LOGGER_NAME


class IBMQTestCase(QiskitTestCase):
Expand Down