Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[NDC19] 좋은 로그란 무엇인가?: 좋은 로그를 위해 고려해야 할 것들

[NDC19] 좋은 로그란 무엇인가?: 좋은 로그를 위해 고려해야 할 것들

NDC19에서 발표하였습니다.

자막 포함 슬라이드 -> https://hyojun.me/~ndc19-caption

Hyojun Jeon

April 26, 2019
Tweet

More Decks by Hyojun Jeon

Other Decks in Programming

Transcript

  1. www.hyojun.me [email protected] devinjeon NDC18 〈야생의땅: 듀랑고〉의 데이터 엔지니어링 이야기 :

    로그 시스템 구축 경험 공유 넥슨 왓 스튜디오의 백엔드 엔지니어 주로 데이터와 DevOps 엔지니어링을 담당 전효준
  2. 들어가기에 앞서 •발표 내용을 기록하시느라 흐름을 놓치실 수 있기에, 발표

    자료는 아래 링크에서 자막과 함께 공개 예정입니다 :) https://hyojun.me/~ndc19
  3. 오늘 이야기 1. ‘좋은 로그’란 무엇인가? 2. ‘좋은 로그’를 위해

    고려해야 할 것들 3. 로그 품질 관리를 위해 해야 할 것들
  4. ‘로그(Log)’에 대한 정의 •이벤트(Event)에 대한 기록(Record) •이 발표에서는 ‘서비스 로그’를

    대상으로 합니다. • 서비스 수준에서 일어나는 상태변화나 유저의 행동에 대한 기록들 • 예) 유저의 입장 및 퇴장, 아이템 구매, 획득 및 사용 등
  5. ‘좋은 로그’에 대한 정의 1. 필요한 정보가 있다. 2. 의미가

    명확하다. 3. 편리하게 데이터를 얻을 수 있다.
  6. ‘좋은 로그’에 대한 정의 1. 필요한 정보가 있다. 2. 의미가

    명확하다. 3. 편리하게 데이터를 얻을 수 있다. 이것만 보면 참 간단한데...
  7. 겪어봤을 만한 문제들 • 필요한 정보가 없다. 예) 꼭 필요하면

    없더라, 왜 이 이벤트에는 있는데 저 이벤트에는 없지?
  8. 겪어봤을 만한 문제들 • 필요한 정보가 없다. 예) 꼭 필요하면

    없더라, 왜 이 이벤트에는 있는데 저 이벤트에는 없지? • 의미를 파악하기 어렵다. 예) 이 이벤트(또는 항목) 이름은 대체 무슨 의미지?
  9. 겪어봤을 만한 문제들 • 필요한 정보가 없다. 예) 꼭 필요하면

    없더라, 왜 이 이벤트에는 있는데 저 이벤트에는 없지? • 의미를 파악하기 어렵다. 예) 이 이벤트(또는 항목) 이름은 대체 무슨 의미지? • 편리하게 데이터를 얻을 수 없다. 예) 값에 여러 데이터가 함께 포함되어 있어서 매번 가공 처리를 해야하는 경우
  10. 왜 항상 비슷한 문제를 겪을까? • 로그에 대한 작업 우선순위가

    일반적으로 높지 않음 • 설계에 대한 충분한 고민 없이 일단 남기는데 집중
  11. 왜 항상 비슷한 문제를 겪을까? • 로그에 대한 작업 우선순위가

    일반적으로 높지 않음 • 설계에 대한 충분한 고민 없이 일단 남기는데 집중 • 무엇을 고려해야 할지 모름
  12. 왜 항상 비슷한 문제를 겪을까? • 로그에 대한 작업 우선순위가

    일반적으로 높지 않음 • 설계에 대한 충분한 고민 없이 일단 남기는데 집중 • 무엇을 고려해야 할지 모름 • 합의된 규약이 없음
  13. 왜 항상 비슷한 문제를 겪을까? • 로그에 대한 작업 우선순위가

    일반적으로 높지 않음 • 설계에 대한 충분한 고민 없이 일단 남기는데 집중 • 무엇을 고려해야 할지 모름 • 합의된 규약이 없음 • 로그 품질을 지속적으로 관리하지 않음
  14. 문제점을 충분히 인식했을 때쯤에는 ... • 필요한 데이터를 얻지 못하거나,

    큰 비용이 들게 됨 • 이미 지나간 시간의 정보를 찾는 것은 불가능하거나 힘듦 → 로그는 그때 그 상황을 기록하는 유일한 정보
  15. 문제점을 충분히 인식했을 때쯤에는 ... • 필요한 데이터를 얻지 못하거나,

    큰 비용이 들게 됨 • 이미 지나간 시간의 정보를 찾는 것은 불가능하거나 힘듦 → 로그는 그때 그 상황을 기록하는 유일한 정보 • 대부분 미래에 기존 설계 구조를 바꾸는 것은 많은 비용이 발생 → 기존에 적재된 모든 로그를 새로운 구조로 변환하는 것은 사실상 비현실적
  16. 이 발표를 준비한 이유 • 초기 ‘좋은 로그’의 필요성에 대한

    인식이 부족했던 것에 대한 아쉬움 • 대부분 공유된 자료는 여기까지의 이야기 • 구체적으로 무엇을 고민해야 하는지에 대한 내용을 찾기 어려웠음.
  17. 이 발표를 준비한 이유 • 초기 ‘좋은 로그’의 필요성에 대한

    인식이 부족했던 것에 대한 아쉬움 • 대부분 공유된 자료는 여기까지의 이야기 • 구체적으로 무엇을 고민해야 하는지에 대한 내용을 찾기 어려웠음. • 새로운 프로젝트를 시작할 때에는, 이런 내용을 복기하기 힘듦
  18. 이 발표를 준비한 이유 • 초기 ‘좋은 로그’의 필요성에 대한

    인식이 부족했던 것에 대한 아쉬움 • 대부분 공유된 자료는 여기까지의 이야기 • 구체적으로 무엇을 고민해야 하는지에 대한 내용을 찾기 어려웠음. • 새로운 프로젝트를 시작할 때에는, 이런 내용을 복기하기 힘듦 • 로그를 다루는 여러 동료들 모두가 공감대를 형성하며, 함께 고민해야 달성할 수 있는 가치 • 공유가 필요하다!
  19. Chapter 2. ‘좋은 로그’를 위해 고려해야 할 것들 1. 필요한

    정보가 있는 로그 2. 의미가 명확한 로그 3. 편리하게 데이터를 얻을 수 있는 로그 4. 그 외 다른 관점에서 고려해봐야 할 것들
  20. 앞으로 나올 단어들 •로그 - 이벤트에 대한 기록 •항목 -

    로그에 포함될 각각의 데이터 time player_id player_class player_level … … … … … … … … … … … PlayerGotItem
  21. 목표가 있는 로그 1. 목표를 한 문장으로 정의 예) 재방문율

    집계가 필요하다. 2. 하나의 지표에 대해서 다양한 각도의 고민 예) 추후 재방문율 집계시 ‘국가별’, ‘레벨별’, ‘직업별’ 필터링이 필요할 것이다.
  22. 목표가 있는 로그 1. 목표를 한 문장으로 정의 예) 재방문율

    집계가 필요하다. 2. 하나의 지표에 대해서 다양한 각도의 고민 예) 추후 재방문율 집계시 ‘국가별’, ‘레벨별’, ‘직업별’ 필터링이 필요할 것이다. 3. 목표에 따라 남겨야 할 이벤트와 그 항목들을 정의 • 목표들의 우선순위에 따라, 점진적으로 항목을 추가하는 방향도 고려
  23. 일관성 • 일관성이란? • 같은 구성요소에 대하여 같은 항목들을 가지는

    것 • 구성요소의 예) → ‘플레이어의 아이템 획득’ 이벤트의 경우, 플레이어와 아이템이라는 구성요소를 가진다.
  24. 일관성 • 일관성이 없는 경우의 예) time player_id player_class player_level

    … … … … … … … … … … … PlayerGotItem PlayerUsedItem time player_id player_class … … … … … … … … … • 두 이벤트 모두 플레이어에 대한 로그 • 하지만 플레이어에 대한 항목 구성이 다름
  25. 믿을 수 있는 로그 1. 로그가 의도한 시점에서 발생했을 것이라는

    믿음 2. 의도한 대로 데이터가 남았을 것이라는 믿음 • 의도한 것과 다른 데이터가 남을 수 있는 가능성 • 어뷰징에 의한 변조 가능성
  26. 믿을 수 있는 로그 1. 로그가 의도한 시점에서 발생했을 것이라는

    믿음 2. 의도한 대로 데이터가 남았을 것이라는 믿음 • 의도한 것과 다른 데이터가 남을 수 있는 가능성 • 어뷰징에 의한 변조 가능성 3. 100%는 아니더라도 납득할 수 있는 수준의 믿음을 위한 노력이 필요
  27. 여기까지 정리 •필요한 정보가 있는 로그를 위해 고려할 것들 •

    목표가 있는 로그 • 일관성 있는 로그 • 믿을 수 있는 로그
  28. 이름에 대한 합의와 규약 • 의미를 충분히 표현할 수 있어야

    함 • 나중에 이벤트 또는 항목의 이름을 바꾸는 것은 큰 비용이 발생할 수 있음
  29. 이름에 대한 합의와 규약 • 의미를 충분히 표현할 수 있어야

    함 • 나중에 이벤트 또는 항목의 이름을 바꾸는 것은 큰 비용이 발생할 수 있음 • 때문에, 길더라도 구체적인 이름을 사용 • 다른 의미와 혼동될만한 가능성을 피할 수 있다. • 미래에 들어가는 이름과 의미가 충돌할 가능성을 낮출 수 있다.
  30. 이름에 대한 합의와 규약 • 의미를 충분히 표현할 수 있어야

    함 • 나중에 이벤트 또는 항목의 이름을 바꾸는 것은 큰 비용이 발생할 수 있음 • 때문에, 길더라도 구체적인 이름을 사용 • 다른 의미와 혼동될만한 가능성을 피할 수 있다. • 미래에 들어가는 이름과 의미가 충돌할 가능성을 낮출 수 있다. • 이름을 정의하기 위한 최소 규약(Naming convention) 정의
  31. 이름에 대한 합의와 규약 • 이벤트 이름 1. 파스칼 표기법(단어의

    첫문자를 대문자로 시작하는 표기법)을 따른다. 2. 이벤트의 구성요소들과 상태 변화 또는 행동에 대한 내용을 모두 포함한다. 예) 플레이어의 아이템 획득 → PlayerGotItem 구성요소 - Player, Item 행동 – Get(Got) • 항목 이름 1. 스네이크 표기법(단어를 밑줄로 구분하는 방법)을 따른다. 예) player_level ... (중략) 예제
  32. 이벤트를 구별하는 기준 • ‘〈상태〉의 시작’, ‘〈상태〉의 종료’ • 상태의

    시작과 종료를 이벤트로 분류하는 구조 • 의미적으로 명확하게 구분이 가능하지만, 이벤트 종류가 많아질 수 있음. • 시작과 완료 시 항목 구성의 차이가 큰 경우에 적합 PlayerStartedQuest PlayerCompletedQuest 예) time quest_id player_id a b c … … … … … … time quest_id player_id d e f … … … … … …
  33. 이벤트를 구별하는 기준 • ‘〈상태〉의 시작’, ‘〈상태〉의 종료’ • 상태의

    시작과 종료를 이벤트로 분류하는 구조 • 의미적으로 명확하게 구분이 가능하지만, 이벤트 종류가 많아질 수 있음. • 시작과 완료 시 항목 구성의 차이가 큰 경우에 적합 PlayerStartedQuest PlayerCompletedQuest 예) time quest_id player_id a b c … … … … … … time quest_id player_id d e f … … … … … …
  34. 이벤트를 구별하는 기준 • ‘〈상태〉 업데이트’ • 로그 항목에서 상태변화의

    종류를 알 수 있는 구조 • 아래의 경우에 좀 더 편리하게 분석할 수 있음 1. 같은 구성요소에 대해 상태만 변한다. 2. 항목 구성이 거의 비슷하다. 3. 이력의 변화가 중요하다. time quest_id player_id action … … … start … … … complete PlayerUpdatedQuest 예)
  35. 이벤트를 구별하는 기준 • 한 이벤트가 억지로 여러 가지 이벤트를

    포괄하지 않도록 함 • 특정 이벤트에 대한 내용이 변경될 수 있음 • 이벤트와 항목의 이름이 여러 가지 의미를 가지게 되어 불명확해질 수 있음 • 데이터 타입이나 표현 방법을 통일하게 되면서, 데이터를 상세하게 남기지 못할 수 있음
  36. 표현력 • 약간의 데이터 용량 절감을 위해 축약된 표현을 사용하지

    않는다. • 저장 비용은 크지 않고, 경우에 따라 압축이 가능하다. • 득보다 실이 많을 수 있다. • 경우에 따라 데이터 타입에 대한 고려 또한 필요 예) 소수점 표현, 숫자 범위
  37. 빈 값의 의미를 명확하게 • 빈 값은 다양하게 해석될 수

    있음 • 해당 항목에 대한 정보가 아예 존재하지 않는 경우 • 실제 값이 빈 값이 경우 • 명확하게 하는 것에 의의
  38. 여기까지 정리 •의미가 명확한 로그를 위해 고려할 것들 • 이름에

    대한 합의와 규약 • 이벤트를 구별하는 기준 • 표현력 • 빈 값의 의미를 명확하게
  39. 로그 형식 • 서비스 로그는 특정 항목에 대한 접근이 필요한

    경우가 많음 • 필요한 요소 • 컴퓨터가 읽기 쉽도록 구조화된 형식 • 사람이 읽을 수 있는 형식 • 일반적으로 많이 쓰이는 형식 • JSON, key/value { "type":"PlayerGotItem", "player_id":"jeonhyojun", "time":"2019-04-26T……", "item_id":"1a2b3c4d5e6f", ... } JSON
  40. 메타데이터 사용에 대한 충분한 고민 • 메타데이터란? • 서비스를 구성하는

    정보에 대하여, 식별자와 그 상세정보가 매핑된 데이터
  41. 메타데이터 사용에 대한 충분한 고민 • 메타데이터란? • 서비스를 구성하는

    정보에 대하여, 식별자와 그 상세정보가 매핑된 데이터 퀘스트 아이디(식별자) 최소 요구 레벨 … tutorial_1 … … tutorial_2 … … … … … 퀘스트 메타데이터 { "type":"PlayerUpdatedQuest", "player_id":"jeonhyojun", "quest_id":"tutorial_1", "time":"2019-04-24T……", ... } 예) 로그
  42. 메타데이터 사용에 대한 충분한 고민 • 메타데이터란? • 서비스를 구성하는

    정보에 대하여, 식별자와 그 상세정보가 매핑된 데이터 퀘스트 아이디(식별자) 최소 요구 레벨 … tutorial_1 … … tutorial_2 … … … … … 퀘스트 메타데이터 { "type":"PlayerUpdatedQuest", "player_id":"jeonhyojun", "quest_id":"tutorial_1", "time":"2019-04-24T……", ... } 예) 로그
  43. 메타데이터 사용에 대한 충분한 고민 • 메타데이터의 남용은 관리 이슈와

    생산성 저하를 유발 • 메타데이터가 많아지면 관리하기 힘들어짐 • 집계 시마다 로그 외의 다른 데이터를 참조해야 함 • 때문에 본래 목표를 위한 기본적인 데이터는 로그 항목에 포함하는 것이 좋다.
  44. 메타데이터 사용에 대한 충분한 고민 • 메타데이터 사용의 적절한 예

    • 정적 데이터가 과도하게 많고, 정의했던 로그의 목표에 필요하지 않은 경우 → 목표에 꼭 필요한 데이터라면 로그의 항목으로 구성하는 게 좋다. • 변경 주체가 서비스 제공자에게 있는 경우에 한하여 사용 • 메타데이터가 불가피하게 많아질 경우 → 시스템에서 메타데이터를 효율적으로 관리하고 사용할 수 있는 도구가 필요
  45. 문맥 식별자와 고유 식별자 • 문맥 식별자(Context identifier) • 하나의

    행동으로 일어난 여러 개의 로그는 같은 문맥 식별자를 갖게 함 • 인과관계나 선후관계를 파악하는 데 도움을 준다.
  46. { "type":"PlayerExpUp", "context_id": "1a2b3c4d5e", ... } 문맥 식별자와 고유 식별자

    • 문맥 식별자(Context identifier) → 문맥 식별자로 검색 “이 플레이어가 경험치를 어떤 경로로 획득했을까?”
  47. { "type": "PlayerUpdatedQuest", "context_id": "1a2b3c4d5e", "action": "complete", ... } {

    "type":"PlayerExpUp", "context_id": "1a2b3c4d5e", ... } 문맥 식별자와 고유 식별자 • 문맥 식별자(Context identifier) “이 플레이어가 경험치를 어떤 경로로 획득했을까?” “퀘스트 완료를 통해 획득했구나!” → 문맥 식별자로 검색 → 인과관계 확인가능
  48. 문맥 식별자와 고유 식별자 • 고유 식별자(Unique identifier) • 중복

    로그를 쉽게 식별할 수 있음 • 특정한 로그 하나를 기준으로 잡기 편리함
  49. 여기까지 정리 •편리하게 데이터를 얻기 위해 고려할 것들 • 로그

    형식 • 메타데이터 사용에 대한 충분한 고민 • 문맥 식별자와 고유 식별자
  50. 서비스에 줄 수 있는 영향 • 배보다 배꼽이 큰 경우가

    있을 수 있음 • 기술적인 한계를 해결하거나, 또는 적절한 타협점을 찾아야 함 • 예) 로그에 필요한 값을 채우는 것이 서버에 과도한 부하를 일으킬 수 있는 경우 → 서버에서 캐싱 하거나 또는 메타데이터를 활용하거나 • 예) 모든 유저에 대하여 n초마다 발생하는 로그 → 샘플링하거나, 변경 시에만 남기거나
  51. 할 수 있는 것부터 • 남기지 않고 있었거나, 잘못 남겨진

    데이터는 깔끔히 포기한다. • 현 상황에서 최선의 방향을 찾는다. • 앞으로의 개선 방향을 논의한다.
  52. 정리 좋은 로그를 위해 고려해야 할 것들 7. 빈 값의

    의미를 명확하게 8. 로그 형식 9. 메타데이터 사용에 대한 충분한 고민 10. 문맥 식별자와 고유 식별자 11. 서비스에 줄 수 있는 영향 12. 할 수 있는 것부터 1. 목표가 있는 로그 2. 일관성 3. 믿을 수 있는 로그 4. 이름에 대한 합의와 규약 5. 이벤트를 구별하는 기준 6. 표현력
  53. 품질 관리가 필요한 이유 • 이벤트와 항목들은 서비스가 성장할수록 점점

    많아진다. • 계속해서 변경과 특이사항들이 발생할 것이다. • 점점 더 많은 사람들이 데이터로부터 의사결정을 하게 될 것이다.
  54. 서비스 구성요소별 로그 관리 • 특정 구성요소에 대한 로그를 쉽게

    파악할 수 있음 • 로그에 존재하는 항목의 일관성을 유지하는 데 도움 예) 플레이어의 아이템 획득 이벤트의 경우 플레이어와 아이템이라는 구성요소를 가진다. 플레이어의 공통 항목 - 아이디, 레벨, 최근 접속 시간 … 등 아이템의 공통 항목 - 종류, 아이템 레벨, 최대 내구도 … 등
  55. 로그의 문서화 • 다음 내용에 대한 기록이 필요하다. • 로그의

    목표와 의미 • 로그의 정확한 발생 시점 • 각 항목들의 의미와 데이터 타입 • 항목의 추가/변경/삭제 이력 • 특이사항 기록(발생 일시, 내용) • 로그가 사용되는 곳 • 로그의 구조나 의미가 변경될 때 다른 지표에 대한 영향을 미리 파악할 수 있음 • 예) 어떤 대시보드에서 어떤 용도로 사용되고 있음
  56. 로그 유실 모니터링 • 믿을 수 있는 로그 • 로그

    유실에 대한 빠른 대응 • 특이사항 기록 • 버그 또는 시스템 이슈로 인해 유실된 경우 • 언제, 얼마나, 어떤 데이터가 유실되었는지 기록
  57. 로그 추가 및 변경의 프로세스화 1. 목표 정의 2. 관계자들의

    의견을 종합하여 로그를 설계 3. 로그 추가 또는 변경 작업 4. 테스트 / QA 5. 배포
  58. 로그 추가 및 변경의 프로세스화 1. 목표 정의 2. 관계자들의

    의견을 종합하여 로그를 설계 3. 로그 추가 또는 변경 작업 4. 테스트 / QA 5. 배포 1. 목표 정의 • 추가(또는 변경)의 목표를 구체적으로 정의 • 어떤 데이터가 필요한 것인지 정의
  59. 로그 추가 및 변경의 프로세스화 1. 목표 정의 2. 관계자들의

    의견을 종합하여 로그를 설계 3. 로그 추가 또는 변경 작업 4. 테스트 / QA 5. 배포 2. 관계자들과 의견을 종합하여 로그를 설계 • 관계자? • 지표를 보는 사람들 / 만드는 사람들(분석가) • 개발자(실제 로그에 대한 코드를 작성) • 이벤트 정의 • 지표를 어떻게 볼 것인지 다양한 각도로 고민 • 필요한 항목들을 더 구체적으로 정의 • 추가 가능 여부, 한계, 대안 • 우선순위 • 가까운 미래에 발생할 수 있는 다른 가능성 고민 • 합의된 내용을 기반으로 문서화
  60. 로그 추가 및 변경의 프로세스화 1. 목표 정의 2. 관계자들의

    의견을 종합하여 로그를 설계 3. 로그 추가 또는 변경 작업 4. 테스트 / QA 5. 배포 3. 로그 추가 또는 변경 작업 4. 테스트 / QA • 의도한 시점에 제대로 발생하는지 확인 • 의도한 형태로 남는지 확인 • 값이 정확한지 확인 5. 배포
  61. 효율적인 프로세스 진행을 위해 • 로그 설계 방식에 대하여 미리

    합의된 최소한의 규약이 필요 • 자칫하면 비효율적으로 작동할 수 있는 프로세스 • 처음부터 모든 것을 충족할 수 없으므로, 점진적 개선이 필요 • 잘못 남겨진 로그는 이후 생산성을 크게 저하시키기 때문에 충분한 테스트와 QA 과정이 필요
  62. 요약 •품질관리를 위해 필요한 것들 • 서비스 구성요소별 로그 관리

    • 로그의 문서화 • 로그 유실 모니터링 • 로그 추가 및 변경의 프로세스화
  63. 마치며 • 가장 중요한 것은 ‘좋은 로그’에 대한 공감대를 형성하는

    것 • 가장 어렵지만 필요한 것은, 서로 다른 입장에 대하여 열린 마음을 가지는 것 • 모든 것을 만족시킬 순 없지만, 할 수 있는 것부터 하는 것이 중요