Skip to content

Commit 3061f28

Browse files
committed
feat: add trace logging with an id to reconstruct chain of events
1 parent 865f40f commit 3061f28

File tree

3 files changed

+83
-34
lines changed

3 files changed

+83
-34
lines changed

lua/copilot/api.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
local logger = require("copilot.logger")
12
local mod = {}
23

34
---@param callback? fun(err: any|nil, data: table, ctx: table): nil
45
---@return any|nil err
56
---@return table data
67
---@return table ctx
78
function mod.request(client, method, params, callback)
9+
logger.trace("api request:", method, params)
810
-- hack to convert empty table to json object,
911
-- empty table is convert to json array by default.
1012
params._ = true
@@ -25,6 +27,7 @@ end
2527

2628
---@return boolean sent
2729
function mod.notify(client, method, params)
30+
logger.trace("api notify:", method, params)
2831
return client.notify(method, params)
2932
end
3033

lua/copilot/logger.lua

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ local mod = {
55
log_file = vim.fn.stdpath("log") .. "/copilot-lua.log",
66
file_log_level = vim.log.levels.OFF,
77
print_log_level = vim.log.levels.WARN,
8+
logger_id = 0,
89
}
910

1011
local log_level_names = {
@@ -24,33 +25,41 @@ end
2425

2526
---@param log_level integer --vim.log.levels
2627
---@param msg string
27-
---@param data any
28+
---@param ... any
2829
---@return string log_msg
29-
local function format_log(log_level, msg, data)
30+
local function format_log(log_level, msg, ...)
3031
local log_level_name = log_level_names[log_level]
31-
local log_msg = string.format("%s [%s]: %s", get_timestamp_with_ms(), log_level_name, msg)
32+
mod.logger_id = mod.logger_id + 1
3233

33-
if data then
34-
log_msg = string.format("%s\n%s", log_msg, vim.inspect(data))
34+
if mod.logger_id > 1000000 then
35+
mod.logger_id = 1
36+
end
37+
38+
-- we add an id as this process is asynchronous and the logs end up in a different order
39+
local log_msg = string.format("%s [%d] [%s]: %s", get_timestamp_with_ms(), mod.logger_id, log_level_name, msg)
40+
41+
local args = { ... }
42+
for _, v in ipairs(args) do
43+
log_msg = string.format("%s\n%s", log_msg, vim.inspect(v))
3544
end
3645

3746
return log_msg
3847
end
3948

4049
---@param log_level integer -- one of the vim.log.levels
4150
---@param msg string
42-
---@param data any
43-
local function notify_log(log_level, msg, data)
44-
local log_msg = format_log(log_level, msg, data)
51+
---@param ... any
52+
local function notify_log(log_level, msg, ...)
53+
local log_msg = format_log(log_level, msg, ...)
4554
vim.notify(log_msg, log_level)
4655
end
4756

4857
---@param log_level integer -- one of the vim.log.levels
4958
---@param log_file string
5059
---@param msg string
51-
---@param data any
52-
local function write_log(log_level, log_file, msg, data)
53-
local log_msg = format_log(log_level, msg, data) .. "\n"
60+
---@param ... any
61+
local function write_log(log_level, log_file, msg, ...)
62+
local log_msg = format_log(log_level, msg, ...) .. "\n"
5463

5564
uv.fs_open(log_file, "a", tonumber("644", 8), function(err, fd)
5665
if err then
@@ -70,52 +79,59 @@ end
7079

7180
---@param log_level integer -- one of the vim.log.levels
7281
---@param msg string
73-
---@param data any
82+
---@param ... any
83+
function mod.log(log_level, msg, ...)
84+
mod.log_force(log_level, msg, false, ...)
85+
end
86+
87+
---@param log_level integer -- one of the vim.log.levels
88+
---@param msg string
89+
---@param ... any
7490
---@param force_print boolean
75-
function mod.log(log_level, msg, data, force_print)
91+
function mod.log_force(log_level, msg, force_print, ...)
7692
if mod.file_log_level <= log_level then
77-
write_log(log_level, mod.log_file, msg, data)
93+
write_log(log_level, mod.log_file, msg, ...)
7894
end
7995

8096
if force_print or (mod.print_log_level <= log_level) then
81-
notify_log(log_level, msg, data)
97+
notify_log(log_level, msg, ...)
8298
end
8399
end
84100

85101
---@param msg string
86-
---@param data any
87-
function mod.debug(msg, data)
88-
mod.log(vim.log.levels.DEBUG, msg, data, false)
102+
---@param ... any
103+
function mod.debug(msg, ...)
104+
mod.log(vim.log.levels.DEBUG, msg, ...)
89105
end
90106

91107
---@param msg string
92-
---@param data any
93-
function mod.trace(msg, data)
94-
mod.log(vim.log.levels.TRACE, msg, data, false)
108+
---@param ... any
109+
function mod.trace(msg, ...)
110+
mod.log(vim.log.levels.TRACE, msg, ...)
95111
end
96112

97113
---@param msg string
98-
---@param data any
99-
function mod.error(msg, data)
100-
mod.log(vim.log.levels.ERROR, msg, data, false)
114+
---@param ... any
115+
function mod.error(msg, ...)
116+
mod.log(vim.log.levels.ERROR, msg, ...)
101117
end
102118

103119
---@param msg string
104-
---@param data any
105-
function mod.warn(msg, data)
106-
mod.log(vim.log.levels.WARN, msg, data, false)
120+
---@param ... any
121+
function mod.warn(msg, ...)
122+
mod.log(vim.log.levels.WARN, msg, ...)
107123
end
108124

109125
---@param msg string
110-
---@param data any
111-
function mod.info(msg, data)
112-
mod.log(vim.log.levels.INFO, msg, data, false)
126+
---@param ... any
127+
function mod.info(msg, ...)
128+
mod.log(vim.log.levels.INFO, msg, ...)
113129
end
114130

115131
---@param msg string
116-
---@param data any
117-
function mod.notify(msg, data)
118-
mod.log(vim.log.levels.INFO, msg, data, true)
132+
---@param ... any
133+
function mod.notify(msg, ...)
134+
mod.log_force(vim.log.levels.INFO, msg, true, ...)
119135
end
120136

121137
---@param conf copilot_config_logging

lua/copilot/suggestion.lua

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,18 @@ end
5151
local function get_ctx(bufnr)
5252
bufnr = bufnr or vim.api.nvim_get_current_buf()
5353
local ctx = copilot.context[bufnr]
54+
logger.trace("suggestion context", ctx)
5455
if not ctx then
5556
ctx = {}
5657
copilot.context[bufnr] = ctx
58+
logger.trace("suggestion new context", ctx)
5759
end
5860
return ctx
5961
end
6062

6163
---@param ctx copilot_suggestion_context
6264
local function reset_ctx(ctx)
65+
logger.trace("suggestion reset context", ctx)
6366
ctx.first = nil
6467
ctx.cycling = nil
6568
ctx.cycling_callbacks = nil
@@ -149,6 +152,7 @@ end
149152

150153
local function stop_timer()
151154
if copilot._copilot_timer then
155+
logger.trace("suggestion stop timer")
152156
vim.fn.timer_stop(copilot._copilot_timer)
153157
copilot._copilot_timer = nil
154158
end
@@ -172,28 +176,34 @@ end
172176

173177
---@param ctx? copilot_suggestion_context
174178
local function cancel_inflight_requests(ctx)
179+
logger.trace("suggestion cancel inflight requests", ctx)
175180
ctx = ctx or get_ctx()
176181

177182
with_client(function(client)
178183
if ctx.first then
179184
client.cancel_request(ctx.first)
180185
ctx.first = nil
186+
logger.trace("suggestion cancel first request")
181187
end
182188
if ctx.cycling then
183189
client.cancel_request(ctx.cycling)
184190
ctx.cycling = nil
191+
logger.trace("suggestion cancel cycling request")
185192
end
186193
end)
187194
end
188195

189196
local function clear_preview()
197+
logger.trace("suggestion clear preview")
190198
vim.api.nvim_buf_del_extmark(0, copilot.ns_id, copilot.extmark_id)
191199
end
192200

193201
---@param ctx? copilot_suggestion_context
194202
---@return copilot_get_completions_data_completion|nil
195203
local function get_current_suggestion(ctx)
204+
logger.trace("suggestion get current suggestion", ctx)
196205
ctx = ctx or get_ctx()
206+
logger.trace("suggestion current suggestion", ctx)
197207

198208
local ok, choice = pcall(function()
199209
if
@@ -229,6 +239,7 @@ end
229239
---@param ctx? copilot_suggestion_context
230240
local function update_preview(ctx)
231241
ctx = ctx or get_ctx()
242+
logger.trace("suggestion update preview", ctx)
232243

233244
local suggestion = get_current_suggestion(ctx)
234245
local displayLines = suggestion and vim.split(suggestion.displayText, "\n", { plain = true }) or {}
@@ -286,6 +297,7 @@ end
286297

287298
---@param ctx? copilot_suggestion_context
288299
local function clear(ctx)
300+
logger.trace("suggestion clear", ctx)
289301
ctx = ctx or get_ctx()
290302
stop_timer()
291303
cancel_inflight_requests(ctx)
@@ -295,6 +307,7 @@ end
295307

296308
---@param callback fun(err: any|nil, data: copilot_get_completions_data): nil
297309
local function complete(callback)
310+
logger.trace("suggestion complete")
298311
stop_timer()
299312

300313
local ctx = get_ctx()
@@ -314,6 +327,7 @@ local function handle_trigger_request(err, data)
314327
if err then
315328
logger.error(err)
316329
end
330+
logger.trace("suggestion handle trigger request", data)
317331
local ctx = get_ctx()
318332
ctx.suggestions = data and data.completions or {}
319333
ctx.choice = 1
@@ -322,10 +336,12 @@ local function handle_trigger_request(err, data)
322336
end
323337

324338
local function trigger(bufnr, timer)
339+
logger.trace("suggestion trigger", bufnr)
325340
local _timer = copilot._copilot_timer
326341
copilot._copilot_timer = nil
327342

328343
if bufnr ~= vim.api.nvim_get_current_buf() or (_timer ~= nil and timer ~= _timer) or vim.fn.mode() ~= "i" then
344+
logger.trace("suggestion trigger, not in insert mode")
329345
return
330346
end
331347

@@ -334,6 +350,7 @@ end
334350

335351
---@param ctx copilot_suggestion_context
336352
local function get_suggestions_cycling_callback(ctx, err, data)
353+
logger.trace("suggestion get suggestions cycling callback", data)
337354
local callbacks = ctx.cycling_callbacks or {}
338355
ctx.cycling_callbacks = nil
339356

@@ -367,6 +384,8 @@ end
367384
---@param callback fun(ctx: copilot_suggestion_context): nil
368385
---@param ctx copilot_suggestion_context
369386
local function get_suggestions_cycling(callback, ctx)
387+
logger.trace("suggestion get suggestions cycling", ctx)
388+
370389
if ctx.cycling_callbacks then
371390
table.insert(ctx.cycling_callbacks, callback)
372391
return
@@ -407,19 +426,23 @@ local function schedule(ctx)
407426
clear()
408427
return
409428
end
429+
logger.trace("suggestion schedule", ctx)
410430

411431
update_preview(ctx)
412432
local bufnr = vim.api.nvim_get_current_buf()
413433
copilot._copilot_timer = vim.fn.timer_start(copilot.debounce, function(timer)
434+
logger.trace("suggestion schedule timer", bufnr)
414435
trigger(bufnr, timer)
415436
end)
416437
end
417438

418439
function mod.next()
419440
local ctx = get_ctx()
441+
logger.trace("suggestion next", ctx)
420442

421443
-- no suggestion request yet
422444
if not ctx.first then
445+
logger.trace("suggestion next, no first request")
423446
schedule(ctx)
424447
return
425448
end
@@ -431,9 +454,11 @@ end
431454

432455
function mod.prev()
433456
local ctx = get_ctx()
457+
logger.trace("suggestion prev", ctx)
434458

435459
-- no suggestion request yet
436460
if not ctx.first then
461+
logger.trace("suggestion prev, no first request", ctx)
437462
schedule(ctx)
438463
return
439464
end
@@ -446,9 +471,11 @@ end
446471
---@param modifier? (fun(suggestion: copilot_get_completions_data_completion): copilot_get_completions_data_completion)
447472
function mod.accept(modifier)
448473
local ctx = get_ctx()
474+
logger.trace("suggestion accept", ctx)
449475

450476
-- no suggestion request yet
451477
if not ctx.first then
478+
logger.trace("suggestion accept, not first request", ctx)
452479
schedule(ctx)
453480
return
454481
end
@@ -466,7 +493,7 @@ function mod.accept(modifier)
466493
end
467494

468495
with_client(function(client)
469-
local ok, err = pcall(function()
496+
local ok, _ = pcall(function()
470497
api.notify_accepted(
471498
client,
472499
{ uuid = suggestion.uuid, acceptedLength = util.strutf16len(suggestion.text) },
@@ -568,6 +595,7 @@ end
568595

569596
local function on_insert_enter()
570597
if should_auto_trigger() then
598+
logger.trace("suggestion on insert enter")
571599
schedule()
572600
end
573601
end
@@ -581,13 +609,15 @@ end
581609
local function on_cursor_moved_i()
582610
local ctx = get_ctx()
583611
if copilot._copilot_timer or ctx.params or should_auto_trigger() then
612+
logger.trace("suggestion on cursor moved insert")
584613
schedule(ctx)
585614
end
586615
end
587616

588617
local function on_text_changed_p()
589618
local ctx = get_ctx()
590619
if not copilot.hide_during_completion and (copilot._copilot_timer or ctx.params or should_auto_trigger()) then
620+
logger.trace("suggestion on text changed pum")
591621
schedule(ctx)
592622
end
593623
end

0 commit comments

Comments
 (0)