Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include query_string in logs #384

Merged
merged 9 commits into from Jul 11, 2019
Merged

Conversation

simonw
Copy link
Contributor

@simonw simonw commented Jul 4, 2019

Refs #382

@simonw
Copy link
Contributor Author

simonw commented Jul 4, 2019

I didn't see any existing unit tests for logging and I wasn't sure how best to add them.

Here's example output from my local development instance:

INFO: ('127.0.0.1', 62821) - "GET /fixtures/no_primary_key.json HTTP/1.1" 200
INFO: ('127.0.0.1', 62821) - "GET /fixtures/no_primary_key?_sort=content HTTP/1.1" 200
INFO: ('127.0.0.1', 62821) - "GET /-/static/app.css?5e037f HTTP/1.1" 200
INFO: ('127.0.0.1', 62824) - "GET /fixtures?sql=select+rowid%2C+%2A+from+no_primary_key+order+by+content+limit+101 HTTP/1.1" 200

@simonw
Copy link
Contributor Author

simonw commented Jul 4, 2019

I'm a little bit puzzled by these test failures:

=================================== FAILURES ===================================
_____________________________ test_invalid_format ______________________________
    def test_invalid_format():
        with pytest.raises(ImportFromStringError) as exc:
            import_from_string("example:")
        expected = 'Import string "example:" must be in format "<module>:<attribute>".'
>       assert expected in str(exc)
E       assert 'Import string "example:" must be in format "<module>:<attribute>".' in '<ExceptionInfo ImportFromStringError tblen=2>'
E        +  where '<ExceptionInfo ImportFromStringError tblen=2>' = str(<ExceptionInfo ImportFromStringError tblen=2>)
tests/importer/test_importer.py:10: AssertionError
_____________________________ test_invalid_module ______________________________
    def test_invalid_module():
        with pytest.raises(ImportFromStringError) as exc:
            import_from_string("module_does_not_exist:myattr")
        expected = 'Could not import module "module_does_not_exist".'
>       assert expected in str(exc)
E       assert 'Could not import module "module_does_not_exist".' in '<ExceptionInfo ImportFromStringError tblen=2>'
E        +  where '<ExceptionInfo ImportFromStringError tblen=2>' = str(<ExceptionInfo ImportFromStringError tblen=2>)
tests/importer/test_importer.py:17: AssertionError
______________________________ test_invalid_attr _______________________________
    def test_invalid_attr():
        with pytest.raises(ImportFromStringError) as exc:
            import_from_string("tempfile:attr_does_not_exist")
        expected = 'Attribute "attr_does_not_exist" not found in module "tempfile".'
>       assert expected in str(exc)
E       assert 'Attribute "attr_does_not_exist" not found in module "tempfile".' in '<ExceptionInfo ImportFromStringError tblen=2>'
E        +  where '<ExceptionInfo ImportFromStringError tblen=2>' = str(<ExceptionInfo ImportFromStringError tblen=2>)
tests/importer/test_importer.py:24: AssertionError

I can't replicate them in my local environment.

@simonw simonw changed the title Include query_string in logs, refs #382 Include query_string in logs Jul 4, 2019
@simonw
Copy link
Contributor Author

simonw commented Jul 4, 2019

Interesting thing I spotted while building the unit test: it looks like the ASGI specification makes it impossible to tell the difference between hits to / and hits to /? - both result in the same scope. I don't think it's a problem, just interesting.

@tomchristie
Copy link
Member

Addressing the (unrelated) test failures you're seeing here: #385

@tomchristie
Copy link
Member

And yes - ASGI can't see the '?' (WSGI either)

If I'd have remembered that at the time I guess I might(?) have advocated for raw_path to be both the path and query string, without any parsing or modification whatsoever.

@tomchristie
Copy link
Member

Alrighy - looks like if you merge master then those tests oughta start passing again.

@simonw
Copy link
Contributor Author

simonw commented Jul 5, 2019

Hmm... that fixed the previous failures but I now have this one, which is also puzzling to me:

___________________ test_request_logging[/?foo-H11Protocol] ___________________
protocol_cls = <class 'uvicorn.protocols.http.h11_impl.H11Protocol'>
path = '/?foo'
caplog = <_pytest.logging.LogCaptureFixture object at 0x0000021042B23390>
    @pytest.mark.parametrize("protocol_cls", HTTP_PROTOCOLS)
    @pytest.mark.parametrize("path", ["/", "/?foo", "/?foo=bar", "/?foo=bar&baz=1"])
    def test_request_logging(protocol_cls, path, caplog):
        get_request_with_query_string = b"\r\n".join(
            ["GET {} HTTP/1.1".format(path).encode("ascii"), b"Host: example.org", b"", b""]
        )
        caplog.set_level(logging.INFO, logger="uvicorn")
        app = Response("Hello, world", media_type="text/plain")
    
        protocol = get_connected_protocol(app, protocol_cls)
        protocol.data_received(get_request_with_query_string)
        protocol.loop.run_one()
    
>       assert '"GET {} HTTP/1.1" 200'.format(path) in caplog.records[0].message
E       assert '"GET /?foo HTTP/1.1" 200' in 'Task was destroyed but it is pending!\ntask: <Task pending coro=<WSGIResponder.sender() done, defined at C:\\Users\\t...icorn\\middleware\\wsgi.py:100> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x0000021042AC61F8>()]>>'

@tomchristie
Copy link
Member

Strange - also it's only occurring on the windows build.
Could it be something odd to do with the interaction between the two parameterizations?
How's it run without the path parameterization decorator in place?

@tomchristie
Copy link
Member

Or, eg. if you swap the two parameterization decorators around so that they're ordered the other way?

@tomchristie
Copy link
Member

Or if you swap the second one so that it's only running ?foo, which is the failing case?

@simonw
Copy link
Contributor Author

simonw commented Jul 6, 2019

Swapping the order of the two parameterization decorators worked, great hunch there!

@simonw
Copy link
Contributor Author

simonw commented Jul 11, 2019

Anything else we need to do before we can merge this?

@tomchristie tomchristie merged commit 5f1e513 into encode:master Jul 11, 2019
@tomchristie
Copy link
Member

Released! 0.8.4

Thanks 🙏

simonw added a commit to simonw/datasette that referenced this pull request Jul 12, 2019
simonw added a commit to simonw/datasette that referenced this pull request Jul 13, 2019
simonw added a commit to simonw/datasette that referenced this pull request Nov 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants