-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathinit.lua
More file actions
274 lines (227 loc) · 9.05 KB
/
init.lua
File metadata and controls
274 lines (227 loc) · 9.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
---@class platforms.lua
--- Standard Lua and LuaJIT platform implementation for distributed tracing
--- Provides initialization and auto-detection of HTTP libraries
local platform = {}
local tracing = require("sentry.tracing")
local http_client = require("platforms.lua.http_client")
local http_server = require("platforms.lua.http_server")
---Platform configuration
platform.config = {
name = "lua",
version = _VERSION or "Unknown",
auto_instrument = true,
supported_libraries = {
http_client = {"socket.http", "http.request"},
http_server = {"pegasus", "http.server"}
}
}
---Auto-instrumentation state
local auto_instrumentation_enabled = false
local instrumented_modules = {}
---Initialize platform-specific tracing features
---@param options table? Platform initialization options
function platform.init(options)
options = options or {}
-- Initialize core tracing
tracing.init(options.tracing)
-- Enable auto-instrumentation if requested
if options.auto_instrument ~= false then
platform.enable_auto_instrumentation()
end
-- Store platform-specific options
platform._options = options
end
---Enable automatic instrumentation of HTTP libraries
function platform.enable_auto_instrumentation()
if auto_instrumentation_enabled then
return
end
auto_instrumentation_enabled = true
-- Auto-instrument HTTP client libraries
platform.auto_instrument_http_clients()
-- Auto-instrument HTTP server libraries
platform.auto_instrument_http_servers()
end
---Disable automatic instrumentation
function platform.disable_auto_instrumentation()
auto_instrumentation_enabled = false
-- Restore original modules if they were instrumented
for module_name, original_module in pairs(instrumented_modules) do
package.loaded[module_name] = original_module
end
instrumented_modules = {}
end
---Auto-instrument HTTP client libraries
function platform.auto_instrument_http_clients()
-- Instrument LuaSocket HTTP module when required
local original_require = require
require = function(module_name)
local module = original_require(module_name)
-- Instrument socket.http when loaded
if module_name == "socket.http" and module and module.request then
if not instrumented_modules[module_name] then
instrumented_modules[module_name] = module
module = http_client.luasocket.wrap_http_module(module)
package.loaded[module_name] = module
end
end
-- Instrument http.request (lua-http) when loaded
if module_name == "http.request" and module and module.new then
if not instrumented_modules[module_name] then
instrumented_modules[module_name] = module
-- Wrap the constructor to return wrapped request objects
local original_new = module.new
module.new = function(...)
local request = original_new(...)
return http_client.lua_http.wrap_request(request)
end
package.loaded[module_name] = module
end
end
return module
end
end
---Auto-instrument HTTP server libraries
function platform.auto_instrument_http_servers()
local original_require = require
require = function(module_name)
local module = original_require(module_name)
-- Instrument Pegasus when loaded
if module_name == "pegasus" and module and module.new then
if not instrumented_modules[module_name] then
instrumented_modules[module_name] = module
-- Wrap the constructor to return wrapped server objects
local original_new = module.new
module.new = function(...)
local server = original_new(...)
return http_server.pegasus.wrap_server(server)
end
package.loaded[module_name] = module
end
end
return module
end
end
---Manually instrument an HTTP client
---@param client table The HTTP client object or module
---@param client_type string? Type of client ("luasocket", "lua-http", or auto-detect)
---@return table instrumented_client Instrumented client
function platform.instrument_http_client(client, client_type)
if not client then
error("HTTP client is required")
end
client_type = client_type or "auto"
if client_type == "auto" then
return http_client.auto_wrap(client)
elseif client_type == "luasocket" then
return http_client.luasocket.wrap_http_module(client)
elseif client_type == "lua-http" then
return http_client.lua_http.wrap_request(client)
else
error("Unsupported HTTP client type: " .. tostring(client_type))
end
end
---Manually instrument an HTTP server
---@param server table The HTTP server object
---@param server_type string? Type of server ("pegasus", "lua-http", or auto-detect)
---@return table instrumented_server Instrumented server
function platform.instrument_http_server(server, server_type)
if not server then
error("HTTP server is required")
end
server_type = server_type or "auto"
if server_type == "auto" then
return http_server.auto_wrap(server)
elseif server_type == "pegasus" then
return http_server.pegasus.wrap_server(server)
elseif server_type == "lua-http" then
return http_server.lua_http_server.wrap_server(server)
else
error("Unsupported HTTP server type: " .. tostring(server_type))
end
end
---Create a traced HTTP client function
---@param client_type string? Type of client to create ("luasocket")
---@return function http_get HTTP GET function with tracing
function platform.create_http_client(client_type)
client_type = client_type or "luasocket"
return http_client.create_get_function(client_type)
end
---Create a traced HTTP server
---@param server_type string Type of server to create ("pegasus")
---@param config table? Server configuration
---@return table server HTTP server with tracing
function platform.create_http_server(server_type, config)
return http_server.create_server(server_type, config)
end
---Wrap any function to continue traces from HTTP headers
---@param handler function The handler function to wrap
---@param extract_headers function? Custom header extraction function
---@return function wrapped_handler Handler with trace continuation
function platform.wrap_request_handler(handler, extract_headers)
return http_server.wrap_handler(handler, extract_headers)
end
---Create middleware for popular frameworks
---@param framework string Framework type ("pegasus", "generic")
---@return function middleware Middleware function
function platform.create_middleware(framework)
if framework == "pegasus" then
return http_server.pegasus.create_middleware()
elseif framework == "generic" then
return http_server.create_generic_middleware(function(request)
return request.headers or {}
end)
else
error("Unsupported framework: " .. tostring(framework))
end
end
---Get platform information
---@return table info Platform information
function platform.get_info()
return {
name = platform.config.name,
version = platform.config.version,
auto_instrumentation_enabled = auto_instrumentation_enabled,
instrumented_modules = (function()
local keys = {}
for k, _ in pairs(instrumented_modules) do
table.insert(keys, k)
end
return keys
end)(),
tracing_active = tracing.is_active(),
supported_libraries = platform.config.supported_libraries
}
end
---Check if a specific HTTP library is available
---@param library_name string Name of the library to check
---@return boolean available True if library is available
function platform.is_library_available(library_name)
local success, _ = pcall(require, library_name)
return success
end
---Get recommended HTTP client for this platform
---@return string|nil client_type Recommended HTTP client type or nil if none available
function platform.get_recommended_http_client()
if platform.is_library_available("socket.http") then
return "luasocket"
elseif platform.is_library_available("http.request") then
return "lua-http"
end
return nil
end
---Get recommended HTTP server for this platform
---@return string|nil server_type Recommended HTTP server type or nil if none available
function platform.get_recommended_http_server()
if platform.is_library_available("pegasus") then
return "pegasus"
elseif platform.is_library_available("http.server") then
return "lua-http"
end
return nil
end
-- Export core functionality for convenience
platform.tracing = tracing
platform.http_client = http_client
platform.http_server = http_server
return platform