nginx / unit

NGINX Unit - universal web app server - a lightweight and versatile open source server that simplifies the application stack by natively executing application code across eight different programming language runtimes.
https://unit.nginx.org
Apache License 2.0
5.26k stars 322 forks source link

Add support for writting application logs into stderr when Unit running inside of Docker #1124

Closed sidz closed 4 months ago

sidz commented 4 months ago

Hi guys.

I'm trying to run Nginx Unit inside of a Docker container with just one application inside of it. I'd like to write application logs to stderr and/or stdout streams so it will be possible to capture error logs and save it somewhere for example in the AWS Cloudwatch.

As far as I know it is not possible to write logs into stderr or stdout streams in --no-daemon mode. But it is not possible to run Nginx Unit inside of Docker container without this option.

Nginx Unit Docker template: https://github.com/nginx/unit/blob/master/pkg/docker/template.Dockerfile#L89.

Issue is extracted from https://github.com/nginx/unit/issues/915

cc @tippexs

tippexs commented 4 months ago

Hi @sidz sorry for the late response!

There is a workaround I use in my Containers that is NOT what I consider a final solution but it works.

Instead of

CMD ["unitd, "OPTIONS"]

I use

FROM unit:php

CMD ["/bin/bash", "-c", "unitd --log /dev/stdout; tail -f /dev/null"]

This will let you configure per application logging to different files that can be combined or scraped by other tools. Let me know if this works for you!

sidz commented 4 months ago

Thank you @tippexs ! I'll give it a try today and let you know.

As far as I understood you are writing application logs into files inside of container and it could be an issue as all our AWS instrastructure configured to scrap logs from the containers stderr/stdout and forward them to cloudwatch.

tippexs commented 4 months ago

If you would like to write all logs to stdout stderr then there is no need to change anything. Per default Unit in Docker will forward application logs to stdout. So there would be no need to define different logfiles if all of them are pointing to /dev/stdout.

The only issue will be that you are unable to see what application created the log entry. For example, in docker compose there will always be the service-name prefixed for each log-line. This is not the case in Unit. For this we would need to have a handy script that would tail multiple files and stream them prefixed by application to /dev/stdout. Another consideration would be the idea to do it the same way docker compose is doing it. I will provide some examples in a bit.

sidz commented 4 months ago

That's an amazing news @tippexs.

I did a new test with an official Nginx Unit image and it seems like it works like I expect!

The only issue will be that you are unable to see what application created the log entry.

That is not a problem for us as we will have just one application inside of container.

sidz commented 4 months ago

I'm going to close this ticket as I finally realized why Nginx Unit didn't write logs into stderr.