Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions raven-lua-scm-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ to Sentry.]],
dependencies = {
"lua >= 5.1",
"lua-cjson",
"lua-resty-http"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually not add senders dependencies on the rockspec because it doesn't make sense to every user of the module to install them. This is why luasocket and luasec are not listed here as they are specific to the luasocket backend.

}
build = {
type = "builtin",
Expand Down
79 changes: 79 additions & 0 deletions raven/senders/lua-resty-http.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
-- vim: st=4 sts=4 sw=4 et:
--- Network backend using [lua-resty-http](https://github.com/ledgetech/lua-resty-http).
--- Supports https, http, and keepalive for better performance.
--
-- @module raven.senders.lua-resty-http
-- @copyright 2014-2017 CloudFlare, Inc.
-- @license BSD 3-clause (see LICENSE file)

local util = require 'raven.util'
local http = require 'resty.http'
local cjson = require 'cjson'

local tostring = tostring
local setmetatable = setmetatable
local table_concat = table.concat
local parse_dsn = util.parse_dsn
local generate_auth_header = util.generate_auth_header
local _VERSION = util._VERSION
local _M = {}

local mt = {}
mt.__index = mt

function mt:send(json_str)
local httpc = http.new()
local res, err = httpc:request_uri(self.server, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that sockets are not always available with lua_nginx_module: some phases such as init, set and log don't support async operations. The plain ngx module works around this limitation by spawning a timer that does the actual sending.

Perhaps there is a way to extract that logic so it doesn't need to be replicated here.

method = "POST",
headers = {
['Content-Type'] = 'applicaion/json',
['User-Agent'] = "raven-lua-http/" .. _VERSION,
['X-Sentry-Auth'] = generate_auth_header(self),
["Content-Length"] = tostring(#json_str),
},
body = cjson.encode(json_str),
keepalive = self.opts.keepalive,
keepalive_timeout = self.opts.keepalive_timeout,
keepalive_pool = self.opts.keepalive_pool
})

if not res then
return nil, table_concat(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding request_uri returns a string error directly, not a table. Attempting to concatenate it will throw an error.

end

return true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case the server responds a non-200 answer, the error would be silently ignored here. The raven library attempts to write the message in the error log as a last resort in case the sender cannot send it (https://github.com/cloudflare/raven-lua/blob/master/raven/init.lua#L323).

end

--- Configuration table for the lua-resty-http.
-- @field dsn DSN string
-- @field verify_ssl Whether or not the SSL certificate is checked (boolean,
-- defaults to false)
-- @field keepalive Whether or not to keep connection alive (boolean,
-- defaults to false)
-- @field keepalive_timeout The maximum number of connections in the keepalive pool(int,
-- defaults to 0)
-- @field keepalive_pool Whether or not to keep connection alive (int,
-- defaults to 0)
-- @table sender_conf

--- Create a new sender object for the given DSN
-- @param conf Configuration table, see @{sender_conf}
-- @return A sender object
function _M.new(conf)
local obj, err = parse_dsn(conf.dsn)
if not obj then
return nil, err
end

obj.opts = {
verify = conf.verify_ssl or false,
keepalive = conf.keepalive or false,
keepalive_timeout = conf.keepalive_timeout or 0,
keepalive_pool = conf.keepalive_pool or 0
}

return setmetatable(obj, mt)
end

return _M