Skip to content

Commit ab80891

Browse files
committed
use hardcoded logging names instead of __name__ (#212)
`__name__` is only the module name, so in e.g. `elasticapm.intrumentation.packages.base`, the logger name would be `base`. By prefixing all logger names with `elasticapm`, it should be easier to filter/debug log messages from elasticapm itself. Additionally, this PR also contains tests for some of our logging. closes #212
1 parent bb56977 commit ab80891

File tree

6 files changed

+50
-25
lines changed

6 files changed

+50
-25
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
=== Unreleased
1313
https://github.com/elastic/apm-agent-python/compare/v2.1.1\...master[Check the HEAD diff]
1414

15+
* introduced consistent logger name scheme for all elasticapm internal log messages ({pull}212[#212])
1516
* added instrumentation of elasticsearch-py ({pull}191[#191])
1617
* added Flask 1.0 to the test matrix ({pull}207[#207])
1718
* fixed an issue with our minimalistic SQL parser and "fully qualified" table names ({pull}206[#206])

elasticapm/contrib/django/handlers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from elasticapm.handlers.logging import LoggingHandler as BaseLoggingHandler
2222

23-
logger = logging.getLogger(__name__)
23+
logger = logging.getLogger('elasticapm.logging')
2424

2525

2626
class LoggingHandler(BaseLoggingHandler):

elasticapm/events.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
__all__ = ('BaseEvent', 'Exception', 'Message')
2222

23-
logger = logging.getLogger(__name__)
23+
logger = logging.getLogger('elasticapm.events')
2424

2525

2626
class BaseEvent(object):

elasticapm/instrumentation/packages/base.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from elasticapm.traces import get_transaction
66
from elasticapm.utils import wrapt
77

8-
logger = logging.getLogger(__name__)
8+
logger = logging.getLogger('elasticapm.instrument')
99

1010

1111
class AbstractInstrumentedModule(object):
@@ -49,12 +49,12 @@ def instrument(self):
4949

5050
skip_env_var = 'SKIP_INSTRUMENT_' + str(self.name.upper())
5151
if skip_env_var in os.environ:
52-
logger.debug("Skipping instrumentation of %s. %s is set.",
53-
self.name, skip_env_var)
52+
logger.debug("Skipping instrumentation of %s. %s is set.", self.name, skip_env_var)
5453
return
5554
try:
5655
instrument_list = self.get_instrument_list()
5756
skipped_modules = set()
57+
instrumented_methods = []
5858

5959
for module, method in instrument_list:
6060
try:
@@ -70,32 +70,35 @@ def instrument(self):
7070
functools.partial(self.call_if_sampling, module, method),
7171
)
7272
wrapt.apply_patch(parent, attribute, wrapper)
73+
instrumented_methods.append((module, method))
7374
except ImportError:
7475
# Could not import module
75-
logger.debug("Skipping instrumentation of %s."
76-
" Module %s not found",
77-
self.name, module)
76+
logger.debug("Skipping instrumentation of %s. Module %s not found", self.name, module)
7877

7978
# Keep track of modules we couldn't load so we don't
8079
# try to instrument anything in that module again
8180
skipped_modules.add(module)
8281
except AttributeError as ex:
8382
# Could not find thing in module
84-
logger.debug("Skipping instrumentation of %s.%s: %s",
85-
module, method, ex)
83+
logger.debug("Skipping instrumentation of %s.%s: %s", module, method, ex)
84+
if instrumented_methods:
85+
logger.debug("Instrumented %s, %s", self.name, ', '.join('.'.join(m) for m in instrumented_methods))
8686

8787
except ImportError as ex:
88-
logger.debug("Skipping instrumentation of %s. %s",
89-
self.name, ex)
88+
logger.debug("Skipping instrumentation of %s. %s", self.name, ex)
9089
self.instrumented = True
9190

9291
def uninstrument(self):
9392
if not self.instrumented or not self.originals:
9493
return
94+
uninstrumented_methods = []
9595
for module, method in self.get_instrument_list():
9696
if (module, method) in self.originals:
9797
parent, attribute, wrapper = wrapt.resolve_path(module, method)
9898
wrapt.apply_patch(parent, attribute, self.originals[(module, method)])
99+
uninstrumented_methods.append((module, method))
100+
if uninstrumented_methods:
101+
logger.debug("Uninstrumented %s, %s", self.name, ', '.join('.'.join(m) for m in uninstrumented_methods))
99102
self.instrumented = False
100103
self.originals = {}
101104

elasticapm/transport/http.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
HTTPTransportBase)
1313
from elasticapm.utils import compat
1414

15-
logger = logging.getLogger(__name__)
15+
logger = logging.getLogger('elasticapm.transport.http')
1616

1717

1818
class Transport(HTTPTransportBase):

tests/instrumentation/base_tests.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class _TestInstrumentNonExistingFunctionOnModule(AbstractInstrumentedModule):
2525
class _TestInstrumentNonExistingMethod(AbstractInstrumentedModule):
2626
name = "test_non_existing_method_instrumentation"
2727
instrument_list = [
28-
("dict", "non_existing_method"),
28+
("logging", "Logger.non_existing_method"),
2929
]
3030

3131

@@ -47,36 +47,54 @@ def test_instrument_nonexisting_method_on_module():
4747
_TestInstrumentNonExistingFunctionOnModule().instrument()
4848

4949

50-
def test_instrument_nonexisting_method():
51-
_TestInstrumentNonExistingMethod().instrument()
50+
def test_instrument_nonexisting_method(caplog):
51+
with caplog.at_level(logging.DEBUG, 'elasticapm.instrument'):
52+
_TestInstrumentNonExistingMethod().instrument()
53+
record = caplog.records[0]
54+
assert 'has no attribute' in record.message
5255

5356

5457
@pytest.mark.skipif(compat.PY3, reason="different object model")
55-
def test_uninstrument_py2():
58+
def test_uninstrument_py2(caplog):
5659
assert isinstance(Dummy.dummy, types.MethodType)
5760
assert not isinstance(Dummy.dummy, wrapt.BoundFunctionWrapper)
5861

5962
instrumentation = _TestDummyInstrumentation()
60-
instrumentation.instrument()
63+
with caplog.at_level(logging.DEBUG, 'elasticapm.instrument'):
64+
instrumentation.instrument()
65+
record = caplog.records[0]
66+
assert "Instrumented" in record.message
67+
assert record.args == ('test_dummy_instrument', 'tests.instrumentation.base_tests.Dummy.dummy')
6168
assert isinstance(Dummy.dummy, wrapt.BoundFunctionWrapper)
6269

63-
instrumentation.uninstrument()
70+
with caplog.at_level(logging.DEBUG, 'elasticapm.instrument'):
71+
instrumentation.uninstrument()
72+
record = caplog.records[1]
73+
assert "Uninstrumented" in record.message
74+
assert record.args == ('test_dummy_instrument', 'tests.instrumentation.base_tests.Dummy.dummy')
6475
assert isinstance(Dummy.dummy, types.MethodType)
6576
assert not isinstance(Dummy.dummy, wrapt.BoundFunctionWrapper)
6677

6778

6879
@pytest.mark.skipif(compat.PY2, reason="different object model")
69-
def test_uninstrument_py3():
80+
def test_uninstrument_py3(caplog):
7081
original = Dummy.dummy
7182
assert not isinstance(Dummy.dummy, wrapt.BoundFunctionWrapper)
7283

7384
instrumentation = _TestDummyInstrumentation()
74-
instrumentation.instrument()
75-
85+
with caplog.at_level(logging.DEBUG, 'elasticapm.instrument'):
86+
instrumentation.instrument()
87+
record = caplog.records[0]
88+
assert "Instrumented" in record.message
89+
assert record.args == ('test_dummy_instrument', 'tests.instrumentation.base_tests.Dummy.dummy')
7690
assert Dummy.dummy is not original
7791
assert isinstance(Dummy.dummy, wrapt.BoundFunctionWrapper)
7892

79-
instrumentation.uninstrument()
93+
with caplog.at_level(logging.DEBUG, 'elasticapm.instrument'):
94+
instrumentation.uninstrument()
95+
record = caplog.records[1]
96+
assert "Uninstrumented" in record.message
97+
assert record.args == ('test_dummy_instrument', 'tests.instrumentation.base_tests.Dummy.dummy')
8098
assert Dummy.dummy is original
8199
assert not isinstance(Dummy.dummy, wrapt.BoundFunctionWrapper)
82100

@@ -97,10 +115,13 @@ def test_module_method_args(elasticapm_client):
97115
assert call_args == ('tests.instrumentation.base_tests', 'Dummy.dummy')
98116

99117

100-
def test_skip_instrument_env_var():
118+
def test_skip_instrument_env_var(caplog):
101119
instrumentation = _TestDummyInstrumentation()
102-
with mock.patch.dict('os.environ', {'SKIP_INSTRUMENT_TEST_DUMMY_INSTRUMENT': 'foo'}):
120+
with mock.patch.dict('os.environ', {'SKIP_INSTRUMENT_TEST_DUMMY_INSTRUMENT': 'foo'}),\
121+
caplog.at_level(logging.DEBUG, 'elasticapm.instrument'):
103122
instrumentation.instrument()
123+
record = caplog.records[0]
124+
assert 'Skipping' in record.message
104125
assert not instrumentation.instrumented
105126

106127

0 commit comments

Comments
 (0)