Google-cloud-python: Every error that is not catchable by the user should be logged via the logging module

Created on 12 Mar 2018  路  2Comments  路  Source: googleapis/google-cloud-python

Currently, at the very least helper threads for pubsub seem to not and they let the exception bubble up and get printed to stderr.

I think this is bad form, there's nothing _I_ can do to catch this error, but it'd be nice if I could get it logged in the format I want.

question pubsub logging

Most helpful comment

I think you misunderstood the problem. Firstly, we do have logging set up. Everything above INFO on the root logger goes through our handler. And, yet, we end up errors in the logs that don't have a jsonPayload and none of our metadata, only a textPayload. The errrors I'm talking about look like this:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 54, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/newrelic/api/external_trace.py", line 40, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/grpc/_channel.py", line 492, in __call__
    return _end_unary_response_blocking(state, call, False, deadline)
  File "/usr/local/lib/python3.6/site-packages/grpc/_channel.py", line 440, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.UNAUTHENTICATED, Deadline Exceeded)>

and

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/publisher/batch/thread.py", line 239, in monitor
    return self._commit()
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/publisher/batch/thread.py", line 204, in _commit
    self._messages,
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/gapic/publisher_client.py", line 325, in publish
    return self._publish(request, retry=retry, timeout=timeout)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/gapic_v1/method.py", line 139, in __call__
    return wrapped_func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/retry.py", line 260, in retry_wrapped_func
    on_error=on_error,
  File "/usr/local/lib/python3.6/site-packages/google/api_core/retry.py", line 177, in retry_target
    return target()
  File "/usr/local/lib/python3.6/site-packages/google/api_core/timeout.py", line 206, in func_with_timeout
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 56, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.Unauthenticated: 401 Deadline Exceeded

As you see, the last one bubbles up all the way to the thread and gets handled there. There's no way for us to catch these and log them correctly. An artefact of the lack of logging support the fact that they're not linked together, since the parser seems to be unable to figure they're linked since we have more than one worker logging there and I guess another process is logging around the same time. In the containers where we only have one process, they get grouped together correctly:

Exception in thread Thread-MonitorBatchPublisher:
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 54, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/newrelic/api/external_trace.py", line 40, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/grpc/_channel.py", line 492, in __call__
    return _end_unary_response_blocking(state, call, False, deadline)
  File "/usr/local/lib/python3.6/site-packages/grpc/_channel.py", line 440, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.UNAUTHENTICATED, Deadline Exceeded)>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/publisher/batch/thread.py", line 239, in monitor
    return self._commit()
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/publisher/batch/thread.py", line 204, in _commit
    self._messages,
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/gapic/publisher_client.py", line 325, in publish
    return self._publish(request, retry=retry, timeout=timeout)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/gapic_v1/method.py", line 139, in __call__
    return wrapped_func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/retry.py", line 260, in retry_wrapped_func
    on_error=on_error,
  File "/usr/local/lib/python3.6/site-packages/google/api_core/retry.py", line 177, in retry_target
    return target()
  File "/usr/local/lib/python3.6/site-packages/google/api_core/timeout.py", line 206, in func_with_timeout
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 56, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.Unauthenticated: 401 Deadline Exceeded

All 2 comments

We handle this by explicitly adding a handler to the root logger.

https://googlecloudplatform.github.io/google-cloud-python/latest/logging/usage.html#integration-with-python-logging-module

I think you misunderstood the problem. Firstly, we do have logging set up. Everything above INFO on the root logger goes through our handler. And, yet, we end up errors in the logs that don't have a jsonPayload and none of our metadata, only a textPayload. The errrors I'm talking about look like this:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 54, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/newrelic/api/external_trace.py", line 40, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/grpc/_channel.py", line 492, in __call__
    return _end_unary_response_blocking(state, call, False, deadline)
  File "/usr/local/lib/python3.6/site-packages/grpc/_channel.py", line 440, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.UNAUTHENTICATED, Deadline Exceeded)>

and

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/publisher/batch/thread.py", line 239, in monitor
    return self._commit()
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/publisher/batch/thread.py", line 204, in _commit
    self._messages,
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/gapic/publisher_client.py", line 325, in publish
    return self._publish(request, retry=retry, timeout=timeout)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/gapic_v1/method.py", line 139, in __call__
    return wrapped_func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/retry.py", line 260, in retry_wrapped_func
    on_error=on_error,
  File "/usr/local/lib/python3.6/site-packages/google/api_core/retry.py", line 177, in retry_target
    return target()
  File "/usr/local/lib/python3.6/site-packages/google/api_core/timeout.py", line 206, in func_with_timeout
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 56, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.Unauthenticated: 401 Deadline Exceeded

As you see, the last one bubbles up all the way to the thread and gets handled there. There's no way for us to catch these and log them correctly. An artefact of the lack of logging support the fact that they're not linked together, since the parser seems to be unable to figure they're linked since we have more than one worker logging there and I guess another process is logging around the same time. In the containers where we only have one process, they get grouped together correctly:

Exception in thread Thread-MonitorBatchPublisher:
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 54, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/newrelic/api/external_trace.py", line 40, in dynamic_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/grpc/_channel.py", line 492, in __call__
    return _end_unary_response_blocking(state, call, False, deadline)
  File "/usr/local/lib/python3.6/site-packages/grpc/_channel.py", line 440, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with (StatusCode.UNAUTHENTICATED, Deadline Exceeded)>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/publisher/batch/thread.py", line 239, in monitor
    return self._commit()
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/publisher/batch/thread.py", line 204, in _commit
    self._messages,
  File "/usr/local/lib/python3.6/site-packages/google/cloud/pubsub_v1/gapic/publisher_client.py", line 325, in publish
    return self._publish(request, retry=retry, timeout=timeout)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/gapic_v1/method.py", line 139, in __call__
    return wrapped_func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/retry.py", line 260, in retry_wrapped_func
    on_error=on_error,
  File "/usr/local/lib/python3.6/site-packages/google/api_core/retry.py", line 177, in retry_target
    return target()
  File "/usr/local/lib/python3.6/site-packages/google/api_core/timeout.py", line 206, in func_with_timeout
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 56, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.Unauthenticated: 401 Deadline Exceeded
Was this page helpful?
0 / 5 - 0 ratings

Related issues

VikramTiwari picture VikramTiwari  路  3Comments

VikramTiwari picture VikramTiwari  路  4Comments

stevenschlansker picture stevenschlansker  路  3Comments

mgoddard-pivotal picture mgoddard-pivotal  路  3Comments

ramuta picture ramuta  路  3Comments