Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

abseil interferes with python logging #99

Closed
matteby opened this issue Mar 29, 2019 · 19 comments
Closed

abseil interferes with python logging #99

matteby opened this issue Mar 29, 2019 · 19 comments
Assignees

Comments

@matteby
Copy link

matteby commented Mar 29, 2019

I have a script where I'm importing a module that internally uses abseil logging. The rest of our code base is using standard python logging. This is leading to a situation where importing that module is interfering with the rest of the code base using standard logging and causing lost log messages.

See here for a description of the issue: tensorflow/hub#263

Have others run into this issue before?

@gpshead
Copy link
Contributor

gpshead commented Mar 29, 2019

While this may not be the answer you want... they aren't lost, but anything below INFO is going to a log file by default with the absl logging handlers in place.

Call absl.logging.set_stderrthreshold('info') and you'll have log messages on stderr again. Though using absl's (Google's) standard log message format.

That is merely a workaround to get your messages in the console output again. I assume you aren't looking to depend on absl from your own code directly, that could be written conditionally within your main code after imports have been done:

# Work around TensorFlow's absl.logging depencency which alters the
# default Python logging output behavior when present.
if 'absl.logging' in sys.modules:
  import absl.logging
  absl.logging.set_stderrthreshold('info')  
  # and any other apis you want, if you want 

This is, for better or worse, currently working as intended, absl.logging installs logging handlers for the process at import time. Perhaps this should change so it could be a good citizen when used by libraries? We use it everywhere so we really hadn't given that (obvious in hingsight) idea a lot of thought.

@matteby
Copy link
Author

matteby commented Mar 30, 2019

@gpshead Thanks for the quick reply!

I tried the second workaround and that helped. For anyone else that has a similar situation, I also had to set the verbosity level:

# Work around TensorFlow's absl.logging depencency which alters the
# default Python logging output behavior when present.
import sys
if 'absl.logging' in sys.modules:
  import absl.logging
  absl.logging.set_verbosity('info')
  absl.logging.set_stderrthreshold('info')
  # and any other apis you want, if you want

+1 to your suggestion. I agree it would be nice to support use in libraries that may be used in code bases with existing logging mechanisms in place.

@dhalperi
Copy link

@gpshead have you now given any thought to this issue that you called "obvious in hindsight"?

As more and more Google-released libraries switched from not-abseil to abseil, this mucking with global state, removing existing logging handlers, overriding formats, etc. is getting really costly.

For my team, it's Capirca that's biting us. See also #102.

(cc: @tituswinters, if he's still leading Abseil)

@gpshead
Copy link
Contributor

gpshead commented May 10, 2019

There's more to this in that library code often has no need to depend on absl.logging at all. I expect most library code can import logging (the stdlib library) and use that. (I'm assuming the function calls library code should be making are the standard debug/info/warn/warning/error APIs)

Regardless of that, getting all libraries using absl in the world to stop doing from absl import logging is probably intractable in the shorter term. Making our absl.logging._initialize() call lazy so that it is only ever done when first needed, or perhaps when explicitly desired (ie: what app._run_init() does) would be helpful. Prior to absl._initialize() the absl.logging functions should just be silent redirects to the stdlib functions.

@dhalperi
Copy link

dhalperi commented May 11, 2019 via email

@yilei
Copy link
Contributor

yilei commented May 24, 2019

One idea might make it better without affecting the existing user base too much.

absl.logging uses its own logger (absl.logging._absl_logger). Logs explicitly logged by absl.logging go through this logger, which propagates to root.

At import time, instead of attaching the absl.logging._absl_handler to root here, attach it to absl.logging._absl_logger and set _absl_logger.propagate = False initially.

Then in absl.logging.use_absl_handler() (called by absl.app.run()), moves the handler to root and set _absl_logger.propagate = True again.

So if a user only uses absl.logging without absl.app.run() (that's the case for most of the users who depend on a library that uses absl.logging, but themselves don't use absl.app):

  1. It doesn't affect their root log configs, i.e. logs from the standard logging module goes to their own config
  2. Logs logged by absl.logging is still handled by absl, e.g. it has its own formatting, goes to its own destination. But that's what the library explicitly chooses to do so by using absl.logging instead of logging.

For existing absl.app users: they loose the formatting for logs from standard logging at import time. But logs from absl.logging at import time are not affected.

@gpshead
Copy link
Contributor

gpshead commented May 24, 2019

That's a bit of a mixed-world compromise. I suspect that libraries using absl.logging don't care about absl specific logging properties at all and are just using it because that is the standard style they've adopted our of habit rather than just import logging. Update such projects copybara code transforms to use that outside of Google and see if anyone notices. :) I'm making the assumption that non-Google authored code is unlikely to bother using from absl import logging directly.

Having logs go to potentially multiple different places in different formats based on which part of the code called the logging statement in a process could just make a different set of peoples lives messier and lead to questions about that being an undesired behavior people file an issue about.

@KristianHolsheimer
Copy link

KristianHolsheimer commented Jul 1, 2019

Is there any update on this? This is currently blocking updates to Tensorflow 1.14 and 2.0.

@gpshead
Copy link
Contributor

gpshead commented Jul 1, 2019

Nobody is assigned to work on this so I don't recommend blocking on a resolution.

@KristianHolsheimer
Copy link

KristianHolsheimer commented Jul 2, 2019

What would you suggest people do?

  • To start using absl for logging everywhere isn't a solution. It merely passes the problem along downstream like a hot potato (as per the example of tensorflow).
  • The workaround to remove the absl handler might break things that expect the handler to be there.

@KristianHolsheimer
Copy link

Also, what's wrong with the "mixed-world compromise" proposed by @yilei? Seems fine to me.

The alternative would be to provide a guide on "how to monkey-patch your codebase to fix a broken state caused by abseil logging", e.g. batfish/pybatfish#370.

@KristianHolsheimer
Copy link

FYI: tensorflow/tensorflow#26691 (comment)

@gpshead
Copy link
Contributor

gpshead commented Jul 3, 2019

My earlier comment answered what was wrong with mixed-world. It is cleaner to have absl.run() or absltest.main() be the installer of the absl logging handlers. Because those are delcarations of intent to do things the absl way.

That should be less complicated, less surprising, and easier to support as an API.

@yilei yilei self-assigned this Jul 19, 2019
@pwais
Copy link

pwais commented Jul 19, 2019

Another fix suggestion for those like me who are finding this bug via Google:

try:
  # FIXME(https://github.com/abseil/abseil-py/issues/99)
  # FIXME(https://github.com/abseil/abseil-py/issues/102)
  # Unfortunately, many libraries that include absl (including Tensorflow)
  # will get bitten by double-logging due to absl's incorrect use of
  # the python logging library:
  #   2019-07-19 23:47:38,829 my_logger   779 : test
  #   I0719 23:47:38.829330 139904865122112 foo.py:63] test
  #   2019-07-19 23:47:38,829 my_logger   779 : test
  #   I0719 23:47:38.829469 139904865122112 foo.py:63] test
  # The code below fixes this double-logging.  FMI see:
  #   https://github.com/tensorflow/tensorflow/issues/26691#issuecomment-500369493
  
  import logging
  
  import absl.logging
  logging.root.removeHandler(absl.logging._absl_handler)
  absl.logging._warn_preinit_stderr = False
except Exception as e:
  print("Failed to fix absl logging bug", e)
  pass

benedikt-voelkel pushed a commit to benedikt-voelkel/MachineLearningHEP that referenced this issue Jul 22, 2019
The newest version of abseil (https://github.com/abseil/abseil-py)
apparently interferes with user logging implemented via

import logging

For details see abseil/abseil-py#99

This was observed when installing the ML package from scratch during the
last week. Comparing TensorFlow versions it was observed that most
people's ML package was still using TF version 1.13.1/2. Installing the
package now leads to installing TF vesion 1.14 and hence a more recent
version of abseil as well which causes the weird logging behaviour.

A fix is possible thanks to
abseil/abseil-py#99 (comment)

As soon as this is fixed in abseil this will be propagated to the ML
package.
benedikt-voelkel pushed a commit to benedikt-voelkel/MachineLearningHEP that referenced this issue Jul 22, 2019
The newest version of abseil (https://github.com/abseil/abseil-py)
apparently interferes with user logging implemented via

import logging

For details see abseil/abseil-py#99

This was observed when installing the ML package from scratch during the
last week. Comparing TensorFlow versions it was observed that most
people's ML package was still using TF version 1.13.1/2. Installing the
package now leads to installing TF vesion 1.14 and hence a more recent
version of abseil as well which causes the weird logging behaviour.

A fix is possible thanks to
abseil/abseil-py#99 (comment)

As soon as this is fixed in abseil this will be propagated to the ML
package.
benedikt-voelkel pushed a commit to benedikt-voelkel/MachineLearningHEP that referenced this issue Jul 22, 2019
The newest version of abseil (https://github.com/abseil/abseil-py)
apparently interferes with user logging implemented via

import logging

For details see abseil/abseil-py#99

This was observed when installing the ML package from scratch during the
last week. Comparing TensorFlow versions it was observed that most
people's ML package was still using TF version 1.13.1/2. Installing the
package now leads to installing TF vesion 1.14 and hence a more recent
version of abseil as well which causes the weird logging behaviour.

A fix is possible thanks to
abseil/abseil-py#99 (comment)

As soon as this is fixed in abseil this will be propagated to the ML
package.
ginnocen pushed a commit to alisw/MachineLearningHEP that referenced this issue Jul 22, 2019
The newest version of abseil (https://github.com/abseil/abseil-py)
apparently interferes with user logging implemented via

import logging

For details see abseil/abseil-py#99

This was observed when installing the ML package from scratch during the
last week. Comparing TensorFlow versions it was observed that most
people's ML package was still using TF version 1.13.1/2. Installing the
package now leads to installing TF vesion 1.14 and hence a more recent
version of abseil as well which causes the weird logging behaviour.

A fix is possible thanks to
abseil/abseil-py#99 (comment)

As soon as this is fixed in abseil this will be propagated to the ML
package.
epa095 pushed a commit to epa095/gordo-components that referenced this issue Aug 16, 2019
Tensorflow imports absl, and it breaks the standard logging module in
python by setting a handler on the root-level logger. The result is
that the log-level does not get set, and the format is all wrong.
This patch introduces an ugly fix I found on the internet to handle it.
Hopefully we can delete it in the future.

References:
tensorflow/tensorflow#29842
tensorflow/tensorflow#26691
abseil/abseil-py#99
epa095 pushed a commit to epa095/gordo-components that referenced this issue Aug 16, 2019
Tensorflow imports absl, and it breaks the standard logging module in
python by setting a handler on the root-level logger. The result is
that the log-level does not get set, and the format is all wrong.
This patch introduces an ugly fix I found on the internet to handle it.
Hopefully we can delete it in the future.

References:
tensorflow/tensorflow#29842
tensorflow/tensorflow#26691
abseil/abseil-py#99
epa095 pushed a commit to epa095/gordo-components that referenced this issue Aug 16, 2019
Tensorflow imports absl, and it breaks the standard logging module in
python by setting a handler on the root-level logger. The result is
that the log-level does not get set, and the format is all wrong.
This patch introduces an ugly fix I found on the internet to handle it.
Hopefully we can delete it in the future.

References:
tensorflow/tensorflow#29842
tensorflow/tensorflow#26691
abseil/abseil-py#99
epa095 pushed a commit to epa095/gordo-components that referenced this issue Aug 16, 2019
Tensorflow imports absl, and it breaks the standard logging module in
python by setting a handler on the root-level logger. The result is
that the log-level does not get set, and the format is all wrong.
This patch introduces an ugly fix I found on the internet to handle it.
Hopefully we can delete it in the future.

References:
tensorflow/tensorflow#29842
tensorflow/tensorflow#26691
abseil/abseil-py#99
@jklaise
Copy link

jklaise commented Aug 16, 2019

Is there any movement on this? This is a pretty huge bug to have...

epa095 pushed a commit to epa095/gordo-components that referenced this issue Aug 16, 2019
Tensorflow imports absl, and it breaks the standard logging module in
python by setting a handler on the root-level logger. The result is
that the log-level does not get set, and the format is all wrong.
This patch introduces an ugly fix I found on the internet to handle it.
Hopefully we can delete it in the future.

References:
tensorflow/tensorflow#29842
tensorflow/tensorflow#26691
abseil/abseil-py#99
epa095 pushed a commit to equinor/gordo that referenced this issue Aug 16, 2019
Tensorflow imports absl, and it breaks the standard logging module in
python by setting a handler on the root-level logger. The result is
that the log-level does not get set, and the format is all wrong.
This patch introduces an ugly fix I found on the internet to handle it.
Hopefully we can delete it in the future.

References:
tensorflow/tensorflow#29842
tensorflow/tensorflow#26691
abseil/abseil-py#99
@yilei
Copy link
Contributor

yilei commented Aug 16, 2019

We have a fix and should be pushed out in a week or two.

@Lothiraldan
Copy link

It doesn't seems to be an issue as long as we don't use the root logger. We define our logger like this in all our files:

LOGGER = logging.getLogger(__name__)

And then set the propagate to False on the package level logger:

logging.getLogger(__package__).propagate = False

If that can helps someone.

yilei added a commit to yilei/abseil-py that referenced this issue Aug 26, 2019
Changelog:

### Added

*   (testing) `absltest.expectedFailureIf`: a variant of
    `unittest.expectedFailure` that allows a condition to be given.

### Changed

*   (bazel) Tests now pass when bazel
    `--incompatible_allow_python_version_transitions=true` is set.
*   (bazel) Both Python 2 and Python 3 versions of tests are now created. To
    only run one major Python version, use
    `bazel test --test_tag_filters=-python[23]` to ignore the other version.
*   (testing) `assertTotallyOrdered` no longer requires objects to implement
    `__hash__`.
*   (testing) `absltest` now integrates better with `--pdb_post_mortem`.
*   (testing) `xml_reporter` now includes timestamps to testcases, test_suite,
    test_suites elements.

### Fixed

*    abseil#99: `absl.logging` no longer registers itself to `logging.root` at import
     time.
*    abseil#108: Tests now pass with Bazel 0.28.0 on macOS.

PiperOrigin-RevId: 265519766
Change-Id: Ie80c838f2436cd0c7407f29ca29e74e0abe4c4da
@yilei
Copy link
Contributor

yilei commented Aug 27, 2019

Version 0.8.0 is released on PyPI, absl.logging no longer registers itself at import time.

Relevant commits: 05c000a and d162b02

@KristianHolsheimer
Copy link

KristianHolsheimer commented Aug 28, 2019

Thanks so much for fixing this @yilei

dhalperi added a commit to dhalperi/pybatfish that referenced this issue Sep 10, 2019
In the latest release of absl-py common library, Google fixed the logging
mess. Force a minimum version of that library and remove the hack.

abseil/abseil-py#99
dhalperi added a commit to batfish/pybatfish that referenced this issue Sep 10, 2019
In the latest release of absl-py common library, Google fixed the logging
mess. Force a minimum version of that library and remove the hack.

abseil/abseil-py#99
KristianHolsheimer added a commit to KristianHolsheimer/keras-gym that referenced this issue Oct 14, 2019
KristianHolsheimer added a commit to KristianHolsheimer/keras-gym that referenced this issue Oct 15, 2019
bittremieux added a commit to bittremieux-lab/GLEAMS that referenced this issue Aug 4, 2020
stas00 added a commit to huggingface/transformers that referenced this issue Dec 23, 2021
the absl workaround hasn't been needed since 2019-04 abseil/abseil-py#99 so it should be safe to remove it.
sgugger pushed a commit to huggingface/transformers that referenced this issue Dec 29, 2021
the absl workaround hasn't been needed since 2019-04 abseil/abseil-py#99 so it should be safe to remove it.
stevhliu pushed a commit to stevhliu/transformers that referenced this issue Jan 6, 2022
the absl workaround hasn't been needed since 2019-04 abseil/abseil-py#99 so it should be safe to remove it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants