본문 바로가기
CS/Python

Python print 함수를 stdout, stderr 로 출력하는 방법 - python 개발자가 stderr를 써야하는 이유

by Warehaus 2022. 6. 15.

python 에서는 print 함수를 정말로 많이 사용한다.
나는 표준출력을 목적으로 사용하기도 하지만 간단하게 Debugging 할 때에도 쓰는 것 같다.
대부분 개발자가 비슷하지 않을까 생각 해 본다.
그런데 실제 production 은 함부로 쓰기가 좀 조심 스러운게 사실이다.

조심스러운 표준 출력, stdout


일반적으로 python 에서 print 함수를 쓰면 stdout으로 출력이 된다.
https://docs.python.org/ko/3/library/functions.html#print

내장 함수 — Python 3.10.5 문서

내장 함수 파이썬 인터프리터에는 항상 사용할 수 있는 많은 함수와 형이 내장되어 있습니다. 여기에서 알파벳 순으로 나열합니다. abs(x) 숫자의 절댓값을 돌려줍니다. 인자는 정수, 실수 또는 __

docs.python.org


내장함수 print의 정의를 보면 file=sys.stdout이 기본 argument 값으로 지정되어 있음을 알 수 있다.


따라서 아래처럼 print에 입력 된 값이 콘솔에 출력이 되는 것이다.

>>> print("Hello?")
Hello?

그런데 이게 왜 조심스러울까?
개발자끼리 혹은 DevOps 끼리 사용하는 시스템이라면 크게 문제가 되지 않을 수 있지만,
시스템에 대한 이해도가 조금 부족한 Operator들이 실행만 시키는 업무 환경이라면 조금 얘기가 달라진다.
정말 말도 안된다고 생각하는 사람도 있겠지만, 그냥 모르는 출력이 나오면 문제있다고 하고 개발자 또는 조금이라도 시스템 담당자에게 물어보는게 운영환경의 현실이다.
그래서 나는 stdout으로 메시지를 출력하는게 조심 스럽다.

조금 덜 조심스러운 출력, stderr


그럼 조금이라도 운영자들에게 이상한 연락을 덜 받기위해 어떻게 해야하는가?
나는 stderr 를 적극적으로 활용하고 있다.
print 함수를 다음과 같이 작성하면 메시지를 stderr 로 출력이 가능하다.

>>> import sys
>>> print( "TEST", file=sys.stdout )
TEST
>>> print( "TEST", file=sys.stderr )
TEST

stdout에 한번, stderr에 한번 TEST를 출력해 보았다.
Python console 내에서는 그닥 차이가 없는데 python 파일로 만들어서 실행을 해 보자.
아래 예시를 보면 stderr를 /dev/null 에 써주면 stdout만 출력되고, stdout을 /dev/null 에 써주면 stderr만 출력되는 것을 볼 수 있다.

% python3 stderr.py 
TEST stdout
TEST stderr

% python3 stderr.py 2>/dev/null
TEST stdout
% python3 stderr.py 1>/dev/null
TEST stderr

다시 운영환경에서의 고충으로 돌아가 보자.
개발자는 사용자에게 에러메시지는 최대한 분리해서 보여주고 싶을 것이다.
그럴 때, print함수에서 stdout, stderr를 분리해서 사용하면 되는데 사용자가 필수적으로 확인해야하는 에러 부분만 stdout으로 출력될 수 있도록 하고, 나머지 디버깅에 필요한 정보는 stderr에 적어 로깅하는 방식을 사용하여 불필요한 연락을 줄일 수 있겠다.
예를들어 http request를 여러번 시도하는 코드가 있다고 생각해보자.
굳이 exception handling를 여러번 수행하는 메시지까지 사용자에게 다 보여줄 필요가 없다.
이런 부분은 stderr로 처리하고, 최종 성공 / 실패 여부만 stdout으로 뿌려줘도 충분할 것이다.
리눅스에서 stdout , stderr는 결국 파일이다.
이 파일로 print 함수의 내용을 쓰겠다는 의미를 코드에 담는다고 생각하면 조금은 머리속이 덜 복잡하지 않을까 싶다.