Skip to content

Commit 2df7eda

Browse files
authored
Merge pull request #2674 from n3hrox/enhance/footnote_deduplication
logger: output footer once for multithreaded push/pull errors
2 parents 46d221f + d25282b commit 2df7eda

File tree

4 files changed

+25
-46
lines changed

4 files changed

+25
-46
lines changed

dvc/logger.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@
1111
import colorama
1212

1313

14+
FOOTER = (
15+
"\n{yellow}Having any troubles?{nc}"
16+
" Hit us up at {blue}https://dvc.org/support{nc},"
17+
" we are always happy to help!"
18+
).format(
19+
blue=colorama.Fore.BLUE,
20+
nc=colorama.Fore.RESET,
21+
yellow=colorama.Fore.YELLOW,
22+
)
23+
24+
1425
class LoggingException(Exception):
1526
def __init__(self, record):
1627
msg = "failed to log {}".format(str(record))
@@ -48,16 +59,6 @@ class ColorFormatter(logging.Formatter):
4859
"CRITICAL": colorama.Fore.RED,
4960
}
5061

51-
footer = (
52-
"{yellow}Having any troubles?{nc}"
53-
" Hit us up at {blue}https://dvc.org/support{nc},"
54-
" we are always happy to help!"
55-
).format(
56-
blue=colorama.Fore.BLUE,
57-
nc=colorama.Fore.RESET,
58-
yellow=colorama.Fore.YELLOW,
59-
)
60-
6162
def format(self, record):
6263
if record.levelname == "INFO":
6364
return record.msg
@@ -66,18 +67,14 @@ def format(self, record):
6667
exception, stack_trace = self._parse_exc(record.exc_info)
6768

6869
return (
69-
"{color}{levelname}{nc}: {description}"
70-
"{stack_trace}\n"
71-
"\n"
72-
"{footer}"
70+
"{color}{levelname}{nc}: {description}" "{stack_trace}\n"
7371
).format(
7472
color=self.color_code.get(record.levelname, ""),
7573
nc=colorama.Fore.RESET,
7674
levelname=record.levelname,
7775
description=self._description(record.msg, exception),
7876
msg=record.msg,
7977
stack_trace=stack_trace,
80-
footer=self.footer,
8178
)
8279

8380
return "{color}{levelname}{nc}: {msg}".format(

dvc/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from dvc.cli import parse_args
88
from dvc.lock import LockError
9+
from dvc.logger import FOOTER
910
from dvc.config import ConfigError
1011
from dvc.analytics import Analytics
1112
from dvc.exceptions import NotDvcRepoError, DvcParserError
@@ -75,6 +76,9 @@ def main(argv=None):
7576
# so won't be reused by any other subsequent run anyway.
7677
clean_repos()
7778

79+
if ret != 0:
80+
logger.info(FOOTER)
81+
7882
Analytics().send_cmd(cmd, args, ret)
7983

8084
return ret

tests/func/test_remote.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,5 +245,5 @@ def unreliable_upload(self, from_file, to_info, name=None, **kwargs):
245245

246246

247247
def get_last_exc(caplog):
248-
_, exc, _ = caplog.records[-1].exc_info
248+
_, exc, _ = caplog.records[-2].exc_info
249249
return exc

tests/unit/test_logger.py

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,7 @@ def test_error(self, caplog):
4545
with caplog.at_level(logging.INFO, logger="dvc"):
4646
logger.error("message")
4747

48-
expected = (
49-
"{red}ERROR{nc}: message\n"
50-
"\n"
51-
"{footer}".format(footer=formatter.footer, **colors)
52-
)
48+
expected = "{red}ERROR{nc}: message\n".format(**colors)
5349

5450
assert expected == formatter.format(caplog.records[0])
5551

@@ -60,11 +56,7 @@ def test_exception(self, caplog):
6056
except Exception:
6157
logger.exception("message")
6258

63-
expected = (
64-
"{red}ERROR{nc}: message\n"
65-
"\n"
66-
"{footer}".format(footer=formatter.footer, **colors)
67-
)
59+
expected = "{red}ERROR{nc}: message\n".format(**colors)
6860

6961
assert expected == formatter.format(caplog.records[0])
7062

@@ -75,11 +67,7 @@ def test_exception_with_description_and_without_message(self, caplog):
7567
except Exception:
7668
logger.exception("")
7769

78-
expected = (
79-
"{red}ERROR{nc}: description\n"
80-
"\n"
81-
"{footer}".format(footer=formatter.footer, **colors)
82-
)
70+
expected = "{red}ERROR{nc}: description\n".format(**colors)
8371

8472
assert expected == formatter.format(caplog.records[0])
8573

@@ -90,10 +78,8 @@ def test_exception_with_description_and_message(self, caplog):
9078
except Exception:
9179
logger.exception("message")
9280

93-
expected = (
94-
"{red}ERROR{nc}: message - description\n"
95-
"\n"
96-
"{footer}".format(footer=formatter.footer, **colors)
81+
expected = "{red}ERROR{nc}: message - description\n".format(
82+
**colors
9783
)
9884

9985
assert expected == formatter.format(caplog.records[0])
@@ -110,13 +96,8 @@ def test_exception_under_verbose(self, caplog):
11096
"{red}ERROR{nc}: description\n"
11197
"{red}{line}{nc}\n"
11298
"{stack_trace}"
113-
"{red}{line}{nc}\n"
114-
"\n"
115-
"{footer}".format(
116-
footer=formatter.footer,
117-
line="-" * 60,
118-
stack_trace=stack_trace,
119-
**colors
99+
"{red}{line}{nc}\n".format(
100+
line="-" * 60, stack_trace=stack_trace, **colors
120101
)
121102
)
122103

@@ -138,10 +119,7 @@ def test_nested_exceptions(self, caplog):
138119
"{red}ERROR{nc}: message - second: first\n"
139120
"{red}{line}{nc}\n"
140121
"{stack_trace}"
141-
"{red}{line}{nc}\n"
142-
"\n"
143-
"{footer}".format(
144-
footer=formatter.footer,
122+
"{red}{line}{nc}\n".format(
145123
line="-" * 60,
146124
stack_trace="\n".join([first_traceback, second_traceback]),
147125
**colors

0 commit comments

Comments
 (0)