Gunicorn: STDOUT์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ๋กœ๊ทธ๋ฅผ ์–ด๋–ป๊ฒŒ ์ธ์‡„ํ•ฉ๋‹ˆ๊นŒ?

์— ๋งŒ๋“  2016๋…„ 01์›” 19์ผ  ยท  22์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: benoitc/gunicorn

์•ˆ๋…•,

http://docs.gunicorn.org/en/stable/settings.html#accesslog ๋Š” '-' ๊ฐ€ stderr๋กœ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋ผ๊ณ  ๋งํ•˜๊ณ  ์žˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๋กœ๊น… ๋ชฉ์ ์œผ๋กœ STDOUT์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์„ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๊ฐ์‚ฌ ํ•ด์š”!

Documentation FeaturLogging

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ํŒŒ์ผ myapp.py ๋กœ ๋‹ค์Œ์„ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

$ python --version
Python 3.5.2
$ gunicorn --version
gunicorn (version 19.7.0)
$ gunicorn --access-logfile - myapp:app 

์•ก์„ธ์Šค ๋กœ๊ทธ ์ถœ๋ ฅ์ด stdout ๋กœ ๊ฐ€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  22 ๋Œ“๊ธ€

๊ด€๋ จ ๋ผ์ธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. https://github.com/benoitc/gunicorn/blame/master/gunicorn/glogging.py#L335 logging.StreamHandler() ๊ธฐ๋ณธ๊ฐ’์€ sys.stderr ์ž…๋‹ˆ๋‹ค. ์•„๋งˆ๋„ "stdout" ๋ฐ "stderr"์„ ์œ ํšจํ•œ ๊ฐ’์œผ๋กœ ๋ฐ›์•„๋“ค์ด๊ณ  logging.StreamHandler() ์— ์ „๋‹ฌํ•˜๋„๋ก accesslog๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ ์—ฐํ•˜์ง€ ์•Š์€ ๋˜ ๋‹ค๋ฅธ ์†”๋ฃจ์…˜:

์ฝ˜์†” ํ•ธ๋“ค๋Ÿฌ๋Š” ์ด๋ฏธ sys.stdout ๋กœ ์ธ์‡„๋ฉ๋‹ˆ๋‹ค. https://github.com/benoitc/gunicorn/blob/master/gunicorn/glogging.py#L64 gunicorn.accesslog ์— ๋Œ€ํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ "console"๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/benoitc/gunicorn/blob/master/gunicorn/glogging.py#L55 ์—์„œ ์ด๋ฏธ gunicorn.error ์— ๋Œ€ํ•ด ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ

ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ์š”. StreamHandler๊ฐ€ ์ด๋ฏธ sys.stdout์— ๋กœ๊ทธ์˜จํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

์•„๋‹ˆ์š”, ๊ธฐ๋ณธ๊ฐ’์€ sys.stderr ์ž…๋‹ˆ๋‹ค. https://github.com/python/cpython/blob/master/Lib/logging/__init__.py#L955

์•Œ์•˜์–ด ์ด์ œ ์ดํ•ด ํ–ˆ์–ด. ์›๋ž˜ ์šฐ๋ฆฌ๋Š” stdout์— ๋กœ๊ทธ๋ฅผ ์ธ์‡„ํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. IMO ์•ก์„ธ์Šค ๋กœ๊ทธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ STDOUT์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒ๊ฐ?

@benoitc :+1:

stdout์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ๋กœ๊ทธ
stderr์— ๋Œ€ํ•œ ์˜ค๋ฅ˜ ๋กœ๊ทธ

์ด ์š”์ฒญ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@benoitc ์ด ์ปค๋ฐ‹์ด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š”์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ์ธ์ˆ˜ ์—†์ด gunicorn myapp:app ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. gunicorn์ด ํ‘œ์ค€ ์ถœ๋ ฅ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ธฐ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด gunicorn์€ ๊ทธ๋ ‡๊ฒŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์ค„ ์ธ์ˆ˜๊ฐ€ ์—†๋Š” https://github.com/benoitc/gunicorn/blob/master/gunicorn/glogging.py#L302 self.cfg.accesslog ๋Š” None ์ด๊ณ  ํ•จ์ˆ˜๋Š” ์ผ์ฐ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜์žˆ๋Š” ํ•œ --log-config ๋˜๋Š” --log-syslog ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  stdout์— ๋กœ๊ทธ์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ์˜ฌ๋ฐ”๋ฅธ์ง€?

์ด๊ฒƒ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋ผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์•ก์„ธ์Šค ๋กœ๊ทธ๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ?

@benoitc ๋„ค. ์œ„์˜ ๋…ผ์˜๋Š” ์•ก์„ธ์Šค ๋กœ๊ทธ๊ฐ€ stdout์œผ๋กœ ์ด๋™ํ•˜๊ณ  ์˜ค๋ฅ˜ ๋กœ๊ทธ๊ฐ€ stderr๋กœ ์ด๋™ํ•จ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•ก์„ธ์Šค ๋กœ๊น…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

BTW, Python 2.7์„ ์‚ฌ์šฉํ•˜์—ฌ --access-log /dev/stdout --error-log /dev/stderr ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  ์ž‘๋™ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. Python 3์—์„œ ์ธ์ˆ˜๋กœ /dev/stdout ์ „๋‹ฌ ์‹คํŒจ

๐Ÿ‘ @suriya ๋‚˜๋Š” ๋‹น์‹ ๊ณผ ๊ฐ™์€ ํ–‰๋™์„ ์ฐพ๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค -- --capture-log ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  --access-logfile=<something> $ ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์•ก์„ธ์Šค ๋กœ๊ทธ ๋ผ์ธ์ด stdout์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค ํ‘œ์ค€ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

ํŽธ์ง‘: ๋ช…ํ™•ํžˆ ํ•˜์ž๋ฉด ์ด๊ฒƒ์€ Python3์˜ ๋ฌธ์ œ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. python3.5.1์„ ์‚ฌ์šฉํ•˜์—ฌ --access-logfile=/dev/stdout ๋ฅผ gunicorn์— ์ „๋‹ฌํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ˆ, ์•ก์„ธ์Šค ๋กœ๊น…์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@huoxy ๊ธฐ๋ณธ๊ฐ’๋ณด๋‹ค ๋” ๋ฌธ์ œ๋Š” ํ‘œ์ค€ ์ถœ๋ ฅ์— ์•ก์„ธ์Šค ๋กœ๊ทธ๋ฅผ ์“ฐ๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@huoxy ห‹--access-logfile=-`์ด ํŠธ๋ฆญ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ผ๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

  • ๋ฒ ๋ˆ„์•„
    2016๋…„ 7์›” 27์ผ ์ˆ˜์š”์ผ 08:49 Suriya Subramanian [email protected]
    ์ผ๋‹ค:

@huoxy https://github.com/huoxy ๊ธฐ๋ณธ๊ฐ’๋ณด๋‹ค ๋” ๋งŽ์€ ๊ฒƒ ๊ฐ™์•„์š”
๋ฌธ์ œ๋Š” ์•ก์„ธ์Šค ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
ํ‘œ์ค€ ์ถœ๋ ฅ.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/benoitc/gunicorn/issues/1184#issuecomment -235501347,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AAA4oj67GbLqwaJaCQ9NOH7-iAXJoMxGks5qZv9fgaJpZM4HHW4G
.

๋˜ํ•œ ์•„๋งˆ๋„ ๋ฌธ์„œ ๋ฌธ์ œ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•ก์„ธ์Šค ๋กœ๊ทธ๋Š” stdout์— ์ธ์‡„๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
- ๊ฐ€ ์‚ฌ์šฉ๋  ๋•Œ. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฒ„๊ทธ์ž…๋‹ˆ๋‹ค. ์•Œ๋ ค ์ค˜์š”...
2016๋…„ 7์›” 27์ผ ์ˆ˜์š”์ผ 09:03์— Benoit Chesneau [email protected] ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

@huoxy ห‹--access-logfile=-`์ด ํŠธ๋ฆญ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ผ๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

  • ๋ฒ ๋ˆ„์•„
    2016๋…„ 7์›” 27์ผ ์ˆ˜์š”์ผ 08:49 Suriya Subramanian [email protected]
    ์ผ๋‹ค:

@huoxy https://github.com/huoxy ๊ธฐ๋ณธ๊ฐ’๋ณด๋‹ค ๋” ๋งŽ์€ ๊ฒƒ ๊ฐ™์•„์š”
๋ฌธ์ œ๋Š” ์•ก์„ธ์Šค ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
ํ‘œ์ค€ ์ถœ๋ ฅ.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/benoitc/gunicorn/issues/1184#issuecomment -235501347,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AAA4oj67GbLqwaJaCQ9NOH7-iAXJoMxGks5qZv9fgaJpZM4HHW4G
.

@benoitc #1293์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด gunicorn --access-log - ๋Š” ํ‘œ์ค€ ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. gunicorn --access-log=- ๋กœ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๋กœ๊ทธ๋Š” ์—ฌ์ „ํžˆ ํ‘œ์ค€ ์˜ค๋ฅ˜๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด์— ๋”ฐ๋ฅด๋ฉด:
https://github.com/gunicorn/gunicorn/blob/master/gunicorn/glogging.py#L58

๊ธฐ๋ณธ ๋กœ๊ฑฐ๋Š” stdout์œผ๋กœ ์ถœ๋ ฅ๋˜๋Š” console ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ €์ฒ˜๋Ÿผ stdout์— ๋ชจ๋“  ๊ฒƒ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ชจ๋“  ๊ฒƒ์ด gunicorn ๋กœ๊น… ๋“œ๋ผ์ด๋ฒ„์— ๋„๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ์˜ต์…˜์„ ๋น„์›Œ ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‚ด๊ฐ€ ์ œ์•ˆํ•˜๋Š” ์†”๋ฃจ์…˜์€ ์ง์ ‘ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ /dev/stdout ๋˜๋Š” /dev/stderror ์— ๋Œ€ํ•œ ๋กœ๊ทธ ํŒŒ์ผ์— ๋Œ€ํ•œ ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ln -sf /var/log/gunicorn.access.log  /dev/stdout
ln -sf /var/log/gunicorn.error.log  /dev/stdout

exec newrelic-admin run-program gunicorn --chdir /usr/src/app --name nexchange --bind 0.0.0.0:${GUNICORN_PORT} --workers 3 --log-level=info --log-file=/var/log/gunicorn.error.log --access-logfile=/var/log/gunicorn.access.log nexchange.wsgi:application "$@"

์ง€๋‚œ์ฃผ์— ์ถœ์‹œ๋œ gunicorn 19.7.0์œผ๋กœ ๋ฐฉ๊ธˆ ์˜ฎ๊ฒผ์Šต๋‹ˆ๋‹ค. ๋ถˆํ–‰ํžˆ๋„, ๋‚˜๋Š” ์—ฌ์ „ํžˆ stderr ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ฒƒ์— ๊ธฐ๋ก๋œ ์•ก์„ธ์Šค ๋กœ๊ทธ๋ฅผ ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์˜ต์…˜ ์—†์ด "--access-logfile=- --error-logfile=- --log-level=DEBUG"๋ฅผ ํฌํ•จํ•˜๊ฑฐ๋‚˜ ํฌํ•จํ•˜์ง€ ์•Š๋Š” ๋ชจ๋“  ์ˆœ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ gunicorn์„ ์‹คํ–‰ํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.

gunicorn์˜ ๋กœ๊น…์— ๋Œ€ํ•œ ๊ธฐ๋ณธ์ ์ธ ๊ฒƒ์„ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด ํ™˜๊ฒฝ์ด๋‚˜ Django์˜ ๋ฌด์–ธ๊ฐ€๊ฐ€ ์ถœํ˜ˆ์„ ์ผ์œผ์ผœ ์ด ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ํŒŒ์ผ myapp.py ๋กœ ๋‹ค์Œ์„ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

$ python --version
Python 3.5.2
$ gunicorn --version
gunicorn (version 19.7.0)
$ gunicorn --access-logfile - myapp:app 

์•ก์„ธ์Šค ๋กœ๊ทธ ์ถœ๋ ฅ์ด stdout ๋กœ ๊ฐ€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” Python 2.7.14๋ฅผ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹ค. (๋ช‡ ๋‹ฌ ์ „์— ๋น ๋ฅธ ์‘๋‹ต์„ ๋†“์ณค์Šต๋‹ˆ๋‹ค.)

gunicorn.config.py์—์„œ accesslog = "-" ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰