Score:0

Why does default nginx access log show access.log > /dev/stdout

ls flag

I'm running nginx locally. Without adding any explicit logging configuration to nginx.conf, a symbolic link is added under /var/log/nginx, for access.log:

/var/log/nginx # ls -l

lrwxrwxrwx    1 root     root            11 Sep  9  2021 access.log -> /dev/stdout

If I add an explicit config to nginx.conf like so:

http {

    access_log /var/log/nginx/access2.log;

Then I get a regular log file in /var/log/nginx and logging works:

-rw-r--r--    1 root     root         11934 Aug  4 00:57 access2.log

My understanding is that /var/log/nginx is the default output destination for nginx logging. What's the purpose of the link to /dev/stdout? Am I missing something in how log data is supposed to persisted? Logging to syslog is described here - https://docs.nginx.com/nginx/admin-guide/monitoring/logging/, and facilitates logging data to be sent to a different source for persistence. What is the purpose of a symbolic link to /dev/stdout for the default logging, and why is it required?

I know that /dev/stdout acts as a device for output but I don't fully understand what's happening here. Is the access.log symlink just some type of mechanism to allow log output via /dev/stdout as a device, which then requires the actual logging definition to be supplied via the nginx config?

anx avatar
fr flag
anx
Defaulting to stdout is just a very cheap method making sure the invoking process does not need to know anything about the software to decide where logs *actually* go - by connecting stdout wherever it wants. Which in the case of that [stub resolver backlight color profile bootloader syslog compression thingy](https://github.com/systemd/systemd) might actually end up getting stuffed wherever the rest of the logs go.
Chris Halcrow avatar
ls flag
Thanks @anx. That essentially answers my main question. Happy to upvote if you want to make your comment an answer. In this case nginx is in a Docker container and I can view the nginx logs with `docker logs`. I don't really understand though how Docker or nginx is informing `/dev/stdout` of where to connect, and what's making the logs available in the Docker log.
Score:1
fr flag
anx

Every software is different, yet all software does or at least should be able produce some form of diagnostic logs. Since service management software, such as init (e.g. systemd) and docker cannot easily offer the best interface for every sort of software, you will often dumb it down to the least common denominator: Every program starts with stdin/stdout/stderr handles assigned index 0/1/2. On most systems following that convention, one can tell, through one way or another, a program that expect to open a file path to use /dev/stdout (or more verbosely: /proc/self/fd/1) and it will get what it already has at index 1 - the stdout handle it was equipped with when started.

And that seems to be what is happening here. Docker create some interface where it wants to accept or store your logs. In the simplest case, it would open a file - and instead of placing that file inside the container, it would just specify the open handle when deciding what stdout to start the container with. Now Nginx has that handle in its stdout slot, all that is missing is to clarify that it should write there. Where Nginx expects a file path, not a handle index, the slightly special path comes in, so that when Nginx works with that path like it would with any other regular file, it gets back what it was started with. This way docker does not need to know about Nginx internals, nor does Nginx need to know about docker internals. They can just do one of the most basix unix things there is: write lines of text to files.

Now this is not ideal, given that Nginx does speak a more expressive language than just files, so you could have its logs immediately partitioned into facilities and severity. I guess lines of text were good enough - or more reliable - for the purpose of that container.

Chris Halcrow avatar
ls flag
Thanks @anx. So I get that Nginx has a standard out, and that's linked to /dev/stdout as a device. So are you saying that /dev/stdout is somehow linked to the interface that docker provides for log storage? It's that part that I don't fully understand i.e. how /dev/stdout is being used as a device or how it constitutes being a 'device'
anx avatar
fr flag
anx
@ChrisHalcrow A slightly better name than "a device" would be to think of /dev/stdout as a "slightly special file that always points to the current processes file descriptor 1" - and in fact that is how it is visibly setup in modern Linux systems. The key takeaway is that *file-like* things are incredibly versatile, and the magic of procfs allows you to fulfil a programs request to be configured with a *path*, when what you want it to do is to *use an already available file descriptor*.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.