알고리즘 공부, 코딩 테스트 연습을 안한지 꽤 오래 되어 문제를 보기 전부터 많이 긴장 했었다. 그리고 당일이 되어 문제가 공개되고 문제를 풀기 시작하는데 코딩 테스트를 안한지도 오래되고 긴장도 해 단순 입출력을 어떻게 받는지 등이 잠깐 생각이 안났지만 문제를 보다보니 기억이 점점 돌아와 가볍게 풀 수 있었다.
문제의 핵심은 소수점 이하 버림을 해결할 수 있느냐의 문제인것 같다.
처음에는 문제를 아무리 봐도 맞게 푼 것 같은데 몇몇 문제에서 오답이 나와 구름 유니버스에서도 계속 도움을 요청하며 돌아다녔다. 아직 문제가 나온지 얼마안된 초반이라 푼 사람도 몇명이 없어서 도움을 못받고 포기하고 저녁을 먹고 다시 돌아와 다시보니 Math.floor 라고 적어야 하는데 Math.round 라고 작성해 소수점 이하 버림이 아닌 소수점 반올림으로 작성했던것이였다. 그래서 다시 Math.floor 라고 수정해 통과할 수 있었다. 코딩 테스트가 오랜만이라 Math 함수 등도 오랜만에 써서 단순 실수 였었다.
이제 파이보게시판을 만들어서 누구나 접속할 수 있게 되었다. 하지만 점프 투 장고 에서 추가로 설명한 도메인설정, SSL, PostgreSQL 등 도 하지 않았다. 보안이나 관리의 편의성 등에 문제가 있을 수 있는 게시판이지만 유료로 도메인을 등록할 필요성등을 아직 못느꼈기 때문에 하지 않았다. 점프 투 장고 온라인 책을 보며 만들었는데 따라서 파이참, 장고, DB, AWS, 등 대부분이 다 처음 사용해보는것들이였다. 이제 책없이 처음부터 다시 만들라고 하면 못만들것 같긴하지만 그래도 한번 만들어 본 경험이 있기 때문에 책을보며 다시 만든다면 막히는 부분없이 잘 만들 수 있을것같다. 학교에서 그냥 프로그래밍 언어만 배우며 얻지 못했던 지식들이나 학교에서 제대로 공부하지 않았던 부분을 다시 배우며 개발과정 전체의 흐름을 이해하는 계기가 되었다. 파이썬과 장고가 내가 미래에 사용할 주된언어가 될지 아닐지는 모르지만 기본적인 틀을 배웠다고 생각한다. 그냥 학교에서 내주는 하나의 과제가 아닌 스스로 공부하며 시작해보는 프로젝트 자체가 처음이라 정말 좋은 경험이였다. 점프 투 장고를 배우며 다시 정리하는 느낌으로 블로그를 작성했는데 말솜씨가 좋지 않아 점프 투 장고 온라인 책을 그대로 옮겨적는 것 같은 느낌이 되버린것이 정말 아쉽다. 이게 책의 저자님께 피해가 가거나 그렇게 되지를 않기를 바라고 있다. 마지막으로 이 책의 저자님께 감사하다는 말을 드리고 싶다. 다른 사람들도 한번씩 해보는것도 좋을것 같다.
저번 게시물에서 DEBUG=False 로 설정했기 때문에 파이보 이용중 오류가 발생한다면 404오류같은 페이지가 출력되고 오류의 원인같은 정보는 출력되지 않는다. 이제 오류의 원인이 무엇인지 파악을 할 수 없는데 그렇다고 DEBUG=True 로 변경할수는 없다. 이를 해결하기 위해 로그 파일을 이용하는것이 가장 좋다.
disable_existing_loggers 항목은 False로 설정했다. True 로 설정하면 기존에 설정된 로거들을 사용하지 않는다. 파이보도 False 로 설정할 것이다.
filters 는 특정 조건에서 로그를 출력하거나 출력하지 않기 위해서 아용된다. require_debug_false 필터는 DEBUG=False 인지 판단하는 필터이고 require_debug_ture 필터는 디버그가 True 인지 판단하는 필터이다.
formatters 는 로그를 출력할 형식을 정한다. 포맷터에 사용된 항목은 server_time(서버의 시간), message(출력 내용) 이다.
handlers 는 로그의 출력방법을 정의한다. console은 콘솔에 로그를 출력한다. 로그레벨이 INFO 이상이고 디버그가True 일때만 로그를 출력한다.
django.server 는 python manage.py runserver 로 작동하는 개발 서버에서만 사용하는 핸들러로 콘솔에 로그를 출력한다. mail_admins 는 로그내용을 이메일로 전송하는 핸들러로 로그레벨이 ERROR 이상이고 DEBUG=False 일때만 로그를 전송한다. 이 핸들러를 사용하려면 환경설정파일에 ADMINS 항목을추가하고 관리자 이메일을 추가해줘야한다. 그리고 이메일발송을 위한 SMTP 설정도 해줘야한다.
loggers 항목은 로그를 출력하는 프로그램에서 사용하는 로거의 이름을 의미한다. django 는 장고 프레임워크가 사용하는 로거이고 로그 레벨이 INFO이상일 경우에만 로그를 출력한다. django.server 는 개발서버가 사용하는 로거로 로그레벨이 INFO 이상일 경우에만 로그를 출력한다. 'propagate' : False 의 의미는 django.server 가 출력하는 로그를 장고 로거로 전달하지 않는다는 의미이다. True 로 최상위 패키지명이 django 로 동일하기 때문에 django.server 하위 패키지에서 출력하는 로그가 django.server 로거에도 출력되고 django 로거에도 출력되어 이중출력 현상이 발생한다.
로그레벨은 5단계로 구성된다. logging.debug, logging.info, logging.warning, logging.error, logging.critical 함수로 출력된다.
1단계 DEBUG : 디버깅 목적으로 사용된다.
2단계 INFO : 일반 정보를 출력할 목적으로 사용된다.
3단계 WARNING : 경고 정보를 출력할 목적으로 사용된다. 주로 작은문제를 출력한다.
4단계 ERROR : 오류 정보를 출력할 목적으로 사용된다. 주로 큰 문제를 출력한다.
5단계 CRITICAL : 아주 심각한 문제를 출력할 목적으로 사용된다.
로그는 설정한 레벨 이상의 로그만 출력된다. 예를들어 핸들러나 로거의 레벨을 INFO로 설정하면 DEBUG로그는 출력되지 않고, INFO 이상의 로그 INFO, WARNING, ERROR, CRITICAL 로그들만 출력된다.
이 파일들을 적용하기위해 먼저 projects\mysite\config\settings\base.py 에 위에 적힌 DEFAULT_LOGGING 을 복사하자.
복사를 그대로 하는데 이름만 DEFAULT_LOGGING 에서 LOGGING 으로 변경해주자.
그리고 포맷터 standard 를 추가하자.
standard 포맷터에 사용한 항목들은 asctime(현재시간), levelname(로그의 레벨,단계), name(로거명), message(출력 내용) 이다.
handlers 에 file 핸들러도 추가해주자.
file 핸들러에 사용한 항목은
level : 출력 레벨로 INFO를 사용
filters : DEBUG=False 인 운영환경에서 사용
class : 파일 핸들러로 RotatingFileHandler 사용. RotatingFileHandler 는 파일 크기가 설정한 크기보다 커지면 파일 뒤에 인덱스를 붙여서 백업한다. 이 핸들러의 장점은 로그가 무한히 증가해도 일정 개수의 파일로 Rolling 되기 때문에 로그 파일이 너무 켜저 디스크가 꽉 차는 위험을 방지한다.
filename : 로그 파일명은 logs 디렉토리에 mysite.log 로 설정
maxBytes : 로그 파일의 최대 크기는 5MB
backupCount : 롤릴되는 파일의 개수는 총 5개로 설정
formatter : 포맷터는 standard를 사용.
마지막으로 django 로거의 handlers 에 file 핸들러를 추가하자.
설정을 다 완료한 후 git으로 서버에 적용하자. 서버에 적용한 후 서버에 logs 디렉토리를 만들어 주자.
개발환경에서도 projects\mysite\logs 디렉토리를 만들어주자. 그리고 logs 디렉토리는 버전 관리 대상이 아니므로 .gitignore 파일에 logs 디렉토리를 추가하자.
잘 적용되었나 테스트를 해보기 위해
projects\mysite\pybo\views\base_views.py 파일에 다음과 같이 강제로 오류를 발생시켜보자.
index 함수가 호출되면 3을 0으로 나누려고 하기 때문에 ZeroDivisonError 가 발생한다. 깃을 이용해 서버에 적용하자. 설정한 후 서버에서 파이보 메인 페이지에 접속해보자. 'Server Error (500)' 오류가 발생한다. 이제 로그를 확인해보자.
어떤 오류가 발생했는지 로그파일에 출력된다. 앞으로는 tail -f mysite.log 로 로그를 확인하자. 이 명령을 하면 mysite.log 파일에 로그가 깧일 때마다 로그의 내용이 자동으로 출력된다.
지금까지 설정한 로깅은 장고가 사용하는 django 와 django.server 라는 로거로만 사용했다. 이번엔 새로운 로거를 생성해 파이보 프로그램에서 로그를 출력해보자.
먼저 projects\mysite\pybbo\views\base_views.py 를 수정하자.
적어 뒀었던 3/0 강제오류 코드를 지우고 사진과 같이 수정하자. 로그 파일에 로그를 출력하기 위해서는 logging 모듈이 필요하다. logger = logging.getLogger('로거명') 으로 얻은 logger 객체를 이용해 logger.debug, logger.error, logger.warning 등의 함수를 이용해ㅑ 로그를 출력할 수 있다. 이렇게 설정해도 'INFO 레벨로 출력' 이라는 문장은 로그로 출력되지 않는다. 그 이유는 위 코드에서 사용한 pybo 라는 로거는 LOGGING 설정에 등록되지 않은 상태이기 때문이다.
이를 등록하기 위해 projects\mysite\config\settings\base.py 를 다음과 같이 수정하자.
장고 환경셜정 파일에는 DEBUG 라는 항목이 있다. 이 항목은 기본값이 True 이지만 장고 공식 문서에는 '운영 환경에서 DEBUG는 반드시 False로 해야한다' 라고 되어있다.
장고는 실행 도중 오류가 발생하면 디버그가 True 인 경우 오류내용을 상세하기 출력한다. 이 때 settings.py 나 urls.py 같은 파일에 설정한 항목들도 노출된다. 정보 노출이나 해킹 등의 위험 때문에 False 로 해야한다.
projects\mysite\config\settings\prod.py 를 수정하자.
그리고 깃을 커밋해 서버에 적용하자. 하는 방법은 전 게시물을 확인하자.
그 후 http://고정ip/asdf 같이 존재하지 않는 페이지로 접속해 보자.
이전에는 오류의 원인같은 다양한 메시지가 적힌 페이지가 출력되었는데 이제는 아무런 정보도 표시되지 않는다.
정보를 표시하지 않기는 하지만 페이지가 단조롭기 때문에 꾸며보자. 꾸미기 위해 먼저
projects\mysite\config\urls.py 를 수정하자.
handler404 변수를 설정하면 404 오류 발생 시 사용자가 정의한 뷰 함수가 호출된다. 우리는 적어 넣은대로 common/views.py 파일의 page_not_found 함수가 호출될것이다. 이 handler404 변수는 반드시 config\urls.py 에 등록해야한다. common\urls.py 같은 곳에 등록하면 작동하지 않는다. 호출할 함수를 설정했으므로 이제 그 함수를 정의해보자.
projects\mysite\common\views.py 를 수정해주자.
함수가 받는 매개변수중 exception 매개변수는 오류의 내용을 담고있다. 오류의 내용을 화면에 보여주려면 exception 값을 읽어 화면에 출력할 수도있다. 함수에 common/404.html 을 리턴한다고 했으므로 그 파일을 만들어주자.
projects\mysite\templates\common\404.html 을 새로 만들고 다음과 같이 작성해주자.
그리고 깃을 이용해 서버에 적용하자. 서버에 적용한 후 구니콘을 restart 해주자. 이제 파이보를 확인해보자.