Nginx does not handle the scrolling problem of the log, it kicked the ball to the user. In general, you can use the Logrotate tool to accomplish this task, or you can write a variety of scripts to accomplish the same task if you wish. This article describes how to scroll the Nginx log files running in Docker (from the Internet).
Ideas
nginx the official actually gives instructions on how to scroll the log:
rotating log-files
in order to rotate log files, they need to be renamed first. A fter that USR1 signal should is sent to the master process. The master process would then re-open all currently open log files and assign them an unprivileged user under which the WOR Ker processes is running, as an owner. After successful re-opening, the master process closes all open files and sends the message to worker process to ask them to re-open files. Worker processes also open new files and close old files right away. As a result, old files is almost immediately available for post processing, such as compression.
- Rename the old log file first
- Then send the USR1 signal to the Nginx master process.
- After the Nginx master process receives the signal, it does some processing and then asks the worker process to reopen the log file
- Worker process opens a new log file and closes the old log file
In fact, we really need to do the work only two points ahead!
Create a test environment
Assuming that you have Docker installed in your system, here we run an nginx container directly:
$ docker run-d \ N: $ \ v $ (pwd)/logs/nginx:/var/log/ Nginx \ --restart= always\ --name=mynginx \ nginx:1.11. 3
Note that we have attached the Nginx log bindings to the logs directory under the current directory.
Save the following contents to the test.sh file:
#!/bin/bash for ((i=1; i<=100000; i++))do Curl http://localhost >/dev/null sleep1 done
Then run this script to simulate the generation of continuous log records.
create a script for rolling logs
Create the rotatelog.sh file with the following contents:
#!/bin/bashgetdatestring () {TZ = " Span style= "COLOR: #800000" >asia/chongqing " date " +%y%m%d%h%m " }datestring =$ (getdatestring) mv /var/log/nginx/access.log/var/log/nginx/access.${ Datestring}.log MV /var/log/nginx/error.log/var/log/nginx/error.${datestring}.log kill -usr1 ' cat /var/run/nginx.pid '
The getdatestring function takes the current time and formats it as a string, such as "201807241310", and I prefer to use the date and time to name the file. Note that this time zone is specified by tz= ' asia/chongqing ', because by default the UTC time is formatted, which is strange (to real-time brain tonic + 8 hours). The following two MV commands are used to rename the log file. Finally, the USR1 signal is sent to the Nginx master process via the KILL command.
Add the executable permissions to the rotatelog.sh file and copy it to the $ (PWD)/logs/nginx directory by using the following command:
chmod +x rotatelog. SH sudocp Rotatelog. sh $ (pwd)/logs/nginx
perform scrolling operations on a timed basis
Our Nginx runs in the container, so we need to send the USR1 signal to the Nginx master process in the container. So we need to execute the rotatelog.sh script in the Mynginx container through the Docker EXEC command:
$ docker exec Mynginx Bash/var/log/nginx/rotatelog. SH
Executing the command above will result in a new batch of log files as expected:
Let's configure this command in a timed task, which is executed 1 o'clock in the morning every day. Execute the CRONTAB-E command and add the following line at the end of the file:
1 * * * Docker exec Mynginx Bash/var/log/nginx/rotatelog. SH
Save and exit on the go. Is the author of the test process every 5 minutes of the effect of scrolling:
why not direct MV log files in the host?
In theory, this is possible, because the contents of the data volume that is mounted by the binding are the same from the host view and the calmly. But when you do, you're likely to run into permission problems. In a host, you typically use a normal user, and the owner of the log file generated in the container is a special user and generally does not write and execute permissions to other users:
Of course, if you are using the root user in the host, there will be no problem.
can I send a signal from the host?
In fact, the full name of this question should be: Can you send a signal to the Nginx master process in the Docker container from the host?
The answer is yes, yes.
This article, "capturing signals in Docker containers," describes the problem of capturing signals in containers, and interested friends can take a look. In that article we described Docker's kill command to send a signal to a process in a container. We can do this by command:
Kill Mynginx-s USR1
Send a USR1 signal to the 1th process (Nginx Master) in the container (this way you can only send a signal to process # 1th):
In combination with the above two questions, we can write another way to scroll the Nginx logs in Docker. In this way, you do not need to execute commands in the container through the Docker EXEC command, but do all of the work in the host:
- Rename the log files in the container data volume first
- Send USR1 signal to process # 1th in the container
Summary
In contrast, I prefer the first way, it is logically clear, the operation is almost completely isolated from the host, nor error prone. But with the second approach, we can not only find new implementations, but also deepen our understanding of container operations. Learning without thinking is no good!
Reference:
How to Configure Logging and logs Rotation in Nginx with an Ubuntu VPS
How to Manage Logfiles with Logrotate on Ubuntu 16.04