|
2 | 2 | from __future__ import annotations |
3 | 3 |
|
4 | 4 | import io |
| 5 | +import sys |
5 | 6 |
|
6 | 7 | import pytest |
| 8 | +from dirty_equals import IsStr |
7 | 9 | from inline_snapshot import snapshot |
8 | 10 | from opentelemetry import trace |
9 | 11 | from opentelemetry.sdk.trace import ReadableSpan |
@@ -689,3 +691,100 @@ def test_console_logging_to_stdout(capsys: pytest.CaptureFixture[str]): |
689 | 691 | ' outer span log message', |
690 | 692 | ] |
691 | 693 | ) |
| 694 | + |
| 695 | + |
| 696 | +def test_exception(exporter: TestExporter) -> None: |
| 697 | + try: |
| 698 | + 1 / 0 # type: ignore |
| 699 | + except ZeroDivisionError: |
| 700 | + logfire.exception('error!!! {a}', a='test') |
| 701 | + |
| 702 | + spans = exported_spans_as_models(exporter) |
| 703 | + assert spans == snapshot( |
| 704 | + [ |
| 705 | + ReadableSpanModel( |
| 706 | + name='error!!! {a}', |
| 707 | + context=SpanContextModel(trace_id=1, span_id=1, is_remote=False), |
| 708 | + parent=None, |
| 709 | + start_time=1000000000, |
| 710 | + end_time=1000000000, |
| 711 | + attributes={ |
| 712 | + 'logfire.span_type': 'log', |
| 713 | + 'logfire.level_num': 17, |
| 714 | + 'logfire.msg_template': 'error!!! {a}', |
| 715 | + 'logfire.msg': 'error!!! test', |
| 716 | + 'code.filepath': 'test_console_exporter.py', |
| 717 | + 'code.function': 'test_exception', |
| 718 | + 'code.lineno': 123, |
| 719 | + 'a': 'test', |
| 720 | + 'logfire.json_schema': '{"type":"object","properties":{"a":{}}}', |
| 721 | + }, |
| 722 | + events=[ |
| 723 | + { |
| 724 | + 'name': 'exception', |
| 725 | + 'timestamp': 2000000000, |
| 726 | + 'attributes': { |
| 727 | + 'exception.type': 'ZeroDivisionError', |
| 728 | + 'exception.message': 'division by zero', |
| 729 | + 'exception.stacktrace': 'ZeroDivisionError: division by zero', |
| 730 | + 'exception.escaped': 'False', |
| 731 | + }, |
| 732 | + } |
| 733 | + ], |
| 734 | + resource=None, |
| 735 | + ) |
| 736 | + ] |
| 737 | + ) |
| 738 | + |
| 739 | + issue_lines = ( |
| 740 | + [' │ 1 / 0 # type: ignore', ' │ ~~^~~'] |
| 741 | + if sys.version_info >= (3, 11) |
| 742 | + else [' │ 1 / 0 # type: ignore'] |
| 743 | + ) |
| 744 | + out = io.StringIO() |
| 745 | + SimpleConsoleSpanExporter(output=out, colors='never').export(exporter.exported_spans) |
| 746 | + assert out.getvalue().splitlines() == snapshot( |
| 747 | + [ |
| 748 | + '00:00:01.000 error!!! test', |
| 749 | + ' │ ZeroDivisionError: division by zero', |
| 750 | + ' │ Traceback (most recent call last):', |
| 751 | + IsStr(regex=rf' │ File "{__file__}", line \d+, in test_exception'), |
| 752 | + *issue_lines, |
| 753 | + ' │ ZeroDivisionError: division by zero', |
| 754 | + '', |
| 755 | + ] |
| 756 | + ) |
| 757 | + |
| 758 | + issue_lines = ( |
| 759 | + [ |
| 760 | + '\x1b[97;49m \x1b[0m\x1b[35;49m│\x1b[0m\x1b[97;49m ' |
| 761 | + '\x1b[0m\x1b[91;49m~\x1b[0m\x1b[91;49m~\x1b[0m\x1b[91;49m^\x1b[0m\x1b[91;49m~\x1b[0m\x1b[91;49m~\x1b[0m', |
| 762 | + ] |
| 763 | + if sys.version_info >= (3, 11) |
| 764 | + else [] |
| 765 | + ) |
| 766 | + |
| 767 | + out = io.StringIO() |
| 768 | + SimpleConsoleSpanExporter(output=out, colors='always').export(exporter.exported_spans) |
| 769 | + assert out.getvalue().splitlines() == [ |
| 770 | + '\x1b[32m00:00:01.000\x1b[0m \x1b[31merror!!! test\x1b[0m', |
| 771 | + '\x1b[34m │ \x1b[0m\x1b[1;31mZeroDivisionError: ' '\x1b[0mdivision by zero', |
| 772 | + '\x1b[97;49m \x1b[0m\x1b[35;49m│\x1b[0m\x1b[97;49m ' |
| 773 | + '\x1b[0m\x1b[97;49mTraceback\x1b[0m\x1b[97;49m ' |
| 774 | + '\x1b[0m\x1b[97;49m(\x1b[0m\x1b[97;49mmost\x1b[0m\x1b[97;49m ' |
| 775 | + '\x1b[0m\x1b[97;49mrecent\x1b[0m\x1b[97;49m ' |
| 776 | + '\x1b[0m\x1b[97;49mcall\x1b[0m\x1b[97;49m ' |
| 777 | + '\x1b[0m\x1b[97;49mlast\x1b[0m\x1b[97;49m)\x1b[0m\x1b[97;49m:\x1b[0m', |
| 778 | + IsStr(), |
| 779 | + '\x1b[97;49m \x1b[0m\x1b[35;49m│\x1b[0m\x1b[97;49m ' |
| 780 | + '\x1b[0m\x1b[37;49m1\x1b[0m\x1b[97;49m ' |
| 781 | + '\x1b[0m\x1b[91;49m/\x1b[0m\x1b[97;49m ' |
| 782 | + '\x1b[0m\x1b[37;49m0\x1b[0m\x1b[97;49m \x1b[0m\x1b[37;49m# type: ' |
| 783 | + 'ignore\x1b[0m', |
| 784 | + *issue_lines, |
| 785 | + '\x1b[97;49m \x1b[0m\x1b[35;49m│\x1b[0m\x1b[97;49m ' |
| 786 | + '\x1b[0m\x1b[92;49mZeroDivisionError\x1b[0m\x1b[97;49m:\x1b[0m\x1b[97;49m ' |
| 787 | + '\x1b[0m\x1b[97;49mdivision\x1b[0m\x1b[97;49m ' |
| 788 | + '\x1b[0m\x1b[97;49mby\x1b[0m\x1b[97;49m \x1b[0m\x1b[97;49mzero\x1b[0m', |
| 789 | + '', |
| 790 | + ] |
0 commit comments