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

Add support of Logger.metadata #22

Merged
merged 1 commit into from
Jan 22, 2021
Merged

Add support of Logger.metadata #22

merged 1 commit into from
Jan 22, 2021

Conversation

c4710n
Copy link
Contributor

@c4710n c4710n commented Oct 23, 2020

Plug.RequestId supports print request_id to console with following
setting:

config :logger, :console, metadata: [:request_id]

Reference:
https://github.com/elixir-plug/plug/blob/3193ab3a8e1973e2fcc37b33417724a45dac857c/lib/plug/request_id.ex#L11

It would be nice if remote_ip support this feature, too:

config :logger, :console, metadata: [:request_id, :remote_ip]

So, here is it. ;)

`Plug.RequestId` supports print request_id to console with following
setting:

    config :logger, :console, metadata: [:request_id]

Reference:
https://github.com/elixir-plug/plug/blob/3193ab3a8e1973e2fcc37b33417724a45dac857c/lib/plug/request_id.ex#L11

It would be nice if remote_ip support this feature:

    config :logger, :console, metadata: [:request_id, :remote_ip]

So, here is it. ;)
@ajvondrak
Copy link
Owner

Excellent idea! Thanks for the contribution.

@ajvondrak ajvondrak merged commit 9f5e5f6 into ajvondrak:master Jan 22, 2021
ajvondrak added a commit that referenced this pull request Jan 23, 2021
ajvondrak added a commit that referenced this pull request Jan 23, 2021
With the functionality added by #22, I want to add tests to make sure
the Logger metadata gets set correctly. Before I can do that, I have to
(once again) overhaul the design of the top-level RemoteIp tests.

To be clear, this commit DOES NOT test the Logger.metadata yet. But it's
refactored in such a way that we'll be able to make the right assertions
later. The rewrite just makes a noisy enough diff that I'm committing it
separately.

Most of the motivation is that I'm uncomfortable testing call/2 and
from/2 together now. The metadata should only be added in the call/2
case, whereas from/2 should most likely not interfere with the current
process's logs (since it could well be invoked outside of the request
cycle).

We could test this via the single function as-is by ordering things
carefully, like

  assert RemoteIp.from(...) == ...
  assert Logger.metadata[:remote_ip] == nil
  assert RemoteIp.call(...) = ...
  assert Logger.metadata[:remote_ip] == ...

but that really just feels finicky; like it's trying to be too smart.

Furthermore, the behavior of call/2 is also practically different from
from/2 because the Plug.Conn *should* always have its :remote_ip set.
That means we should be testing whether the default case of call/2
leaves the :remote_ip intact. By contrast, from/2 can return nil. The
way the tests were previously written, I'd swept the distinction under
the rug by effectively only ever using %Plug.Conn{remote_ip: nil}
structs, thus forcing a false equivalence between the call/2 and from/2.

So, I specifically factored out the essential single-header cases into
the call/2 and from/2 describe blocks. In my latest bid to try to reduce
the copy/paste endemic to this test suite, I pulled these examples out
into loops over the module attributes. The two blocks can then make
their separate assertions: call/2 defaults to the incoming peer address
and adds metadata, whereas from/2 returns nil and sets no metadata.

However, the examples around specific :clients and :proxies
configurations were too convoluted to move into these loops. There were
just too many moving pieces, and the previous examples were being
tacitly overloaded to test all sorts of niggling things. So rather than
try to jam those into the loopy call/2 & from/2 describe blocks, I
factored out specific describe blocks for each of the options. These
spell out the exact interactions expected of the configurations and
doesn't get bogged down in call/2 vs from/2 behavior. In fact, they
exclusively use RemoteIp.from/2 for their assertions, just because it's
more ergonomic than making a %Plug.Conn{}. I figure we don't lose out on
much by doing this, because the basic metadata & return value semantics
are codified by the call/2 & from/2 blocks.
ajvondrak added a commit that referenced this pull request Jan 23, 2021
The problem with the implementation from #22 is that it fails to set the
logger metadata when an IP can't be parsed out of the forwarding
headers. I think it's safe to say that the less surprising behavior
would be to go ahead and add the metadata anyway, even though it's
coming from the original :remote_ip and not the :req_headers.

These tests have been deliberately added to enforce this expected
behavior, although the implementation currently fails.
ajvondrak added a commit that referenced this pull request Jan 23, 2021
This fixes the tests added by e89412e.
They had been failing against the original implementation of #22.
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.

2 participants