본문 바로가기

공부/Python

[Python]Chapter12 입/출력(input/output) 그리고 로깅(logging)

입/출력(Input/Output)


참고 사이트


01. 문자열형 데이터 메소드 format()의 기본 사용법 예제



02. 사용자로부터 이름을 입력받아서 출력



03. 인자 값이 여러 개인 경우



04. 중괄호 안에 인덱스(순서)가 들어간 경우



05. 중괄호 안에 인덱스(순서) 뿐만 아니라 변수명을 활용한 경우



06. 메소드 format()에 인덱스 및 변수명을 사용한 경우


여기서 lang은 매개 변수!





07. 문자열이나 튜플, 리스트 형 데이터들을 자동으로 언패킹하여 값을 출력 - format()의 인자 값으로 대입할 때 별표 기호(*)를 데이터 형 앞에 붙여 주면 된다.


문자열과 리스트 형 데이터 언패킹하여 출력 예시


08. 인자 값의 색인과 중괄호 기호([ ])를 활용하여 튜플이나 리스트, 사전 형의 항목을 추출


사전형 예제(위), 리스트형 예제(아래)




09. format()의 좌측, 중앙, 우측 정렬 기능


< : 좌측 정렬

> : 우측 정렬

^ : 중앙 정렬


콜론 기호( : ) : 글자 포맷을 명시

중괄호 안의 숫자 : 출력 결과의 전체 길이



10. 실수를 보기 좋게 출력하는 방법( : ) & 숫자 앞에 있는 기호를 제어하는 방법(+, -)




11. 여러 진수 표현





로깅(Logging)


참고 사이트1


01. 로깅이란?

: 소프트웨어가 실행될 때 일어나는 이벤트들을 추적하기 위한 용도로 소스 코드에 집어넣는 출력문을 작성하는 행위


02. 로그란?

- 로깅에 의해 출력된 출력문, 일반적으로 별도의 파일에 저장되어 체계적으로 관리됨, 

- 문제가 발생하였을 때 원인 분석을 하기 위한 중요한 데이터로 활용됨, 

- 여러 사람과 함께 개발하는 프로젝트에서 중요함,

- 일반적으로 로그에는 현재 소스코드에서 진행되고 있는 상황을 서술 형태로 기술함.

- 동적으로 변하고 있는 변수의 값을 출력하므로써 내부적으로 데이터가 어떻게 변하고 있는지 추적할 수 있게 해줌.

- 우리가 디버깅을 할 때, 중간에 변수들의 내용 등을 출력하고 싶거나 혹은 실행시 중요한 메시지를 어딘가에 저장하게 하여 우리의 프로그램이 제대로 실행되고 있는지 확인하고 싶을 때 사용[출처 : byte of python]


03. 로그의 레벨 


 

 레벨

대상 로그 

중요도 낮음



중요도 높음

DEBUG 

상세한 정보, 통상적으로 문제를 분석할 때에만 필요한 로그 

INFO 

소스 코드가 기대대로 동작하는지 확인하기 위한 로그 

WARNING 

예상치 못한 상황이 벌어질 조짐이 보이거나, 곧 일어날 문제(예-디스크 공간 부족)를 미리 알려주기 위한 로그, 소프트웨어는 여전히 잘 동작하고 있는 상황임 

ERROR 

WARNING보다 더 심각한 문제로 인하여 소프트웨어의 일부 기능이 제대로 동작하지 않을 때 필요한 로그 

CRITICAL 

가장 심각한 상황으로 인해 소프트 웨어 자체가 장애로 인해 더이상 실행할 수 없을 때 필요한 로그 


- 로그의 중요도가 높아질수록 로그의 레벨은 높아지며, 낮은 레벨의 로그는 높은 레벨의 로그를 포함한다.

- 만약 로그 레벨이 DEBUG라면 모든 로그가 출력될 것이다.

- 만약 로그 레벨이 WARNING이라면 DEBUG, INFO 레벨의 로그는 출력되지않고 WARNING, ERROR, CRITICAL 로그만 출력될 것이다.

- 참고) NOTSET : 모든 로그를 출력하겠다는 뜻이며 로거나 핸들러 생성시에 로그 레벨이 기본적으로 NOTSET으로 설정되어 있다.

- root 로거가 WARNING이면 새로 생성된 root 로거의 하위 로거는 세팅을 DEBUG로 하더라도 부모 로거에서 한차례 이미 걸려졌기 때문에 DEBUG나 INFO 메세지가 출력이 되지 않는다.



Q. 그러면 위의 코드들이 일반 소스코드들 중간에 들어가있는 건가?



04. 로그 메시지


형태 - 로그레벨 : 로거의 정보 : 출력 메시지


로거 - logging 모듈 안에 탑재되어 있는 일종의 객체, 로깅을 하는 주체

파이썬의 기본 로거는 root이다.



root 로거의 로그 레벨 변경하기 : logging.root.setLevel(logging.로그레벨)



05. 로깅 모듈을 사용하지 않고 그냥 print()문을 사용하여 로깅한다면?

- 운영자에게는 모든 레벨의 로그가 중요한 것이 아님.(개발자에게는 모든 레벨의 로그를 보고 자신이 만든 코드의 동작을 확인하는 중요한 기능이지만) 따라서 print()문을 사용한다면 개발자가 일일이 해당(운영자에게 중요하지 않은) print()문을 주석문 처리(comment out)하거나 지워서 서버에 배포해야하는 경우가 발생할 수 있음. 이는 기본적으로 개발 환경의 소스 코드와 운영 환경의 소스 코드가 서로 다르다는 것을 의미하며 또 다른 문제점을 야기할 가능성이 높아짐(= Side Effect)

+ 주석문 처리한 print()문이 다시 필요해서 #기호를 일일이 다시 삭제하거나 삭제한 print()문을 다시 작성하기도 해야함(ㅠㅠ)


06. 로깅 모듈이 제공하는 객체(서로 역할이 다름)


- 로거(Logger)

: 소스 코드에서 바로 호출하여 사용할 수 있는 인터페이스를 제공

: 일반적으로 파이썬 모듈 단위로 로거를 생성하며, 최상단에 root 로거 밑으로 계층 구조로 부모 자식관계를 형성

: 모든 로거는 root로거의 자식임.

: 로거의 생성, 획득 - 로거는 자체적으로 인스턴스를 생성할 수 없고, 무조건 logging 모듈의 getLogger(로거이름) 메소드에 의해 인스턴스화 된다.

*) __name__ 변수 : 모듈의 이름을 담고있는 변수



- 핸들러(Handler)

: 로거에 의해 생성된 로그 레코드(LogRecord)를 적절한 곳에 출력

: 로그는 콘솔이나 파일, 데이터베이스 등에 저장 가능하다.

: 로거는 여러 개의 핸들러를 보유할 수 있고, 핸들러는 반드시 특정 로거의 객체에 귀속된다.

: logger.addHandler(handler)


# 콘솔 출력용 핸들러 생성

handler = logging.StreamHandler()

# 파일 출력용 핸들러 생성

handler = logging.FileHandler('경로/파일이름.log')


- 포매터(Formatter)

: 위의 로그 포맷(기본 포맷)은 적절한 포맷은 아님. 일반적으로 로그에는 해당 로그가 찍힌 시간이 포함되고(추적이 용이하기 때문), 콜론 기호( : )는 익숙하지도 않고 찍힌 시간이 잘 구분되어 보이지 않음.

따라서 보기 쉽게 바꾸기 위해서 포매터를 사용한다.

: 로그의 출력 포맷(날짜와 시간, 파일명, 로그레벨, 메세지 등)을 결정함.

: logging.Formatter()

: handler.setFormatter(formatter)


Q. logging.basicConfig(format = '%(asctime)s : %(levelname)s : %(message)s',)와의 차이점?

내 생각) formatter는 특정 로거의 포맷을 설정, basicConfig는 일반적인 로거의 포맷을 설정(더 넓은 설정)?



: Formatter 함수에서 마지막의 소문자 s는 문자열을 뜻하고, %기호는 로그 레코드의 속성들을 호출하겠다는 의미.


: 로그 레코드의 주요 속성 호출 방법


%(asctime)s : 로그 레코드 생성 시간

%(filename)s : 로깅 소스 코드가 작성된 파일 이름(확장자 포함)

%(funcName)s : 로깅을 호출한 함수의 이름

%(levelname)s : 로그 레벨

%(lineno)d : 로그 소스 코드의 줄 위치

%(module)s : 모듈 이름(확장자 포함)

%(message)s : 로깅 메세지

%(name)s : 로거 이름

%(pathname)s : 로깅 소스 코드가 작성된 파일의 전체 경로(절대 경로)


07. 설정 파일


: 개발자와 운영자와같이, 역할이 다른 사람들이 바라보는 로그 레벨이 다를 수 있는데, 만약 파이썬 코드 내에서 직접 레벨을 지정(setLevel( ))하게 되면 사람마다 다른 소스 코드를 실행하게 된다.


: 이렇게 되면 같은 이름의 파이썬 소스 파일이지만 로그 레벨 설정 부분만 다른 중복되는 파일을 생성하게 되고, 이것은 다른 오류를 일으킬 가능성이 높아진다.


: 따라서 이러한 낭비, 오류를 막기 위해 대부분 소스 코드와는 별개의 '설정 파일'에 로그 레벨, 포매터, 핸들러, 로거 등의 설정을 기록해놓고, 파이썬 코드에서 해당 파일을 읽는 것으로 설정한다.


: 소스 코드가 변경이 될 가능성을 줄여주고, 설정 부분이 변경되면 소스 코드 수정 없이 설정 파일의 값만 수정하면 된다.


- 설정 방법



logging.config 모듈 : 설정 파일을 로딩

logging.config 모듈의 fileConfig( ) 메소드 : 설정 파일을 불러옴, 인자값은 설정파일 이름.