@@ -43,12 +43,7 @@ defmodule Tesla.Middleware.Logger.Formatter do
43
43
Enum . map ( format , & output ( & 1 , request , response , time ) )
44
44
end
45
45
46
- defp output ( :query , env , _ , _ ) do
47
- encoding = Keyword . get ( env . opts , :query_encoding , :www_form )
48
-
49
- Tesla . encode_query ( env . query , encoding )
50
- end
51
-
46
+ defp output ( :query , env , _ , _ ) , do: env . query |> Tesla . encode_query ( )
52
47
defp output ( :method , env , _ , _ ) , do: env . method |> to_string ( ) |> String . upcase ( )
53
48
defp output ( :url , env , _ , _ ) , do: env . url
54
49
defp output ( :status , _ , { :ok , env } , _ ) , do: to_string ( env . status )
@@ -61,32 +56,31 @@ defmodule Tesla.Middleware.Logger do
61
56
@ moduledoc ~S"""
62
57
Log requests using Elixir's Logger.
63
58
64
- With the default settings it logs request method, URL, response status, and
65
- time taken in milliseconds.
59
+ With the default settings it logs request method, URL, response status, and time taken in milliseconds.
66
60
67
61
## Examples
68
62
69
63
```elixir
70
64
defmodule MyClient do
71
- def client do
72
- Tesla.client([Tesla.Middleware.Logger])
73
- end
65
+ use Tesla
66
+
67
+ plug Tesla.Middleware.Logger
74
68
end
75
69
```
76
70
77
71
## Options
78
72
79
73
- `:log_level` - custom function for calculating log level (see below)
80
74
- `:filter_headers` - sanitizes sensitive headers before logging in debug mode (see below)
81
- - `:debug` - use `Logger.debug/2` to log request/response details
75
+ - `:debug` - show detailed request/response logging
82
76
- `:format` - custom string template or function for log message (see below)
83
77
84
78
## Custom log format
85
79
86
80
The default log format is `"$method $url -> $status ($time ms)"`
87
81
which shows in logs like:
88
82
89
- ```elixir
83
+ ```
90
84
2018-03-25 18:32:40.397 [info] GET https://bitebot.io -> 200 (88.074 ms)
91
85
```
92
86
@@ -100,11 +94,9 @@ defmodule Tesla.Middleware.Logger do
100
94
101
95
```elixir
102
96
defmodule MyClient do
103
- def client do
104
- Tesla.client([
105
- {Tesla.Middleware.Logger, format: &my_format/3}
106
- ])
107
- end
97
+ use Tesla
98
+
99
+ plug Tesla.Middleware.Logger, format: &my_format/3
108
100
109
101
def my_format(request, response, time) do
110
102
"request=#{inspect(request)} response=#{inspect(response)} time=#{time}\n"
@@ -124,11 +116,9 @@ defmodule Tesla.Middleware.Logger do
124
116
125
117
```elixir
126
118
defmodule MyClient do
127
- def client do
128
- Tesla.client([
129
- {Tesla.Middleware.Logger, log_level: &my_log_level/1}
130
- ])
131
- end
119
+ use Tesla
120
+
121
+ plug Tesla.Middleware.Logger, log_level: &my_log_level/1
132
122
133
123
def my_log_level(env) do
134
124
case env.status do
@@ -141,28 +131,22 @@ defmodule Tesla.Middleware.Logger do
141
131
142
132
## Logger Debug output
143
133
144
- `Tesla` will use `Logger.debug/2` to log request & response details using
145
- the `:debug` option. It will require to set the `Logger` log level to `:debug`
146
- in your configuration, example:
147
-
148
- ```elixir
149
- # config/dev.exs
150
- config :logger, level: :debug
151
- ```
134
+ When the Elixir Logger log level is set to `:debug`
135
+ Tesla Logger will show full request & response.
152
136
153
- If you want to disable detailed request/response logging but keep the
154
- `:debug` log level (i.e. in development) you can set `debug: false` in your
155
- config:
137
+ If you want to disable detailed request/response logging
138
+ but keep the `:debug` log level (i.e. in development)
139
+ you can set `debug: false` in your config:
156
140
157
- ```elixir
141
+ ```
158
142
# config/dev.local.exs
159
143
config :tesla, Tesla.Middleware.Logger, debug: false
160
144
```
161
145
162
146
Note that the logging configuration is evaluated at compile time,
163
147
so Tesla must be recompiled for the configuration to take effect:
164
148
165
- ```shell
149
+ ```
166
150
mix deps.clean --build tesla
167
151
mix deps.compile tesla
168
152
```
@@ -187,7 +171,7 @@ defmodule Tesla.Middleware.Logger do
187
171
debug logs, add them to the `:filter_headers` option.
188
172
`:filter_headers` expects a list of header names as strings.
189
173
190
- ```elixir
174
+ ```
191
175
# config/dev.local.exs
192
176
config :tesla, Tesla.Middleware.Logger,
193
177
filter_headers: ["authorization"]
@@ -281,7 +265,7 @@ defmodule Tesla.Middleware.Logger do
281
265
"\n <<< RESPONSE <<<\n " ,
282
266
debug_headers ( response . headers , config ) ,
283
267
?\n ,
284
- debug_body ( response . body )
268
+ debug_body ( response , response . body )
285
269
]
286
270
end
287
271
@@ -318,6 +302,13 @@ defmodule Tesla.Middleware.Logger do
318
302
end )
319
303
end
320
304
305
+ def debug_body ( request , body ) do
306
+ cond do
307
+ has_streamed_body? ( request ) -> "[Streamed body]"
308
+ true -> debug_body ( body )
309
+ end
310
+ end
311
+
321
312
defp debug_body ( nil ) , do: @ debug_no_body
322
313
defp debug_body ( [ ] ) , do: @ debug_no_body
323
314
defp debug_body ( % Stream { } ) , do: @ debug_stream
@@ -338,4 +329,14 @@ defmodule Tesla.Middleware.Logger do
338
329
339
330
defp debug_body ( data ) when is_binary ( data ) or is_list ( data ) , do: data
340
331
defp debug_body ( term ) , do: inspect ( term )
332
+
333
+ defp has_streamed_body? ( % Tesla.Env { body: % Stream { } } ) , do: true
334
+ defp has_streamed_body? ( % { headers: headers } ) do
335
+ cond do
336
+ Enum . any? ( headers , fn { k , v } -> k == "content-type" and v == "application/octet-stream" end ) -> true
337
+ Enum . any? ( headers , fn { k , v } -> k == "transfer-encoding" and v == "chunked" end ) -> true
338
+ true -> false
339
+ end
340
+
341
+ end
341
342
end
0 commit comments