Commit 24865c22 authored by Jérome Perrin's avatar Jérome Perrin

software/nginx-push-stream: implement log rotation

parent 690bafbf
Pipeline #18420 passed with stage
[template] [template]
filename = instance.cfg.in filename = instance.cfg.in
md5sum = 56e986c74ef236f261834c57f5861ce0 md5sum = 87fd83d33ba786550a45f484b3ae2b24
[template-nginx-configuration] [template-nginx-configuration]
filename = template-nginx.cfg.in filename = template-nginx.cfg.in
md5sum = 022e4b53e1b2db16c4e518fe76f638fa md5sum = 3eb7dda365d30c3c3c2ce939bbc607d4
[buildout] [buildout]
parts = parts =
nginx-service nginx-service
cron-service
cron-entry-logrotate
logrotate-entry-nginx
promises promises
publish-connection-information publish-connection-information
extends = ${monitor-template:rendered} extends = ${monitor-template:rendered}
...@@ -46,6 +49,7 @@ output = $${directory:etc}/nginx.cfg ...@@ -46,6 +49,7 @@ output = $${directory:etc}/nginx.cfg
mode = 0600 mode = 0600
access-log = $${directory:log}/nginx-access.log access-log = $${directory:log}/nginx-access.log
error-log = $${directory:log}/nginx-error.log error-log = $${directory:log}/nginx-error.log
pid-file = $${directory:run}/nginx.pid
ip = $${slap-configuration:ipv6-random} ip = $${slap-configuration:ipv6-random}
local-ip = $${slap-configuration:ipv4-random} local-ip = $${slap-configuration:ipv4-random}
port = 9443 port = 9443
...@@ -68,6 +72,15 @@ cert-file = $${directory:ssl}/${:_buildout_section_name_}.cert ...@@ -68,6 +72,15 @@ cert-file = $${directory:ssl}/${:_buildout_section_name_}.cert
common-name = $${nginx-configuration:ip} common-name = $${nginx-configuration:ip}
stop-on-error = true stop-on-error = true
[logrotate-entry-nginx]
<= logrotate-entry-base
name = nginx
log =
$${nginx-configuration:access-log}
$${nginx-configuration:error-log}
post =
test ! -s $${nginx-configuration:pid-file} || kill -USR1 $(cat "$${nginx-configuration:pid-file}")
[promises] [promises]
recipe = recipe =
promises = promises =
......
daemon off; # run in the foreground so supervisord can look after it daemon off; # run in the foreground so supervisord can look after it
worker_processes 4; worker_processes 4;
pid $${directory:run}/nginx.pid; pid $${nginx-configuration:pid-file};
events { events {
worker_connections 768; worker_connections 768;
......
...@@ -25,12 +25,16 @@ ...@@ -25,12 +25,16 @@
# #
############################################################################## ##############################################################################
import functools
import os import os
import lzma
import multiprocessing import multiprocessing
import urllib.parse
import uritemplate import uritemplate
import requests import requests
from slapos.testing.utils import CrontabMixin
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass( setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
...@@ -38,7 +42,7 @@ setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass( ...@@ -38,7 +42,7 @@ setUpModule, SlapOSInstanceTestCase = makeModuleSetUpAndTestCaseClass(
os.path.join(os.path.dirname(__file__), '..', 'software.cfg'))) os.path.join(os.path.dirname(__file__), '..', 'software.cfg')))
class TestNginxPushStream(SlapOSInstanceTestCase): class TestNginxPushStream(SlapOSInstanceTestCase, CrontabMixin):
def setUp(self): def setUp(self):
self.connection_parameters = \ self.connection_parameters = \
self.computer_partition.getConnectionParameterDict() self.computer_partition.getConnectionParameterDict()
...@@ -83,3 +87,55 @@ class TestNginxPushStream(SlapOSInstanceTestCase): ...@@ -83,3 +87,55 @@ class TestNginxPushStream(SlapOSInstanceTestCase):
self.assertEqual(q.get_nowait(), b': ') self.assertEqual(q.get_nowait(), b': ')
self.assertEqual(q.get_nowait(), b'data: Hello') self.assertEqual(q.get_nowait(), b'data: Hello')
def test_log_rotation(self):
status_url = urllib.parse.urljoin(
self.connection_parameters['publisher-url'], '/status')
error_url = urllib.parse.urljoin(
self.connection_parameters['publisher-url'], '/..')
log_file_path = functools.partial(
os.path.join,
self.computer_partition_root_path,
'var',
'log',
)
rotated_file_path = functools.partial(
os.path.join,
self.computer_partition_root_path,
'srv',
'backup',
'logrotate',
)
requests.get(status_url, verify=False)
with open(log_file_path('nginx-access.log')) as f:
self.assertIn('GET /status HTTP', f.read())
requests.get(error_url, verify=False)
with open(log_file_path('nginx-error.log')) as f:
self.assertIn('forbidden', f.read())
# first log rotation initialize the state, but does not actually rotate
self._executeCrontabAtDate('logrotate', '2050-01-01')
self._executeCrontabAtDate('logrotate', '2050-01-02')
# today's file is not compressed
with open(rotated_file_path('nginx-access.log-20500102')) as f:
self.assertIn('GET /status HTTP', f.read())
with open(rotated_file_path('nginx-error.log-20500102')) as f:
self.assertIn('forbidden', f.read())
# after rotation, the program re-opened original log file and writes in
# expected location.
requests.get(status_url, verify=False)
with open(log_file_path('nginx-access.log')) as f:
self.assertIn('GET /status HTTP', f.read())
requests.get(error_url, verify=False)
with open(log_file_path('nginx-error.log')) as f:
self.assertIn('forbidden', f.read())
self._executeCrontabAtDate('logrotate', '2050-01-03')
# yesterday's file are compressed
with lzma.open(rotated_file_path('nginx-access.log-20500102.xz'), 'rt') as f:
self.assertIn('GET /status HTTP', f.read())
with lzma.open(rotated_file_path('nginx-error.log-20500102.xz'), 'rt') as f:
self.assertIn('forbidden', f.read())
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment