| # |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You under the Apache License, Version 2.0 |
| # (the "License"); you may not use this file except in compliance with |
| # the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| |
| use t::APISIX 'no_plan'; |
| |
| repeat_each(1); |
| no_long_string(); |
| no_shuffle(); |
| no_root_location(); |
| |
| add_block_preprocessor(sub { |
| my ($block) = @_; |
| |
| my $user_yaml_config = <<_EOC_; |
| apisix: |
| node_listen: 1984 |
| admin_key: null |
| |
| plugins: # plugin list |
| - log-rotate |
| |
| plugin_attr: |
| log-rotate: |
| interval: 1 |
| max_kept: 3 |
| _EOC_ |
| |
| $block->set_value("yaml_config", $user_yaml_config); |
| |
| |
| if ((!defined $block->error_log) && (!defined $block->no_error_log)) { |
| $block->set_value("no_error_log", "[error]"); |
| } |
| |
| if (!defined $block->request) { |
| $block->set_value("request", "GET /t"); |
| } |
| |
| }); |
| |
| run_tests; |
| |
| __DATA__ |
| |
| === TEST 1: log rotate |
| --- config |
| location /t { |
| content_by_lua_block { |
| ngx.log(ngx.ERR, "start xxxxxx") |
| ngx.sleep(2.5) |
| local has_split_access_file = false |
| local has_split_error_file = false |
| local lfs = require("lfs") |
| for file_name in lfs.dir(ngx.config.prefix() .. "/logs/") do |
| if string.match(file_name, "__access.log$") then |
| has_split_access_file = true |
| end |
| |
| if string.match(file_name, "__error.log$") then |
| local f = assert(io.open(ngx.config.prefix() .. "/logs/" .. file_name, "r")) |
| local content = f:read("*all") |
| f:close() |
| local index = string.find(content, "start xxxxxx") |
| if index then |
| has_split_error_file = true |
| end |
| end |
| end |
| |
| if not has_split_access_file or not has_split_error_file then |
| ngx.status = 500 |
| else |
| ngx.status = 200 |
| end |
| } |
| } |
| --- error_code eval |
| [200] |
| |
| |
| |
| === TEST 2: in current log |
| --- config |
| location /t { |
| content_by_lua_block { |
| ngx.sleep(0.1) |
| ngx.log(ngx.WARN, "start xxxxxx") |
| ngx.say("done") |
| } |
| } |
| --- response_body |
| done |
| --- error_log |
| start xxxxxx |
| |
| |
| |
| === TEST 3: fix: ensure only one timer is running |
| --- config |
| location /t { |
| content_by_lua_block { |
| ngx.sleep(0.5) |
| local t = require("lib.test_admin").test |
| local code, _, org_body = t('/apisix/admin/plugins/reload', |
| ngx.HTTP_PUT) |
| |
| ngx.status = code |
| ngx.say(org_body) |
| |
| ngx.sleep(1) |
| |
| local lfs = require("lfs") |
| for file_name in lfs.dir(ngx.config.prefix() .. "/logs/") do |
| if string.match(file_name, "__error.log$") then |
| local f = assert(io.open(ngx.config.prefix() .. "/logs/" .. file_name, "r")) |
| local content = f:read("*all") |
| f:close() |
| local counter = 0 |
| ngx.re.gsub(content, [=[run timer\[plugin#log-rotate\]]=], function() |
| counter = counter + 1 |
| return "" |
| end) |
| |
| if counter ~= 1 then |
| ngx.say("not a single rotator run at the same time: ", file_name) |
| end |
| end |
| end |
| } |
| } |
| --- response_body |
| done |
| |
| |
| |
| === TEST 4: disable log-rotate via hot reload |
| --- config |
| location /t { |
| content_by_lua_block { |
| local data = [[ |
| apisix: |
| node_listen: 1984 |
| admin_key: null |
| plugins: |
| - prometheus |
| ]] |
| require("lib.test_admin").set_config_yaml(data) |
| local t = require("lib.test_admin").test |
| local code, _, org_body = t('/apisix/admin/plugins/reload', |
| ngx.HTTP_PUT) |
| |
| ngx.status = code |
| ngx.say(org_body) |
| |
| ngx.sleep(2.1) -- make sure two files will be rotated out if we don't disable it |
| |
| local n_split_error_file = 0 |
| local lfs = require("lfs") |
| for file_name in lfs.dir(ngx.config.prefix() .. "/logs/") do |
| if string.match(file_name, "__error.log$") then |
| n_split_error_file = n_split_error_file + 1 |
| end |
| end |
| |
| -- Before hot reload, the log rotate may or may not take effect. |
| -- It depends on the time we start the test |
| ngx.say(n_split_error_file <= 1) |
| } |
| } |
| --- response_body |
| done |
| true |
| |
| |
| |
| === TEST 5: check file changes (disable compression) |
| --- config |
| location /t { |
| content_by_lua_block { |
| ngx.sleep(2) |
| |
| local default_logs = {} |
| for file_name in lfs.dir(ngx.config.prefix() .. "/logs/") do |
| if string.match(file_name, "__error.log$") or string.match(file_name, "__access.log$") then |
| local filepath = ngx.config.prefix() .. "/logs/" .. file_name |
| local attr = lfs.attributes(filepath) |
| if attr then |
| default_logs[filepath] = { change = attr.change, size = attr.size } |
| end |
| end |
| end |
| |
| ngx.sleep(1) |
| |
| local passed = false |
| for filepath, origin_attr in pairs(default_logs) do |
| local check_attr = lfs.attributes(filepath) |
| if check_attr.change == origin_attr.change and check_attr.size == origin_attr.size then |
| passed = true |
| else |
| passed = false |
| break |
| end |
| end |
| |
| if passed then |
| ngx.say("passed") |
| end |
| } |
| } |
| --- response_body |
| passed |