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

fix: reload once when log rotate #7869

Merged
Merged
Show file tree
Hide file tree
Changes from 3 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
53 changes: 41 additions & 12 deletions apisix/plugins/log-rotate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ local str_format = string.format
local str_reverse = string.reverse
local tab_insert = table.insert
local tab_sort = table.sort

local new_tab = require "table.new"
local ngx_sleep = require("apisix.core.utils").sleep
local isempty = require "table.isempty"
Copy link
Member

Choose a reason for hiding this comment

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

Better to introduce it via core.table

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

local local_conf


Expand All @@ -46,6 +48,7 @@ local INTERVAL = 60 * 60 -- rotate interval (unit: second)
local MAX_KEPT = 24 * 7 -- max number of log files will be kept
local MAX_SIZE = -1 -- max size of file will be rotated
local COMPRESSION_FILE_SUFFIX = ".tar.gz" -- compression file suffix
local WAIT_TIME_BEFORE_COMPRESS = 0.5 -- wait time before compress
local rotate_time
local default_logs
local enable_compression = false
Expand Down Expand Up @@ -218,25 +221,42 @@ local function file_size(file)
end


local function rotate_file(files, now_time, max_kept)
local function rotate_file(files, now_time, max_kept, wait_time)
if isempty(files) then
return
end

local new_files = new_tab(2, 0)
-- rename the log files
for _, file in ipairs(files) do
local now_date = os_date("%Y-%m-%d_%H-%M-%S", now_time)
local new_file = rename_file(default_logs[file], now_date)
if not new_file then
return
end

local pid = process.get_master_pid()
core.log.warn("send USR1 signal to master process [", pid, "] for reopening log file")
local ok, err = signal.kill(pid, signal.signum("USR1"))
if not ok then
core.log.error("failed to send USR1 signal for reopening log file: ", err)
end
tab_insert(new_files, new_file)
end

-- send signal to reopen log files
local pid = process.get_master_pid()
core.log.warn("send USR1 signal to master process [", pid, "] for reopening log file")
local ok, err = signal.kill(pid, signal.signum("USR1"))
if not ok then
core.log.error("failed to send USR1 signal for reopening log file: ", err)
end

if enable_compression then
-- Waiting for nginx reopen files
-- to avoid losing logs during compression
ngx_sleep(wait_time)
Copy link
Member

Choose a reason for hiding this comment

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

Will the sleep block the timer and cause the next rotation time incorrect?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

wait_time is just 0.5s by default. rotation time is much lager than 0.5s, right?

Copy link
Member

Choose a reason for hiding this comment

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

@monkeyDluffy6017
Currently, there is no limitation for the user-specific wait_time. BTW, we need to doc it if this argument is exposed to the user.

Copy link
Member

Choose a reason for hiding this comment

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

If the wait time is only for hardcode, maybe we can add extra sleep in the test so we don't need to set a special value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


if enable_compression then
for _, new_file in ipairs(new_files) do
compression_file(new_file)
end
end

for _, file in ipairs(files) do
-- clean the oldest file
local log_list, log_dir = scan_log_folder(file)
for i = max_kept + 1, #log_list do
Expand All @@ -254,11 +274,14 @@ local function rotate()
local interval = INTERVAL
local max_kept = MAX_KEPT
local max_size = MAX_SIZE
-- for test
local wait_time = WAIT_TIME_BEFORE_COMPRESS
local attr = plugin.plugin_attr(plugin_name)
if attr then
interval = attr.interval or interval
max_kept = attr.max_kept or max_kept
max_size = attr.max_size or max_size
wait_time = attr.wait_time or wait_time
enable_compression = attr.enable_compression or enable_compression
end

Expand All @@ -284,19 +307,25 @@ local function rotate()

if now_time >= rotate_time then
local files = {DEFAULT_ACCESS_LOG_FILENAME, DEFAULT_ERROR_LOG_FILENAME}
rotate_file(files, now_time, max_kept)
rotate_file(files, now_time, max_kept, wait_time)

-- reset rotate time
rotate_time = rotate_time + interval

elseif max_size > 0 then
local access_log_file_size = file_size(default_logs[DEFAULT_ACCESS_LOG_FILENAME].file)
local error_log_file_size = file_size(default_logs[DEFAULT_ERROR_LOG_FILENAME].file)
local files = new_tab(2, 0)

if access_log_file_size >= max_size then
rotate_file({DEFAULT_ACCESS_LOG_FILENAME}, now_time, max_kept)
tab_insert(files, DEFAULT_ACCESS_LOG_FILENAME)
end

if error_log_file_size >= max_size then
rotate_file({DEFAULT_ERROR_LOG_FILENAME}, now_time, max_kept)
tab_insert(files, DEFAULT_ERROR_LOG_FILENAME)
end

rotate_file(files, now_time, max_kept, wait_time)
end
end

Expand Down
1 change: 1 addition & 0 deletions t/plugin/log-rotate2.t
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ plugin_attr:
interval: 1
max_kept: 3
enable_compression: true
wait_time: 0
_EOC_

$block->set_value("yaml_config", $yaml_config);
Expand Down