🔒

가디원 서브스테이션 내 로깅 시스템 적용기: 신속한 유지보수와 보안의 비밀

기록을 뜻하는 단어인 ‘로그(log)’는 알고 보면 여기저기 많이 숨어있습니다. 출근하자마자 사내 인트라넷에 ‘로그’인, 지금 포스트를 읽고 계신 이 곳도 블’로그’이고요. 논리를 뜻하는 Logic이라는 단어도 ‘로그’에서 유래한 단어라고 합니다. 기록이 쌓여야 논리를 뒷받침할 수 있기 때문일까요?
이렇게 우리 일상에서도 쉽게 찾아볼 수 있는 ‘로그’의 존재는 백엔드 업무에서 그 중요성이 더욱 커집니다. 운영 중인 소프트웨어 솔루션에 이슈가 발생했을 경우, 문제가 발생했을 당시의 기록을 확인할 수 있다면 문제의 원인을 파악하는 것이 훨씬 용이해지기 때문인데요. 그러므로 적절한 로그를 남기고 관리하는 로깅 시스템 (logging system)은 모든 소프트웨어 솔루션에 반드시 구축되어야 하는 요소라고 해도 과언이 아닙니다.
로깅 시스템은 에러를 대처하는 것 외에도 다양한 용도로 활용되고 있습니다. 로그 관리 시스템이 구축되어 있다면, 솔루션 발생 장애에 대한 판단 기준을 갖출 수 있을 뿐만 아니라, 인프라 내외부의 이상 징후를 모니터링해 시스템 보안도 철저히 관리할 수 있게 됩니다.
안타까운 예시이지만, 수년 전 국내 인터넷 쇼핑몰에서 1천만 건 이상의 고객 개인정보가 유출되는 사건이 있었는데요. 이 역시 로그 관리 시스템의 부재로 인해 발생한 사건이었다고 합니다.
그래서 이번 포스트에서는 저희 가디원 서브스테이션에는 어떤 로깅 시스템이 어떻게 구축되어 있는지, 그 당시의 구축 과정과 이를 통해 더욱 더 견고해진 가디원 서브스테이션의 모습에 대해 얘기하려고 합니다.

1. 가디원 서브스테이션이란?

본격적으로 이야기를 시작하기에 앞서, 이번 포스트의 주제어가 될 가디원 서브스테이션에 대해 먼저 알아볼까요?
가디원 서브스테이션은 국내 최초 산업AI 기반 변압기 예측진단 솔루션입니다. 이미 주기적으로 추출되고 있는 유중가스 분석(Dissolved Gas Analysis, DGA) 데이터를 수십만 건의 빅데이터 기반 AI 알고리즘으로 분석해 변압기의 결함을 높은 정확도로 진단, 예측하는 것이 특징입니다. 이를 통해 설비 관리자가 변압기의 상태를 더 확실히 진단하여 사고를 예방하고 대응할 수 있도록 지원하죠.
GS파워, E1 등 국내에서 내로라하는 기업들은 이미 가디원 서브스테이션을 도입해 그 효용성을 현장에서 실감하고 있으며, 최근에는 성능효율성, 사용성, 신뢰성 등 다양한 기준에서 우수한 평가를 받은 소프트웨어만 받을 수 있는 국가 인증 제도인 GS인증 1등급까지 획득한 바 있습니다.

2. 가디원 서브스테이션 내 로깅 시스템 구축 과정

고객을 위해서라면 당연히 해야할 일!
해당 제품의 백엔드는 SaaS 기반의 'Python' Flask 시스템이며, 심플한 MVC 구조의 API 서버로, 각 함수에 대한 Exception 처리 및 에러 코드와 메시지가 잘 정리되어 있어서 탄탄하고 짜임새 있게 구성된 시스템이었습니다.
다만, 로깅 과정을 보완해 에러 발생에 대한 원인 분석을 보다 체계적으로 하고자 아래 목표 하에 로깅 시스템을 새롭게 구축하게 되었습니다.
SQL (Structured Query Language) Transaction 로그를 기록한다.
모든 유저의 행동을 Tracking 한다.
서버에서 발생하는 로그를 기록한다.
에러 발생 알람을 메일, 메시지 형태로 알린다.
Splunk 외부 툴을 활용해서 로그를 필터링 및 시각화 한다.
1.
SQL Transaction 로그를 기록한다.
가디원 서브스테이션은 는 아니지만 공장 내에서 발생하는 데이터를 수집하고 관리 추적한다는 점에서 유사성을 가지고 있습니다. MES는 ERP와 비슷하게 하나의 거대한 DB에 여러 테이블과 복잡한 관계로 구성된 특징을 가지고 있기 때문에 시스템 대부분의 로직이 SQL에 녹아 있었고, SQL 로그만 제대로 확인해도 에러 대부분을 찾아낼 수 있었습니다.
*SQL이란? 관계형 데이터베이스에 대해서 데이터의 구조를 정의, 조작, 제어 등을 할 수 있는 절차형 언어
Clean Architecture Diagram 비즈니스 업무 규칙을 ‘엔티티’에 넣어야 한다는 clean architecture에 정면으로 맞서 DB SQL에서 처리하는 MES
가디원 서브스테이션은 Python에서 사용하는 'SQL Alchemy' ORM을 활용해서 DB Transaction 처리를 하게 되고 Python 'Logging' 라이브러리를 활용해 보기 좋은 포맷터를 지정 후 변환된 Raw SQL 로그와 서버 로그를, console 형태와 일자별 file 형태로 저장해 관리합니다. 가디원 서브스테이션은 MES와는 거리가 있지만, 이러한 형태의 로그 관리는 여전히 필요하다고 생각했습니다.
2.
모든 유저의 행동을 Tracking한다.
API 필수 요청 정보 뿐만 아니라 시스템, 도메인에 필요한 여러 부가적인 정보를 함께 저장하여 사용자에 대한 로그를 관리하고 있음에도, 파라미터 변조 등 언제 어떻게 예상치 못한 해킹을 당할 수도 있으니 로그 관리를 통해 예외적인 접근(exception)을 통한 원인을 추적할 수 있어야 합니다.
부디 저희 제품을 해커로부터 무사하게 하시옵소서 (이미지 출처: 유튜브 좋코딩 채널)
3.
서버에서 발생하는 로그를 기록한다.
이 부분은 4대 MES 중 '생산 실적 집계'에 해당하는 시스템의 특화된 부분이기도 합니다. 여러 시스템에서 받아온 데이터를 가지고 최종적으로 설비별, 웨이퍼별 생산실적 집계를 내기 위해 금융 분야에서 자주 사용하는, proc 파일을 Linux의 Crontab에 등록해 배치를 돌려서 가공합니다.
그러다 보면 심심치 않게 proc에서 에러가 발생해 데이터 집계의 오류가 발생하곤 하는데, 어느 시스템에서 받아올 파일에 데이터가 없거나, 새로운 공정의 추가로 데이터 포맷이 달라 에러가 발생하거나, 배치가 평상시보다 오래 걸려서, 이어서 진행할 배치가 돌지 못하는 등 여러 이슈로 인해서, 서버 내부적으로 발생하는 이벤트에 대한 로그를 남기고 있었습니다.
저는 위 두 가지 '모든 유저의 행동을 Tracking 한다', '서버에서 발생하는 로그를 기록한다'를 처리하기 위해서 시스템 내부 DB에 user_log 외 server_log 테이블을 만들어 관리하도록 구현했습니다.
user_log 예시 어떤 유저가, 어떤 API에, 무슨 파라미터로 언제 보냈는지에 대한 Input 기록
server_log 예시
server_log는 code에 따라서 큰 범주로 나누고, 해당 로그가 발생한 파일명, 함수명, 구체적인 로그(에러) 내용, 시간을 기록하여 user_log의 Input에 대한 Output을 기록하게끔 구현했습니다.
예시로 server_log의 9XX code 로 관리하는 보안로직은, user_log 테이블에서 '특정 유저'가, ‘특정 API'를 분당 'n번' 실행 시, 해당 유저를 Block 하고 server_log에 남기는 로직으로 구성되어 있습니다.
가디원 서브스테이션은 각 설비에 License를 발급받아 사용되는 구조로서, 사용자가 임의의 License를 계속해서 체크하는 API를 날리거나 엑셀 파일을 여러 번 업로드하는 등 악성 유저를 차단하는 로직을 가지고 있기 때문에 보안 측면에서 더욱 더 믿을 수 있는 솔루션입니다.
또한 Exception에 대한 로그를 남기는 과정은, 모든 함수에 대해 Exception 구문을 만들고, Exception 발생 시, 재귀적으로 각 함수에 대한 에러 로그가 server_log에 남을 수 있도록 구현했습니다.
server_log 테이브 exception 처리 프로세스
이렇게 구현을 한 이유는, Clean Code를 지향하는 개발자라면, 하나의 함수 안에 많은 양의 코드를 작성하지 않고 기능적 단위로 함수를 분할해서 함수를 구현하는데, 이렇게 되면 많은 Depth의 함수를 띄게 됩니다.
개인적으로 Exception이 발생했을 때 함수마다 Exception을 걸지 않으면, 최상단에서 실행한 function_A에서 보게 되는 Exception 에러 문구는 제한적이게 되며, 어느 함수명에서 어떤 Exception Argument로 발생했는지 알아채기 어려우므로, 각 함수마다 같은 작업을 걸어주었습니다.
4.
에러 발생 알람을 메일, 메시지 형태로 알린다
원프레딕트는 회사 메신저로 Microsoft의 Teams를 사용하고 있는데, 마침 Microsoft에서 제공하는 Teams bot 기능이 있어서, 해당 라이브러리를 활용해 에러가 발생할 때 알려주는 구조를 만들었습니다.
Teams 내 알람 메시지 예시
알람 메시지로는, 위에서 얘기한 유저의 요청 콜에 대한 Input과 Output을 조합해서 보이도록 해, 시나리오 재현과정을 바로 확인할 수 있게 구현했습니다.
5.
외부 툴을 활용해서 로그를 필터링 및 시각화한다.
방대한 양의 로그를 보다 효율적으로 모니터링하고 관리하기 위해서, 데이터 시각화 도구도 추가로 도입할 계획입니다. 다양한 툴이 있지만, 가디원 서브스테이션에서는 아래 3개 툴을 가장 적합한 툴을 선택해 SQL로그를 확인하거나 CPU, 메모리 상태 등을 측정하는 용도로 활용하려고 합니다.  
Kibana
Kibana는 Elasticsearch 클러스터에서 생성된 로그 데이터를 시각화하는 데 도움이 되는 데이터 시각화 도구입니다.
Kibana는 Elasticsearch 및 Logstash와 함께 ELK 스택을 구성합니다. 따라서 Kibana는 Elasticsearch와 긴밀하게 통합됩니다
Grafana
Grafana는 데이터 시각화에 적합한 오픈 소스 도구입니다. 주로 InfluxDB, Graphite 및 Elasticsearch에서 사용됩니다.
Grafana를 사용하면 사용자가 처음부터 자신만의 플러그인을 만들고 이를 사용하여 데이터 소스와의 통합을 수행할 수 있습니다. 강력한 경고 시스템이 있으며 사용자가 그래프에 주석을 달 수 있습니다.
Splunk
Splunk는 방대한 양의 머신 생성 데이터를 수집 및 관리하고 그 안에서 특정 정보를 검색하는 데 사용할 수 있는 BI 플랫폼입니다.
Splunk는 모든 유형의 데이터를 수집하고 검색 결과가 특정 조건을 충족할 때 알림을 받도록 경고를 구성하는 데 도움을 줄 수 있습니다. 데이터 내에서 빠른 검색을 위해 데이터를 인덱싱합니다.

3. 로깅 시스템 구축 후 이어진 고민들

끝날 때까지 끝난 게 아니다
이번에는 로깅 시스템 구축 후 리뷰 과정에서 이어졌던 몇 가지 고민들과 해결 방안에 대해서도 공유드려볼까 합니다.
개발에서는 되는데 운영에서는 안 되는 경우 커버 가능한가?
방대한 레거시 프로그램을 유지보수 해온 사람이라면, 상상하기 꺼림칙한 일이란 것을 공감할 것입니다.
이전 회사에서 근무할 당시, C#, WPF Desktop 프로그램을 운영하면서 개발 환경에서와는 달리 운영 환경에서 Client, Server 간 통신이 비정상적으로 종료되는 케이스가 있었습니다. 원인을 찾기까지 2달 가량을 투자했고 그 결과로는, Client 가 .exe 프로그램을 실행하기 전에, 해외 사업장에 접속하기 위한 원격 프로그램을 실행하게 되면 발생하는 현상이었고, 원격 프로그램의 알 수 없는 보안 로직이 Client와 Server 간 SOAP RPC 통신 방해로 나타나는 현상이 있었습니다.
이런 경험을 기반으로 가디원 서브스테이션에서도 코드 로직과 무관하게 발생할 수 있는 오류에 대한 대처 방안에 대한 고민으로 이어지다가, 문득 정말 이런 케이스가 발생할 확률이 높은지에 대한 의문으로 이어졌습니다.
"Docker 환경에서 실행되는 가디원 서브스테이션은, OS 버전부터 시작해, ARM, AMD 같은 아키텍처, 라이브러리를 모두 동일한 환경에서 실행되는 구조로 개발, 운영 서버를 각각 두어 운영되는 On-Premise 환경과 본질적으로 다르지 않나?"
"Desktop과 달리 Web에서는 외부 간섭이 없기 때문에 도메인이 다르거나, SSL 인증서가 없어서 발생하는 CORS 이슈가 대부분이지 않나? "
위 2가지 질문에 대한 고민으로 해당 케이스는 Docker 기반 환경에서는 커버가 가능하다고 생각했습니다.
저렇게 구축하면 정말 에러에 대한 원인 파악이 가능한가?
복잡한 로직으로 구성된 서버 오류를 확인하기 위해 개발자가 트레이스하는 주된 방식은 똑같이 재현하는 것으로 생각합니다. 이를 위해서는 시스템 운영상의 Input 과 에러 Output을 확실하게 아는 게 필요했고, 이러한 정보가 갖춰지게 된다면 당시의 시나리오를 재현할 수 있어 오류에 대한 원인을 파악하고 수정할 수 있습니다.
다만 Input과 Output을 확실히 알아도, 동일한 시나리오 결과를 낼 수 없는 예외 케이스가 있는데 바로 Database 나 Time과 같은 '외부 종속' 요인들이 함께할 상황에 해당합니다. TDD(Test-Driven-Development)에 진심이었던 팀원분과 테스트 코드를 작성하면서, 이러한 외부 종속요인 처리에 고민을 많이 했었고, 이러한 부분은, 가능한 모든 경우의 수를 고려해 심도 있게 테스트 코드를 작성하면, 시나리오 재현 과정에서 해당 영역으로 발생할 에러를 많이 걸러낼 수 있다고 판단했습니다
가디원 서브스테이션의 로깅 시스템은 이렇게 만약의 만약까지 고려하는 과정을 통해 구축되었습니다.
처음에 말씀드렸듯이, 가디원 서브스테이션은 변압기의 상태를 정확히 진단, 예측하여 설비 자체뿐만 아니라 산업 현장의 안전을 도모하고, 설비 관리자들의 업무가 보다 효율적으로 진행될 수 있게 지원하는 솔루션입니다.
로깅 시스템은 고객의 눈에 보이는 요소는 아닙니다. 하지만 가디원 서브스테이션 내의 로깅 시스템은 분명 고객을 위해 만들어진 장치입니다. 저희는 로깅 시스템을 통해 이슈 발생 시 빠르게 원인을 확인하여 설비 고장으로 인한 다운타임을 더욱 더 최소화하는 데 집중하고 있으며, 고객의 설비 및 현장 정보를  안전하게 관리하고 있습니다. 더 나아가, 고객이 알기 전에 가디원 TCX (Technical Customer Experience)팀에서 이상 징후를 선제적으로 포착해 이슈 관리를 지원하고 있기 때문에 보다 안전하고 기민하게 고객들의 설비 관리를 지원하고 있습니다.
가디원 서브스테이션으로 달라지는 산업 현장과 당신의 업무, 직접 경험해보세요.
데모 신청하러 가기
<가디원 서브스테이션 개발 이야기> 시리즈도 함께 읽어보세요. 당신의 의견에서 시작되는 우리의 제품 연대기
내 동료는 또 다른 고객

이 글을 쓴 사람

장 진 수 | guardione substation 팀
제조 분야 대기업에서 수많은 설비 데이터를 가공하고 운영해왔습니다.
CTO(Chief Technology Officer) 를 꿈꾸며 마주하는 이슈를 풀어가기 위해 아키텍처와 컨셉을 고민하고, 이런 노력이 제품에 반영될 수 있는 환경을 찾아 스타트업인 원프레딕트에 합류하게 되었습니다.

이 글을 정리한 사람

오 혜 원 | 마케팅팀
원프레딕트 마케팅팀에서 홍보와 대내외 커뮤니케이션을 담당하고 있습니다.
천상 문과생이지만 최첨단 초일류 AI 회사에 다니는만큼 어디 가서 창피 당하지 않을 정도의 이과적 소양을 쌓고자 노력하는 중입니다.
물욕이 강한 편이라, 하고 싶은 거, 입고 싶은 거, 먹고 싶은 거 다 사기 위해 오늘도(뚠뚠) 개미는(뚠뚠) 열심히(뚠뚠) 일하고 있습니다.
원프레딕트 홈페이지 https://onepredict.ai/
원프레딕트 블로그 https://blog.onepredict.ai/
원프레딕트 기술 블로그 https://tech.onepredict.ai