안녕하세요. MANVSCLOUD 김수현입니다.
2023-02-17(금) ~ 2023-02-23(목) 1주간 퇴근 후 남는 시간을 활용하여
네이버 클라우드 일간 보고서를 만들어보는 개인 프로젝트를 진행하기로 했습니다.
오늘은 네이버 클라우드 API를 이용하여 일간 보고서를 만든 후기에 대해 작성해보려고 합니다. 다수의 API를 사용하여 모든 소스를 공개할 수 없으므로 개발 소스는 공유되지 않는 점 참고 부탁드립니다.
Motive
무엇이든 시작함에 있어 동기가 있듯 이번 개인 프로젝트 역시 이유가 있었습니다.
- 개발 역량 부족
: 다른 기술들에 비해 개발 역량이 부족했고, 개발에 대한 경험이 없어 다양한 역량 확보에 있어 한계를 느낌. - 일간 보고서
: 네이버 클라우드 플랫폼을 이용하여 서비스 운영 중 원하는 메트릭에 대한 값을 모아 보고서 형태로 보고싶다는 생각이 듦.
(비용, 리소스 사용률, 이벤트, 콘솔 접속 여부 등 확인하는 페이지가 모두 다름)
How
- 언어
Python으로 선택했습니다.
쉽게 배울 수 있는 언어였고 웹, 인공지능, 자동화 등 엔지니어가 광범위하게 활용할 수 있는 언어라고 판단했기 때문입니다.
- 구조
구조는 단순하게 만들어졌습니다.
서버 1대를 생성했고 pyenv를 이용하여 독립된 공간에서 python 3.7을 사용할 수 있도록 하였으며 html을 pdf파일로 변경하기 전 python 웹 연동을 위해 flask를 설치했습니다.
디렉토리는 /root 디렉토리 외 다수의 User Home 디렉토리로 분리하였습니다.
그 이유는 각 역할을 완전히 분리하기 위함이었는데 크게 역할은 두 가지로 나뉩니다.
/root :
mailsender – 메일 전송 모듈
pdfmaker – html을 pdf로 변경해주는 모듈
. ├── mailsender │ └── manvscloud │ └── mailRequest.py ├── pdfmaker │ ├── pdfbox │ │ └── manvscloud │ │ ├── nrporter-manvscloud-2023-02-20.pdf │ │ ├── nrporter-manvscloud-2023-02-21.pdf │ │ └── nrporter-manvscloud-2023-02-22.pdf │ └── script │ ├── count │ └── urltopdf.sh └── userinit.sh
HTML을 PDF로 변경하는 부분은 파이썬의 pdfkit 모듈로 사용이 가능하지만 ShellScript로 컨트롤하는 게 개인적으로 더 편리하여 해당 부분은 Python을 활용하지 않았습니다.
Python을 활용한다면 wkhtmltopdf 설치가 필요하며 다음과 같은 예시로 사용할 수 있습니다.
import os
import pdfkit
os.environ['DISPLAY'] = ':0'
options = {'quiet': ''}
config = pdfkit.configuration(wkhtmltopdf='/usr/bin/wkhtmltopdf')
url = 'http://localhost:10000'
pdf_path = '../pdf/test.pdf'
pdfkit.from_url(url, pdf_path, options=options, configuration=config
userinit.sh은 초기 유저 생성 및 설정용으로 유저 생성 시 /etc/skel에서 가져온 데이터 중 변경해야하는 부분과 /root/mailsender, /root/pdfbox에 username의 디렉토리 및 모듈 추가 작업이 진행된다.
/USERHOME :
flask의 app.py – 웹 서버 구동
module – 리포트에 연결되는 각 기능들에 대한 모듈 모음 디렉토리
static – 대시보드 이미지가 저장되는 images 디렉토리 및 css 파일이 저장되는 static 디렉토리
templates – html 파일이 저장되는 디렉토리
위 구조만 보면 알 수 있듯 만들어진 해당 시스템은 하나의 계정에 대해서만 리포트를 생성해주기보다 새로운 계정이 추가될 때마다 userinit.sh 스크립트를 통해 user를 생성하고 User별 정보, Access Key에 따라 각각 다른 리포트 생성 및 User별 메일 전송이 가능하다는 점입니다.
- 리포트 서비스 하나 만들자고 서버를 하나 만들기엔 월 서버 비용이 걱정된다?
비용 절감만 목적이라면 돈을 벌 수 없습니다. 서비스로 수익을 내고 서비스에 맞게 비용을 최적화 하십시오. 비용을 줄이는 것이 아니라 돈을 벌어야합니다.
1. 이 서비스는 자원 사용량이 매우 낮습니다.
– 최저 사양으로 서버를 생성합니다.
2. 이 서비스는 00:00 시각에 맞춰 시작하여 몇분 내외로 작업을 마칩니다.
– Cloud Function을 이용하여 사용 시간에만 서버를 시작하고 작업이 끝나면 중지시킵니다.
(High CPU 2vCPU Mem 4GB HDD 기준으로 월 약 6.9만원의 비용인데 위와 같이 설정만해도 월 5천원 비용으로 최적화될 것입니다.)

- 네이버 클라우드 API 활용
이 부분이 오늘 포스팅의 핵심이기도 합니다.
네이버 클라우드는 사용자에게 다양한 API를 제공합니다.
API는 다음과 같은 예시처럼 사용되었습니다.
import sys
import os
import hashlib
import hmac
import base64
import requests
import time
import json
import datetime
def getActivityList():
active_data = []
timestamp = int(time.time() * 1000)
timestamp = str(timestamp)
access_key = os.environ['NCLOUD_ACCESS_KEY']
secret_key = os.environ['NCLOUD_SECRET_KEY']
secret_key = bytes(secret_key, 'UTF-8')
method = "POST"
api_server = "https://cloudactivitytracer.apigw.ntruss.com"
uri = "/api/v1/activities"
uri = uri + "?responseFormatType=json"
message = method + " " + uri + "\n" + timestamp + "\n" + access_key
message = bytes(message, 'UTF-8')
signingKey = base64.b64encode(hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())
http_header = {
'x-ncp-apigw-signature-v2': signingKey,
'x-ncp-apigw-timestamp': timestamp,
'x-ncp-iam-access-key': access_key,
}
ms = time.time_ns() // 1_000_000
start_time = ms - 86400000
start_time = str(start_time)
payload = {
"fromEventTime": start_time,
"pageSize": 100
}
response = requests.post(api_server + uri, headers=http_header, json=payload)
data = json.loads(response.text)
for item in data['items']:
if item['actionDisplayName'] == 'Login':
event_dt = datetime.datetime.fromtimestamp(item['eventTime']/1000)
event_date = event_dt.strftime("%Y년 %m월 %d일 %H시 %M분 %S초")
client_country = item['productData']['clientIpCountry']
client_ip = item['productData']['clientIp']
user_name = item['productData']['userName']
active_data.append({
"event_time": event_date,
"country": client_country,
"client": client_ip,
"username": user_name
})
return active_data
해당 일간 보고서를 생성 하는 서비스에 사용된 네이버 클라우드 API는 Platform – getDemandCostList , Cloud Outbound Mailer – createMailRequest , Cloud Outbound Mailer – createFile , Cloud Activity Tracer – GetActivityList , Cloud Insight – GetDashboardList , Cloud Insight – GetDashboardWidgetList , Cloud Insight – GetDashboardWidgetImage , Cloud Insight – QueryData , Cloud Insight – SearchEvent 등 약 20개에 가까운 API가 사용되었습니다.
- Cloud Insight Dashboard
생성된 일간 리포트에 들어갈 대시보드 이미지는 Cloud Insight의 Dashboard에서 먼저 생성되어야합니다. Dashboard에서 생성해둔 위젯들을 이미지 형태로 가져와 일간 보고서에 첨부되도록 하였습니다.

- Cloud Outbound Mailer
메일은 Cloud Outbound Mailer를 이용하여 메일이 발신되도록 설정하였습니다.
API를 이용하여 자동화 하기 전 도메인 등록 및 인증 작업이 완료되어있어야합니다.
“Cloud Outbound Mailer 생성 및 도메인 인증 등 사용법에 대한 내용은 해당 포스팅의 주제와 거리가 멀어 작성되지 않습니다. 가이드가 필요하신 경우 댓글로 남겨주시면 따로 포스팅 준비해보겠습니다.”

createMailRequest API를 이용하여 메일이 발송되면 콘솔에서 아래와 같이 [발송성공] 상태를 확인할 수 있습니다.
(파일 첨부 필요 시 createFile API도 함께 사용해줘야 합니다.)

Result
- 매일 00시에 Report 서버가 시작합니다. (Cloud Function 활용)
- 시작된 서버는 Cloud Insight에서 Widget 이미지를 가져오며 app.py가 실행됩니다.
- 실행 후 USER별 보고서 URL은 PDF 파일로 변환됩니다. (HTML to PDF)
→ USER는 포트별로 분리됨. (http://localbost:10000, http://localbost:10001 … ) - 생성된 PDF 파일은 USER별 지정된 수신 이메일로 발송됩니다.
- 작업 실패 시 재실행 또는 작업이 완료 시 서버는 종료됩니다.
아래는 완성된 ‘네이버 클라우드 일간 보고서’입니다.
다양한 API를 활용하여 필요한 데이터가 하나의 보고서에 모두 저장되었습니다.


API를 이용하여 원하는 데이터가 담긴 자신만의 일간 보고서를 만들어보시기 바랍니다.
Personal Comments
개발 소스 공유요?… 소스가 꽤 많기도하고 …
무엇보다 개발이라 하기엔 너무 쉬운?…
퇴근 후 1~2시간씩만 투자해도 1주일도 안돼서 만들어지는 코드라 고수분들은 당연히 만드실 수 있을 것이라 공유가 필요 없을 것이고 초보자 분들은 Python 경험으로 좋은 과제라 생각되므로 소스는 공유하지 않도록 하겠습니다.
긴 글 읽어주셔서 감사합니다.

