Skip to content

Commit 3aa7346

Browse files
fix(logging): tag keboola-owned handlers; only remove those in set_default_logger
set_default_logger and set_gelf_logger iterated root.handlers while calling removeHandler in the same loop body, causing mutation-during-iteration skips (alternating handlers were missed). More importantly, all handlers were removed indiscriminately, dropping any test-infrastructure handlers (e.g. LogCaptureHandler from keboola.vcr) that were installed before the component initialised. Fix: mark handlers created by keboola.component with _keboola_owned = True and only remove those. External handlers installed by test frameworks survive set_default_logger calls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4dd9894 commit 3aa7346

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

src/keboola/component/interface.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,18 +165,22 @@ def filter(self, rec):
165165

166166
hd1 = logging.StreamHandler(sys.stdout)
167167
hd1.addFilter(InfoFilter())
168+
hd1._keboola_owned = True
168169
hd2 = logging.StreamHandler(sys.stderr)
169170
hd2.setLevel(logging.WARNING)
171+
hd2._keboola_owned = True
170172

171-
logging.getLogger().setLevel(log_level)
172-
# remove default handler
173-
for h in logging.getLogger().handlers:
174-
logging.getLogger().removeHandler(h)
175-
logging.getLogger().addHandler(hd1)
176-
logging.getLogger().addHandler(hd2)
173+
root = logging.getLogger()
174+
root.setLevel(log_level)
175+
# Remove only handlers previously installed by keboola.component, leaving
176+
# any external handlers (e.g. test infrastructure) untouched.
177+
for h in list(root.handlers):
178+
if getattr(h, '_keboola_owned', False):
179+
root.removeHandler(h)
180+
root.addHandler(hd1)
181+
root.addHandler(hd2)
177182

178-
logger = logging.getLogger()
179-
return logger
183+
return root
180184

181185
@staticmethod
182186
def set_gelf_logger(log_level: int = logging.INFO, transport_layer='TCP',
@@ -196,9 +200,11 @@ def set_gelf_logger(log_level: int = logging.INFO, transport_layer='TCP',
196200
197201
Returns: Logger object
198202
"""
199-
# remove existing handlers
200-
for h in logging.getLogger().handlers:
201-
logging.getLogger().removeHandler(h)
203+
# Remove only handlers previously installed by keboola.component.
204+
root = logging.getLogger()
205+
for h in list(root.handlers):
206+
if getattr(h, '_keboola_owned', False):
207+
root.removeHandler(h)
202208
if stdout:
203209
CommonInterface.set_default_logger(log_level)
204210

0 commit comments

Comments
 (0)