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

Return ability to use custom loggers and to set loggers for a specific route #107

Merged
merged 1 commit into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ _test: &test
- sudo apt-get install -y tarantool tarantool-dev
- tarantoolctl rocks make
- tarantoolctl rocks install luacheck 0.25.0
- tarantoolctl rocks install luatest 0.4.0
- tarantoolctl rocks install luatest 0.5.0
script:
- .rocks/bin/luacheck .
- .rocks/bin/luatest -v --shuffle all
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,13 @@ server = require('http.server').new(host, port[, { options } ])
needed).
* `display_errors` - return application errors and backtraces to the client
(like PHP).
* `log_errors` - log application errors using `log.error()`.
* `log_requests` - log incoming requests.
* `log_requests` - log incoming requests. This parameter can receive:
- function value, supporting C-style formatting: log_requests(fmt, ...),
where fmt is a format string and ... is Lua Varargs, holding arguments to be replaced in fmt.
- boolean value, where `true` choose default `log.info` and `false` disable request logs at all
By default uses `log.info` function for requests logging.
* `log_errors` - same as the `log_requests` option but is used for error messages logging.
By default uses `log.error()` function.

## Creating a router

Expand Down Expand Up @@ -163,6 +168,8 @@ The first argument for `route()` is a Lua table with one or more keys:
| `path` | route path, as described earlier. |
| `name` | route name. |
| `method` | method on the route like `POST`, `GET`, `PUT`, `DELETE` |
| `log_requests` | option that overrides the server parameter of the same name but only for current route. |
| `log_errors` | option that overrides the server parameter of the same name but only for current route. |

The second argument is the route handler to be used to produce
a response to the request.
Expand Down
13 changes: 13 additions & 0 deletions http/router/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,19 @@ local function add_route(self, opts, handler)
else
table.insert(self.routes, opts)
end

if opts.log_requests ~= nil then
if type(opts.log_requests) ~= 'function' and type(opts.log_requests) ~= 'boolean' then
error("'log_requests' option should be a function or a boolean")
end
end

if opts.log_errors ~= nil then
if type(opts.log_errors) ~= 'function' and type(opts.log_errors) ~= 'boolean' then
error("'log_errors' option should be a function or a boolean")
end
end

return self
end

Expand Down
54 changes: 52 additions & 2 deletions http/server/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,54 @@ local function headers_ended(hdrs)
or string.endswith(hdrs, "\r\n\r\n")
end

local function is_function(obj)
return type(obj) == 'function'
end

local function get_request_logger(server_opts, route_opts)
if route_opts and route_opts.endpoint.log_requests ~= nil then
if is_function(route_opts.endpoint.log_requests) then
return route_opts.endpoint.log_requests
elseif route_opts.endpoint.log_requests == false then
return log.debug
elseif route_opts.endpoint.log_requests == true then
return log.info
end
end

if server_opts.log_requests then
if is_function(server_opts.log_requests) then
return server_opts.log_requests
end

return log.info
end

return log.debug
end

local function get_error_logger(server_opts, route_opts)
if route_opts and route_opts.endpoint.log_errors ~= nil then
if is_function(route_opts.endpoint.log_errors) then
return route_opts.endpoint.log_errors
elseif route_opts.endpoint.log_errors == false then
return log.debug
elseif route_opts.endpoint.log_errors == true then
return log.error
end
end

if server_opts.log_errors then
if is_function(server_opts.log_errors) then
return server_opts.log_errors
end

return log.error
end

return log.debug
end

----------
-- Server
----------
Expand Down Expand Up @@ -99,7 +147,9 @@ local function process_client(self, s, peer)
s:write('HTTP/1.0 100 Continue\r\n\r\n')
end

local logreq = self.options.log_requests and log.info or log.debug
local matched_route = self.options.router:match(p.method, p.path)

local logreq = get_request_logger(self.options, matched_route)
logreq("%s %s%s", p.method, p.path,
p.query ~= "" and "?"..p.query or "")

Expand All @@ -117,7 +167,7 @@ local function process_client(self, s, peer)
status = 500
hdrs = {}
local trace = debug.traceback()
local logerror = self.options.log_errors and log.error or log.debug
local logerror = get_error_logger(self.options, matched_route)

-- TODO: copypaste
logerror('unhandled error: %s\n%s\nrequest:\n%s',
Expand Down
Loading