Skip to content

Commit d5ad40a

Browse files
authored
Remove accepted_comparators option from logger interceptors (#326)
* reverse logger level comparison logic * add more details to example * remove accepted_comparator * adjust client tests * adjust server tests * prevent log level from being changed globally * mix format * adjust tests to (hopefully) pass for all elixir/otp versions * one more attempt to have tests working for all elixir versions
1 parent 691ac21 commit d5ad40a

File tree

5 files changed

+153
-117
lines changed

5 files changed

+153
-117
lines changed

lib/grpc/client/interceptors/logger.ex

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,14 @@ defmodule GRPC.Client.Interceptors.Logger do
88
## Options
99
1010
* `:level` - the desired log level. Defaults to `:info`
11-
* `:accepted_comparators` - a list with the accepted `Logger.compare_levels(configured_level, Logger.level())` results.
12-
Defaults to `[:lt, :eq]`
1311
1412
## Usage
1513
1614
{:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [GRPC.Client.Interceptors.Logger])
17-
# This will log on `:info` and greater priority
18-
{:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [{GRPC.Client.Interceptors.Logger, level: :info}])
19-
# This will log only on `:info`
20-
{:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [{GRPC.Client.Interceptors.Logger, level: :info, accepted_comparators: [:eq]}])
21-
# This will log on `:info` and lower priority
22-
{:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [{GRPC.Client.Interceptors.Logger, level: :info, accepted_comparators: [:eq, :gt]}])
15+
16+
## Usage with custom level
17+
18+
{:ok, channel} = GRPC.Stub.connect("localhost:50051", interceptors: [{GRPC.Client.Interceptors.Logger, level: :warn}])
2319
"""
2420

2521
require Logger
@@ -29,16 +25,14 @@ defmodule GRPC.Client.Interceptors.Logger do
2925
@impl true
3026
def init(opts) do
3127
level = Keyword.get(opts, :level) || :info
32-
accepted_comparators = Keyword.get(opts, :accepted_comparators) || [:lt, :eq]
33-
[level: level, accepted_comparators: accepted_comparators]
28+
[level: level]
3429
end
3530

3631
@impl true
3732
def call(%{grpc_type: grpc_type} = stream, req, next, opts) do
3833
level = Keyword.fetch!(opts, :level)
39-
accepted_comparators = Keyword.fetch!(opts, :accepted_comparators)
4034

41-
if Logger.compare_levels(level, Logger.level()) in accepted_comparators do
35+
if Logger.compare_levels(level, Logger.level()) != :lt do
4236
Logger.log(level, fn ->
4337
["Call ", to_string(elem(stream.rpc, 0)), " of ", stream.service_name]
4438
end)

lib/grpc/server/interceptors/logger.ex

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ defmodule GRPC.Server.Interceptors.Logger do
88
## Options
99
1010
* `:level` - the desired log level. Defaults to `:info`
11-
* `:accepted_comparators` - a list with the accepted `Logger.compare_levels(configured_level, Logger.level())` results.
12-
Defaults to `[:lt, :eq]`
1311
1412
## Usage
1513
@@ -18,20 +16,6 @@ defmodule GRPC.Server.Interceptors.Logger do
1816
1917
intercept GRPC.Server.Interceptors.Logger, level: :info
2018
end
21-
22-
defmodule Your.Endpoint do
23-
use GRPC.Endpoint
24-
25-
# logs on :info and higher priority (warn, error...)
26-
intercept GRPC.Server.Interceptors.Logger, level: :info, accepted_comparators: [:lt, :eq]
27-
end
28-
29-
defmodule Your.Endpoint do
30-
use GRPC.Endpoint
31-
32-
# logs only on :error
33-
intercept GRPC.Server.Interceptors.Logger, level: :error, accepted_comparators: [:eq]
34-
end
3519
"""
3620

3721
require Logger
@@ -41,16 +25,14 @@ defmodule GRPC.Server.Interceptors.Logger do
4125
@impl true
4226
def init(opts) do
4327
level = Keyword.get(opts, :level) || :info
44-
accepted_comparators = Keyword.get(opts, :accepted_comparators) || [:lt, :eq]
45-
[level: level, accepted_comparators: accepted_comparators]
28+
[level: level]
4629
end
4730

4831
@impl true
4932
def call(req, stream, next, opts) do
5033
level = Keyword.fetch!(opts, :level)
51-
accepted_comparators = opts[:accepted_comparators]
5234

53-
if Logger.compare_levels(level, Logger.level()) in accepted_comparators do
35+
if Logger.compare_levels(level, Logger.level()) != :lt do
5436
Logger.metadata(request_id: Logger.metadata()[:request_id] || stream.request_id)
5537

5638
Logger.log(level, "Handled by #{inspect(stream.server)}.#{elem(stream.rpc, 0)}")

test/grpc/client/interceptors/logger_test.exs

Lines changed: 69 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,74 @@ defmodule GRPC.Client.Interceptors.LoggerTest do
66
alias GRPC.Client.Interceptors.Logger, as: LoggerInterceptor
77
alias GRPC.Client.Stream
88

9-
test "accepted_comparators filter logs correctly" do
10-
for {configured_level, accepted_comparators, should_log} <-
11-
[
12-
{:error, [:lt], false},
13-
{:error, [:eq], false},
14-
{:error, [:gt], true},
15-
{:debug, [:eq], false},
16-
{:debug, [:eq, :gt], false},
17-
{:info, [:lt, :eq], true}
18-
] do
19-
logger_level = Logger.level()
20-
assert logger_level == :info
21-
22-
service_name = "service_name"
23-
rpc = {1, 2, 3}
24-
25-
logs =
26-
capture_log(fn ->
27-
stream = %Stream{grpc_type: :unary, rpc: rpc, service_name: service_name}
28-
29-
LoggerInterceptor.call(
30-
stream,
31-
:request,
32-
fn ^stream, :request -> {:ok, :ok} end,
33-
LoggerInterceptor.init(
34-
level: configured_level,
35-
accepted_comparators: accepted_comparators
36-
)
37-
)
38-
end)
39-
40-
if should_log do
41-
assert Regex.match?(
42-
~r/\[#{configured_level}\]\s+Call #{to_string(elem(rpc, 0))} of #{service_name}/,
43-
logs
44-
)
45-
else
46-
assert logs == ""
47-
end
48-
end
9+
defmodule FakeRequest do
10+
defstruct []
11+
end
12+
13+
@service_name "service_name"
14+
@rpc {1, 2, 3}
15+
16+
setup do
17+
log_level = Logger.level()
18+
on_exit(fn -> Logger.configure(level: log_level) end)
19+
end
20+
21+
test "logs info-level by default" do
22+
Logger.configure(level: :all)
23+
24+
request = %FakeRequest{}
25+
stream = %Stream{grpc_type: :unary, rpc: @rpc, service_name: @service_name}
26+
next = fn _stream, _request -> {:ok, :ok} end
27+
opts = LoggerInterceptor.init([])
28+
29+
logs =
30+
capture_log(fn ->
31+
LoggerInterceptor.call(stream, request, next, opts)
32+
end)
33+
34+
assert logs =~ ~r/\[info\]\s+Call #{to_string(elem(@rpc, 0))} of #{@service_name}/
35+
end
36+
37+
test "allows customizing log level" do
38+
Logger.configure(level: :all)
39+
40+
request = %FakeRequest{}
41+
stream = %Stream{grpc_type: :unary, rpc: @rpc, service_name: @service_name}
42+
next = fn _stream, _request -> {:ok, :ok} end
43+
opts = LoggerInterceptor.init(level: :warn)
44+
45+
logs =
46+
capture_log(fn ->
47+
LoggerInterceptor.call(stream, request, next, opts)
48+
end)
49+
50+
assert logs =~ ~r/\[warn(?:ing)?\]\s+Call #{to_string(elem(@rpc, 0))} of #{@service_name}/
51+
end
52+
53+
@tag capture_log: true
54+
test "calls next when above :logger level" do
55+
Logger.configure(level: :all)
56+
57+
request = %FakeRequest{}
58+
stream = %Stream{grpc_type: :unary, rpc: @rpc, service_name: @service_name}
59+
next = fn stream, req -> send(self(), {:next_called, stream, req}) end
60+
opts = LoggerInterceptor.init(level: :info)
61+
62+
LoggerInterceptor.call(stream, request, next, opts)
63+
64+
assert_receive {:next_called, ^stream, ^request}
65+
end
66+
67+
test "calls next when below :logger level" do
68+
Logger.configure(level: :warn)
69+
70+
request = %FakeRequest{}
71+
stream = %Stream{grpc_type: :unary, rpc: @rpc, service_name: @service_name}
72+
next = fn stream, req -> send(self(), {:next_called, stream, req}) end
73+
opts = LoggerInterceptor.init(level: :info)
74+
75+
LoggerInterceptor.call(stream, request, next, opts)
76+
77+
assert_receive {:next_called, ^stream, ^request}
4978
end
5079
end

test/grpc/integration/endpoint_test.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ defmodule GRPC.Integration.EndpointTest do
1313
defmodule HelloEndpoint do
1414
use GRPC.Endpoint
1515

16-
intercept GRPC.Server.Interceptors.Logger, level: :info, accepted_comparators: [:lt, :eq, :gt]
16+
intercept GRPC.Server.Interceptors.Logger
1717
run HelloServer
1818
end
1919

@@ -51,14 +51,14 @@ defmodule GRPC.Integration.EndpointTest do
5151
defmodule FeatureEndpoint do
5252
use GRPC.Endpoint
5353

54-
intercept GRPC.Server.Interceptors.Logger, accepted_comparators: [:lt, :eq, :gt]
54+
intercept GRPC.Server.Interceptors.Logger
5555
run FeatureServer
5656
end
5757

5858
defmodule FeatureAndHelloHaltEndpoint do
5959
use GRPC.Endpoint
6060

61-
intercept GRPC.Server.Interceptors.Logger, accepted_comparators: [:lt, :eq, :gt]
61+
intercept GRPC.Server.Interceptors.Logger
6262
run HelloServer, interceptors: [HelloHaltInterceptor]
6363
run FeatureServer
6464
end

test/grpc/server/interceptors/logger_test.exs

Lines changed: 73 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,29 @@ defmodule GRPC.Server.Interceptors.LoggerTest do
66
alias GRPC.Server.Interceptors.Logger, as: LoggerInterceptor
77
alias GRPC.Server.Stream
88

9+
defmodule FakeRequest do
10+
defstruct []
11+
end
12+
13+
@server_name :server
14+
@rpc {1, 2, 3}
15+
16+
setup do
17+
log_level = Logger.level()
18+
on_exit(fn -> Logger.configure(level: log_level) end)
19+
end
20+
921
test "request id is only set if not previously set" do
1022
assert Logger.metadata() == []
1123

1224
request_id = to_string(System.monotonic_time())
13-
stream = %Stream{server: :server, rpc: {1, 2, 3}, request_id: request_id}
25+
request = %FakeRequest{}
26+
stream = %Stream{server: @server_name, rpc: @rpc, request_id: request_id}
1427

1528
LoggerInterceptor.call(
16-
:request,
29+
request,
1730
stream,
18-
fn :request, ^stream -> {:ok, :ok} end,
31+
fn ^request, ^stream -> {:ok, :ok} end,
1932
LoggerInterceptor.init(level: :info)
2033
)
2134

@@ -33,44 +46,62 @@ defmodule GRPC.Server.Interceptors.LoggerTest do
3346
assert request_id == Logger.metadata()[:request_id]
3447
end
3548

36-
test "accepted_comparators filter logs correctly" do
37-
for {configured_level, accepted_comparators, should_log} <-
38-
[
39-
{:error, [:lt], false},
40-
{:error, [:eq], false},
41-
{:error, [:gt], true},
42-
{:debug, [:eq], false},
43-
{:debug, [:eq, :gt], false},
44-
{:info, [:lt, :eq], true}
45-
] do
46-
server_name = :"server_#{System.unique_integer()}"
47-
48-
logger_level = Logger.level()
49-
assert logger_level == :info
50-
51-
logs =
52-
capture_log(fn ->
53-
stream = %Stream{server: server_name, rpc: {1, 2, 3}, request_id: "1234"}
54-
55-
LoggerInterceptor.call(
56-
:request,
57-
stream,
58-
fn :request, ^stream -> {:ok, :ok} end,
59-
LoggerInterceptor.init(
60-
level: configured_level,
61-
accepted_comparators: accepted_comparators
62-
)
63-
)
64-
end)
65-
66-
if should_log do
67-
assert Regex.match?(
68-
~r/\[#{configured_level}\]\s+Handled by #{inspect(server_name)}/,
69-
logs
70-
)
71-
else
72-
assert logs == ""
73-
end
74-
end
49+
test "logs info-level by default" do
50+
Logger.configure(level: :all)
51+
52+
request = %FakeRequest{}
53+
stream = %Stream{server: @server_name, rpc: @rpc, request_id: nil}
54+
next = fn _stream, _request -> {:ok, :ok} end
55+
opts = LoggerInterceptor.init([])
56+
57+
logs =
58+
capture_log(fn ->
59+
LoggerInterceptor.call(request, stream, next, opts)
60+
end)
61+
62+
assert logs =~ ~r/\[info\]\s+Handled by #{inspect(@server_name)}/
63+
end
64+
65+
test "allows customizing log level" do
66+
Logger.configure(level: :all)
67+
68+
request = %FakeRequest{}
69+
stream = %Stream{server: @server_name, rpc: @rpc, request_id: nil}
70+
next = fn _stream, _request -> {:ok, :ok} end
71+
opts = LoggerInterceptor.init(level: :warn)
72+
73+
logs =
74+
capture_log(fn ->
75+
LoggerInterceptor.call(request, stream, next, opts)
76+
end)
77+
78+
assert logs =~ ~r/\[warn(?:ing)?\]\s+Handled by #{inspect(@server_name)}/
79+
end
80+
81+
@tag capture_log: true
82+
test "calls next when above :logger level" do
83+
Logger.configure(level: :all)
84+
85+
request = %FakeRequest{}
86+
stream = %Stream{server: @server_name, rpc: @rpc, request_id: nil}
87+
next = fn stream, req -> send(self(), {:next_called, stream, req}) end
88+
opts = LoggerInterceptor.init(level: :info)
89+
90+
LoggerInterceptor.call(request, stream, next, opts)
91+
92+
assert_receive {:next_called, ^request, ^stream}
93+
end
94+
95+
test "calls next when below :logger level" do
96+
Logger.configure(level: :warn)
97+
98+
request = %FakeRequest{}
99+
stream = %Stream{server: @server_name, rpc: @rpc, request_id: nil}
100+
next = fn stream, req -> send(self(), {:next_called, stream, req}) end
101+
opts = LoggerInterceptor.init(level: :info)
102+
103+
LoggerInterceptor.call(request, stream, next, opts)
104+
105+
assert_receive {:next_called, ^request, ^stream}
75106
end
76107
end

0 commit comments

Comments
 (0)