Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python logging class in Docker: logs gone

Tags:

python

docker

For several years now I've used Python's logging class in the same way:

def get_module_logger(mod_name):
    """
    To use this, do logger = get_module_logger(__name__)
    """
    logger = logging.getLogger(mod_name)
    handler = logging.StreamHandler()
    formatter = logging.Formatter(
        '%(asctime)s [%(name)-12s] %(levelname)-8s %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    logger.setLevel(logging.DEBUG)
    return logger

Then in some module,

logger = get_module_logger(__name__)

Now, I am running a Python app that uses this inside of a Docker container. I am running the container with -d -i -t. When I am inside the container after a docker exec -it containername /bin/bash, I can see the logs if I execute a command in my python script that produces logs. However, from outside, docker logs containername never shows anything. I have tried running my container with PYTHONUNBUFFERED=0 per a few web posts and that did not help either. Tailing with docker logs -f containername never shows anything either. So all my logs, both stderr and stdout are empty. I have also tried logging.StreamHandler(sys.stdout) but to no avail.

What is wrong? Do I need to change something in the handler?

EDIT: my Dockerfile is very simple:

FROM python:3.5.1
MAINTAINER tommy@...
ADD . /tmp

#need pip > 8 to have internal pypi repo in requirements.txt
RUN pip install --upgrade pip 
#do the install
RUN pip install /tmp/py/

CMD myservice 

EDIT2:

~ docker --version
Docker version 1.11.0, build 4dc5990
like image 569
Tommy Avatar asked Aug 30 '16 11:08

Tommy


2 Answers

  • PYTHONUNBUFFERED=0 is turn on buffered, the log will be all output when the docker is closed.
    1. https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUNBUFFERED
PYTHONUNBUFFERED
If this is set to a non-empty string it is equivalent to specifying the -u option.
  1. https://docs.python.org/3/using/cmdline.html#cmdoption-u
-u
Force the stdout and stderr streams to be unbuffered. This option has no effect on the stdin stream.

See also PYTHONUNBUFFERED.

Changed in version 3.7: The text layer of the stdout and stderr streams now is unbuffered.
like image 132
bykebyn Avatar answered Nov 15 '22 07:11

bykebyn


I was able to see the log outputs and was not able to reproduce your issue with your code.

I created a file called tommy.py:

import logging

def get_module_logger(mod_name):
    """
    To use this, do logger = get_module_logger(__name__)
    """
    logger = logging.getLogger(mod_name)
    handler = logging.StreamHandler()
    formatter = logging.Formatter(
        '%(asctime)s [%(name)-12s] %(levelname)-8s %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    logger.setLevel(logging.DEBUG)
    return logger

if __name__ == "__main__":
    get_module_logger(__name__).info("HELLO WORLD!")

Ran the following:

docker run -d -v /tmp/tommy.py:/opt/tommy.py python:3.5 python /opt/tommy.py

And saw this:

$ docker logs -f sleepy_poincare 
2016-08-30 17:01:36,026 [__main__    ] INFO     HELLO WORLD!

Edit:
Here's my Docker version:

$ docker --version
Docker version 1.12.0, build 8eab29e
like image 30
mikehwang Avatar answered Nov 15 '22 07:11

mikehwang