Skip to content

Commit e69965e

Browse files
authored
SCANPY-180 Non-error logs should not be sent to stderr (#212)
1 parent 1ac7e0f commit e69965e

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

src/pysonar_scanner/app_logging.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,34 @@
1818
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919
#
2020
import logging
21+
import sys
22+
23+
24+
class LevelFilter(logging.Filter):
25+
def __init__(self, level):
26+
super().__init__()
27+
self.__level = level
28+
29+
def filter(self, record):
30+
return record.levelno < self.__level
2131

2232

2333
def setup() -> None:
24-
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
34+
logger = logging.getLogger()
35+
36+
non_error_handler = logging.StreamHandler(sys.stdout)
37+
non_error_handler.setLevel(logging.DEBUG)
38+
non_error_handler.addFilter(LevelFilter(logging.ERROR))
39+
40+
error_handler = logging.StreamHandler(sys.stderr)
41+
error_handler.setLevel(logging.ERROR)
42+
43+
formatter = logging.Formatter("%(levelname)s: %(message)s")
44+
non_error_handler.setFormatter(formatter)
45+
error_handler.setFormatter(formatter)
46+
47+
logger.addHandler(non_error_handler)
48+
logger.addHandler(error_handler)
2549

2650

2751
def configure_logging_level(verbose: bool) -> None:

tests/unit/test_app_logging.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#
2+
# Sonar Scanner Python
3+
# Copyright (C) 2011-2024 SonarSource SA.
4+
# mailto:info AT sonarsource DOT com
5+
#
6+
# This program is free software; you can redistribute it and/or
7+
# modify it under the terms of the GNU Lesser General Public
8+
# License as published by the Free Software Foundation; either
9+
# version 3 of the License, or (at your option) any later version.
10+
# This program is distributed in the hope that it will be useful,
11+
#
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
# Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License
17+
# along with this program; if not, write to the Free Software Foundation,
18+
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
#
20+
import logging
21+
import unittest
22+
23+
import pytest
24+
25+
from pysonar_scanner import app_logging
26+
27+
28+
class TestAppLogging(unittest.TestCase):
29+
@pytest.fixture(autouse=True)
30+
def set_capsys(self, capsys):
31+
self.capsys = capsys
32+
33+
def setUp(self) -> None:
34+
app_logging.setup()
35+
36+
def test_logging_output_destinations(self):
37+
logging.info("hello world")
38+
logging.error("boom!")
39+
40+
captured = self.capsys.readouterr()
41+
self.assertIn("INFO: hello world", captured.out)
42+
self.assertIn("ERROR: boom!", captured.err)
43+
self.assertEqual(len(captured.err.splitlines()), 1)
44+
self.assertEqual(len(captured.out.splitlines()), 1)

0 commit comments

Comments
 (0)