feat(lsp): add logging level "OFF" (#18379)

This commit is contained in:
ii14 2022-05-03 16:49:23 +02:00 committed by GitHub
parent 73741e9486
commit 70e2c5d10d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 31 deletions

View File

@ -750,7 +750,9 @@ omnifunc({findstart}, {base}) *vim.lsp.omnifunc()*
set_log_level({level}) *vim.lsp.set_log_level()* set_log_level({level}) *vim.lsp.set_log_level()*
Sets the global log level for LSP logging. Sets the global log level for LSP logging.
Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR" Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR",
"OFF"
Level numbers begin with "TRACE" at 0 Level numbers begin with "TRACE" at 0
Use `lsp.log_levels` for reverse lookup. Use `lsp.log_levels` for reverse lookup.

View File

@ -1012,6 +1012,7 @@ Log levels are one of the values defined in `vim.log.levels`:
vim.log.levels.INFO vim.log.levels.INFO
vim.log.levels.TRACE vim.log.levels.TRACE
vim.log.levels.WARN vim.log.levels.WARN
vim.log.levels.OFF
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
LUA-VIMSCRIPT BRIDGE *lua-vimscript* LUA-VIMSCRIPT BRIDGE *lua-vimscript*

View File

@ -58,6 +58,7 @@ vim.log = {
INFO = 2; INFO = 2;
WARN = 3; WARN = 3;
ERROR = 4; ERROR = 4;
OFF = 5;
} }
} }

View File

@ -1790,13 +1790,14 @@ end
-- --
-- Can be used to lookup the number from the name or the -- Can be used to lookup the number from the name or the
-- name from the number. -- name from the number.
-- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR" -- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"
-- Level numbers begin with "TRACE" at 0 -- Level numbers begin with "TRACE" at 0
lsp.log_levels = log.levels lsp.log_levels = log.levels
--- Sets the global log level for LSP logging. --- Sets the global log level for LSP logging.
--- ---
--- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR" --- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"
---
--- Level numbers begin with "TRACE" at 0 --- Level numbers begin with "TRACE" at 0
--- ---
--- Use `lsp.log_levels` for reverse lookup. --- Use `lsp.log_levels` for reverse lookup.

View File

@ -8,7 +8,7 @@ local log = {}
-- Log level dictionary with reverse lookup as well. -- Log level dictionary with reverse lookup as well.
-- --
-- Can be used to lookup the number from the name or the name from the number. -- Can be used to lookup the number from the name or the name from the number.
-- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR" -- Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"
-- Level numbers begin with "TRACE" at 0 -- Level numbers begin with "TRACE" at 0
log.levels = vim.deepcopy(vim.log.levels) log.levels = vim.deepcopy(vim.log.levels)
@ -25,27 +25,47 @@ do
end end
local logfilename = path_join(vim.fn.stdpath('cache'), 'lsp.log') local logfilename = path_join(vim.fn.stdpath('cache'), 'lsp.log')
-- TODO: Ideally the directory should be created in open_logfile(), right
-- before opening the log file, but open_logfile() can be called from libuv
-- callbacks, where using fn.mkdir() is not allowed.
vim.fn.mkdir(vim.fn.stdpath('cache'), "p")
--- Returns the log filename. --- Returns the log filename.
---@returns (string) log filename ---@returns (string) log filename
function log.get_filename() function log.get_filename()
return logfilename return logfilename
end end
vim.fn.mkdir(vim.fn.stdpath('cache'), "p") local logfile, openerr
local logfile = assert(io.open(logfilename, "a+")) ---@private
--- Opens log file. Returns true if file is open, false on error
local function open_logfile()
-- Try to open file only once
if logfile then return true end
if openerr then return false end
local log_info = vim.loop.fs_stat(logfilename) logfile, openerr = io.open(logfilename, "a+")
if log_info and log_info.size > 1e9 then if not logfile then
local warn_msg = string.format( local err_msg = string.format("Failed to open LSP client log file: %s", openerr)
"LSP client log is large (%d MB): %s", vim.notify(err_msg, vim.log.levels.ERROR)
log_info.size / (1000 * 1000), return false
logfilename end
)
vim.notify(warn_msg) local log_info = vim.loop.fs_stat(logfilename)
if log_info and log_info.size > 1e9 then
local warn_msg = string.format(
"LSP client log is large (%d MB): %s",
log_info.size / (1000 * 1000),
logfilename
)
vim.notify(warn_msg)
end
-- Start message for logging
logfile:write(string.format("[START][%s] LSP logging initiated\n", os.date(log_date_format)))
return true
end end
-- Start message for logging
logfile:write(string.format("[START][%s] LSP logging initiated\n", os.date(log_date_format)))
for level, levelnr in pairs(log.levels) do for level, levelnr in pairs(log.levels) do
-- Also export the log level on the root object. -- Also export the log level on the root object.
log[level] = levelnr log[level] = levelnr
@ -63,23 +83,26 @@ do
-- ``` -- ```
-- --
-- This way you can avoid string allocations if the log level isn't high enough. -- This way you can avoid string allocations if the log level isn't high enough.
log[level:lower()] = function(...) if level ~= "OFF" then
local argc = select("#", ...) log[level:lower()] = function(...)
if levelnr < current_log_level then return false end local argc = select("#", ...)
if argc == 0 then return true end if levelnr < current_log_level then return false end
local info = debug.getinfo(2, "Sl") if argc == 0 then return true end
local header = string.format("[%s][%s] ...%s:%s", level, os.date(log_date_format), string.sub(info.short_src, #info.short_src - 15), info.currentline) if not open_logfile() then return false end
local parts = { header } local info = debug.getinfo(2, "Sl")
for i = 1, argc do local header = string.format("[%s][%s] ...%s:%s", level, os.date(log_date_format), string.sub(info.short_src, #info.short_src - 15), info.currentline)
local arg = select(i, ...) local parts = { header }
if arg == nil then for i = 1, argc do
table.insert(parts, "nil") local arg = select(i, ...)
else if arg == nil then
table.insert(parts, format_func(arg)) table.insert(parts, "nil")
else
table.insert(parts, format_func(arg))
end
end end
logfile:write(table.concat(parts, '\t'), "\n")
logfile:flush()
end end
logfile:write(table.concat(parts, '\t'), "\n")
logfile:flush()
end end
end end
end end