최근 진행되고 있는 프로젝트에서 AWS S3 와 CloudFront를 사용하여 동영상 서비스를 하고 있는데 CBT중이라 버그 리포팅이 자주 오고 있다.

분명히 테스트때는 정상 작동을 했는데 왜 항상 실제 사용하면 버그가 튀어나올까...?!


Video Thumbnail 파일을 새로 업로드 하였는데 이미지가 바뀌지 않는다는 내용의 문제가 접수되었다. 

Thumbnail 수정 로직은 기존에 사용하던 파일 이름에 확장자만 새로 올린 사진 파일을 따르게 되어있었다. 해서, 사진이 업로드된 S3에는 새로 올려진 파일이 존재하는데, CloudFront에 요청을 하면 캐시되어있는 예전 사진이 보여지는것이었다. 



파일이 새로 올라왔는데 CloudFront는 왜 새로운 파일을 캐시하지 못했을까?


문제 해결을 위해 문서를 찾아보니 다음과 같은 내용을 확인하였다.

CloudFront 배포에서 기존 객체를 업데이트하고 동일한 객체 이름을 사용할 수는 있지만 권장되지는 않습니다. CloudFront에서는 오리진에 새 객체나 업데이트된 객체를 배치할 때가 아닌 객체가 요청된 경우에만 엣지 로케이션에 객체를 배포합니다. 이름이 같은 최신 버전으로 오리진에서 기존 객체를 업데이트한 경우, 다음 두 가지 상황이 모두 발생하기 전까지는 엣지 로케이션에서 오리진으로부터 새 버전을 가져오지 않습니다.

문제에 대한 이유를 찾았으니, 문제 해결을 해보도록 했다.


CloudFront 엣지 캐시에서 객체가 만료되기 전에 이것을 제거하는것, 즉 CloudFront의 객체 무효화를 사용하면 된다. 


1. AWS Console에 접속하여 CloudFront 페이지로 이동한다.


2. 문제가 발생한 Distribution을 선택한다.


3. Invalidations탭을 선택한다.


4. Create Invalidation을 선택한다.



5. Object Paths에 Invalidate할 파일 이름을 적어준다.


이때 Origin Path를 제외하고 난 나머지를 적어주면 된다.

예를 들어, 

Invalidate할 파일이 S3 bucket에 /thumbnail/1234.jpg이고,

CloudFront의 Origin Path가 /thumbnail로 잡혀있다면, 

Create Invalidation의 Object Path에 1234.jpg를 적어주면 된다.



6. Invalidate버튼을 누르고 Status가 Completed가 되길 기다리면 된다. (생각보다 오래 걸린다...)


참고로 Invalidation은 무료 갯수가 제한되어있어서 그 이상 Invalidate을 하게 되면 과금되니 주의해야 한다.


과금 정보는 다음 페이지에서 확인 가능하다.

http://aws.amazon.com/cloudfront/pricing/






참고자료


http://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/ReplacingObjectsSameName.html





Posted by 알 수 없는 사용자
,

Firebase: Robo Test

Test Lab 2016. 6. 15. 18:16



Firebase: Robo Test


Firebase는 앱 개발을 위한 실시간 데이터베이스, 사용자 인증 및 호스팅 기능을 제공하는 서비스에서

Google에서 인수한 후 앱(Android, iOS, 모바일 웹)을 위한 통합 앱 플랫폼으로 확장되었다.


Firebase에서는 앱 개발을 위한 기능 뿐만 아니라 분석, 관리, 마케팅등을 위한 기능들이 다수가 포함되어 있다.

- Firebase Overview Google I/O 2016[1]

- Firebase Features[2]


본 포트스에서는 Firebase의 앱 자동화 테스트 기능인 "Robo Test"에 대해서 살펴보려고 한다. 

- Google Cloud Test Lab for Robo Test[3]

- Firebase Test Lab for Android Robo Test[4]


테스트를 위한 대상 앱을 회사에서 개발한 "On-ly 앱"을 테스트 해보기로 결정하였다.

On-ly는 "스마트 게임 만보계"

1) On-ly를 설치한다.

2) 평소대로 스마트폰(게임)을 사용한다.

3) 내가 스마트폰으로 게임을 얼마나 어떤 패턴으로 하는지 궁굼하면 On-ly에서 살펴본다.

와 같은 간단한 컨셉을 바탕으로 개발되었다.

- On-ly 앱[5] 



1. On-ly 테스트 Coverage

테스트를 진행해 보기에 앞서, Robo Test가 "어디까지 테스트를 해줄 수 있을까? 또는 이런것도 테스트가 가능할까?"에 대해서 생각을 해보았다.


1) 게임 플레이 시간 수집

앞서 설명한 바와 같이, On-ly는 사용자의 게임 플레이 시간을 수집하여 정보를 제공하는 앱이다. 게임 플레이 시간 수집을 테스트하기 위해서는, "a) 게임이 설치되어 있어야하고, b) On-ly가 설치되어 있어야 한다. c) 게임을 일정시간(5분이상) 실행한 후, d) On-ly를 실행해야 한다."와 같이 타 앱과의 연계가 필요하다.


2) Facebook 연동(로그인 기능)

부가 기능(친구 데이터 공유, 데이터 persistency등)을 위해 Facebook 연동을 제공하고 있다. 만약, Robo Test에서 로그인이 가능하다면 서버에 저장된 데이터를 사용하여, UI 테스트가 가능하다.


3) 전체 페이지(State) 테스트

사용자가 접할 수 있는 On-ly의 총 페이지(State)는 43개이다. 43개는 동일한 기능(상세 팝압)은 1개의 페이지로 고려하였을때 확인된 수치이다. 실제로는 더많은 페이지를 접하게 된다. 이번 테스트에서는 전체 중 몇%의 페이지를 Robo Test가 테스트 할 수 있는지를 확인하려고 한다.

(* 페이지별 세부 테스트 또는 페이지의 연계성을 고려한 테스트는 고려하지 않음)

<On-ly 페이지별 스크린샷>


4) 시스템 권한

On-ly는 게임 모니터링을 위해, "android.permission.PACKAGE_USAGE_STATS" 시스템 권한이 필요하다.(*Android 5.1, Lollipop 부터 시스템 권한으로 변경됨)

시스템 권한은 앱을 설치후 사용자가 직접 안드로어드 OS 설정 페이지에서 권한을 추가해야 한다. 즉, 테스트시 안드로이드 OS와의 연계가 필요하다.

<PACKAGE_USAGE_STATS 시스템 권한 획득과정>


당연히 내부에서 테스트를 진행할 시 위 4가지만을 고려하는 것은 아니다. 더 많은 항목을 테스트 해야 한다. 단, 본 테스트에서는 Robo Test로 큰 틀에서 어느 범위까지 테스트가 가능한지를 확인하기 위해 위 4가지 항목으로 정해보았다.


2. Robo Test 실행

Test Lab을 사용하기 위해서는 Firebase가입 및 카드 등록이 필요하다. 시간당 $5로, 테스트 장비 대여 및 관리 비용이라고 생각하면 비싼 가격은 아니라고 생각된다.

<Firebase Pricing[6]>




2.1. 프로젝트 만들기

프로젝트는 Firebase console에서 "새 프로젝트 만들기"로 생성할 수 있다. 해당 프로젝트로 이동하면, 좌측 DEVELOP -> Test Lab을 확인할 수 있다.

<새 프로젝트 만들기>


2.2. 테스트 실행

메뉴의 DEVELOP -> Test Lab을 선택하고, "테스트 실행 -> Robo 테스트 실행"을 선택한다.

<Robo Test 실행>


테스트할 앱(On-ly)의 APK를 업로드한 후 "계속"을 선택한다.

<앱 선택(APK 업로드)>



테스트 실행 단계에서 가장 복잡한단계로, [실제기기, API수준, 방향, 언어, 고급 옵션1, 고급 옵션2]6개의 측정기준을 선택하는 단계이다.  "테스트의 개수 = 실제기기 수 x API수준 수 x 방향 수 x 언어 수"로 결정된다. 본 예제는 1x3x1x1=3으로 3개의 테스트를 진행한다.


고급 옵션은

1) 테스트 제한시간: 테스트를 실행할 최대 시간(분)으로, 기본은 5분으로 설정되어 있다.

2) 최대 깊이: Robo 테스트에서 앱 UI의 특정 분기를 얼마나 깊이 탐색한 후 UI 루트(기본 화면)로 돌아가서 다른 분기를 탐색할지를 결정합니다.

으로 기본값으로 테스트 하였다.

<측정기준 선택>



테스트가 모두 완료되면 아래와 같은 결과를 확인할 수 있다. 모두 통과 하였다. 이제 상세 결과를 확인해 보자.

<테스트 매트릭스>



3. Robo Test 결과 확인

3.1. 테스트 결과 항목

테스트 결과는 

a)로그: Device에서 발생한 level별 로그

b)스크린샷: 테스트를 진행한 페이지의 스크린샷 목록

c)활동 지도: 테스트를 진행한 과정의 activity diagram[7]형태의 diagram

d)동영상: 테스트를 진행한 과정이 녹화된 동영상

으로 구성되어 있다.


<테스트 결과 화면>


3.2. 결과 확인

"1. On-ly 테스트 Coverage"에서 생각해 보았던 내용을 충족시킬 수 있는지를 확인해 보자.

1) 게임 플레이 시간 수집 (테스트 할 수 없음)

"2.2. 테스트 실행"에서 확인한 바와 같이, 테스트 대상 앱 이외의 앱은 설치가 불가능 하다.


2) Facebook 연동 (실패 테스트만 가능)

테스트 Input에 사용자 데이터가 없다. 즉, 로그인 Action을 수행(테스트)할 수 는 있지만 로그인 성공에 대한 테스트는 불가능 하다.  아래 "활동 지도"에서 "Facebook 로그인" 페이지에서 실패를 반복하고 있다. 또한, 이로인해  테스트 시간을 모두 소비하여 다른 페이지는 테스트를 진행하지 못한것으로 판단된다.

<활동 지도 결과>


3) 전체 페이지(State) 테스트 (약 79%는 테스트 하지 못함)

Facebook 로그인을 실패한 페이지의 중복을 제거하면, 9개의 페이지를 테스트 하였다. On-ly의 전체 페이지(49) 중 약 21%의 페이지만을 테스트한 것이다. 


또한, 로그인 실패(수집된 데이터가 없는경우)한 경우만 확인을 하면 전체 17페이지 중 약 53%의 페이지만을 테스트 하였다.

<스크린샷 결과>


4) 시스템 권한 (테스트 하지 못함)

API 22(Lollipop)에서 새로 추가된 PACKAGE_USAGE_STATS를 위한 시스템 권한 획득에서 더이상 진행되지 않았다.  

<API 22 테스트의 활동 지도 결과>




4. 마치며

어찌보면 당연한 결과일지 모른다. 또는, Firebase에서 Robo Test의 사용목적과 부합하지 않는 테스트만 진행한 것 일 수도 있다. 그러나, 만약, 모두 자동으로 잘 테스트 되어 진다면 얼마나 좋을까?라는 생각을 해보았다.(누군가는 허황된 꿈? 이라고 할 수 있을 것이다)

최근 자동화 앱 테스트(Automated App Test) 또는 자동화 테스트 입력 생성(Automated Test Input Generation)에 대한 연구 자료들을 보기 시작했다. 자료들에서도 Robo Test와 동일한 컨셉으로 연구를 진행하고 있다[9-12].
a)Android Activity분석 -> b)분석 결과를 model(Finite State Machine[8])화 -> c)Model의 최적화(learning algorithm, heuristics 등을 이용) -> d) 테스트 입력 생성(Test Input Generation)
연구 자료를 보면서 전체는 아니더라도 지금보다는 더 나은 방향으로 갈 수 있지 않을까 생각해 보았다.

*본 글은 절대로 Firebase의 Robo Test를 비판 또는 평가하기 위한 목적으로 작성되지 않았습니다.


References

[1] Firebase Overview Google I/O 2016, https://www.youtube.com/watch?v=tb2GZ3Bh4p8

[2] Firebase Features[2], https://firebase.google.com/features/ 

[3] Google Cloud Test Lab for Robo Test, https://developers.google.com/cloud-test-lab/robo-ux-test

[4] Firebase Test Lab for Android Robo Test, https://firebase.google.com/docs/test-lab/robo-ux-test

[5] On-ly 앱, https://play.google.com/store/apps/details?id=com.embian.only

[6] Firebase Pricing, https://firebase.google.com/pricing/

[7] Activity Diagram Wiki, https://en.wikipedia.org/wiki/Activity_diagram

[8] Finite State Machine Wiki, https://en.wikipedia.org/wiki/Finite-state_machine

[9] Guided GUI Testing of Android Apps with Minimal Restart and Approximate Learning, http://www.cs.berkeley.edu/~necula/Papers/swifthand-oopsla13.pdf

[10] MobiGUITAR – A Tool for Automated Model-Based Testing of Mobile Apps, https://scholar.google.co.kr/scholar?q=A+Tool+for+Automated+Model-Based+Testing+of+Mobile+Apps&btnG=&hl=ko&as_sdt=0%2C5&as_vis=1

[11] Reducing Combinatorics in GUI Testing of Android Applications, https://seal.ics.uci.edu//wp-content/uploads/seal/PID4096715.pdf

[12] A GUI State Comparison Technique for Effective Model-based Android GUI Testing,https://scholar.google.co.kr/scholar?q=A+GUI+State+Comparison+Technique+for+Effective+Model-based+Android+GUI+Testing&hl=ko&as_sdt=0&as_vis=1&oi=scholart&sa=X&ved=0ahUKEwj6gMbo16nNAhXj3aYKHW5TA1sQgQMIGjAA



Posted by 알 수 없는 사용자
,

요새 AWS에서 제공하는 서비스들을 사용하여 동영상 스트리밍 서비스를 구축을 하고 있다. AWS쪽 관리와 운영 방법을 인수인계를 받는 중에 정리를 위하여 블로그를 작성해보기로 했다.



AWS S3와 CouldFront를 사용하여 동영상 스트리밍 서비스 해보기.



시나리오 

이 동영상 스트리밍 서비스는 권한이 부여된 사용자에게만 서비스를 하기 위하여 Signed Cookie와 Signed URL을 사용하여 서비스 한다. 



준비물은 다음과 같다.


1) AWS CloudFront, S3

2) 서비스 대상 HLS 파일


1. 먼저 S3에 Bucket을 생성한다.





2. 서비스 대상 HLS파일을 S3에 업로드 한다. 파일 업로드 방법은 다양한데, 이번 예제에서는 AWS Consol을 사용하여 업로드 해 보도록 하겠다.


먼저 폴더를 생성한다.


서비스 대상 HLS 파일들을 업로드 한다.



업로드가 완료되었다.



3. CloudFront 설정

CloudFront를 셋팅하기 위해 CloudFront페이지로 접근한다.


3.1 주요 설정

CloudFront의 주요설정은 다음과 같다.

Delivery Method 

- RTMP와 WEB이 있다. HLS는 WEB 방식의 Delivery를 사용하기 때문에 값을 WEB으로 선택한다. 

Origin Domain Name

- CloudFront로 서비스 하고자 하는 S3 Bucket이름이다. 클릭하면 select box가 나타난다.

Origin Path 

- S3 Bucket내의 DocumentRoot. S3 Bucket 내의 디렉토리 중 어느 위치를 해당 CloudFront의 /로 사용할 것인지를 나타낸다.

Restricted Bucket Access 

- S3에서 자체적으로 서비스를 하지 않고 CloudFront를 통해서만 서비스가 가능하도록 한다.

설정값은 Yes.

Origin Access Identity 

- S3 접근에 사용할 접근 정보. 이미 기존에 만들어진 것이 있기 때문에 기존 내용을 사용하면 된다. CloudFront의 좌측 하단 메뉴에서도 관리가 가능하다. 설정 값은 Use Existing Identity.

Grant Read Permissions on Bucket

- Origin Access Identity가 S3에 접근 가능하도록 하기 위해서는 S3의 Policy를 업데이트 해야 한다. 이것을 자동으로 해준다. 설정값은 Yes.

Forward Header 

- CORS가 정상적으로 적용되도록 하기 위해서는 Origin을 Forward해줘야 한다. 설정 값은 WhiteList.

Restricted Viewer Access 

- Signed Cookie, Signed URL이 필요하도록 할 경우 Yes. Signed Cookie, Signed URL을 통해서만 접근이 가능하도록 할 경우 설정한다.


그 외의 옵션은 모두 기본값으로 설정한다.



3.2 CloudFront Key Pairs

Signed Cookie, Signed URL을 사용할 경우 Security Credential에서 CloudFront Key Pairs를 설정해야 한다. Security Credential 메뉴는 우측 상단의 로그인 아이디를 클릭하면 메뉴에 나타난다.

여기에서 CloudFront Key Pairs를 추가하거나 Access Key ID를 확인할 수 있다.



4. 동영상 재생을 하기 위해 HLS 파일 주소 가져오기


지금 하고 있는 프로젝트에서는 Signed URL, Signed Cookie 생성시 expire time을 1분으로 주어 생성된 url을 1분간 유효하도록 하였다. 하지만 1분이 지나면 비디오 시청이 불가능해지므로, 비디오 재생 후 매 30초 마다 Signed Cookie를 발급받는 api를 호출하여 인증 갱신하도록 하였다.


4.1 동영상 시청을 위하여 Signed Cookie를 발급하는 API를 호출한다. 이 API는 CloudFront-Key-Pair-Id, CloudFront-Policy, CloudFront-Signature를 키값으로 하는 쿠키를 발급한다. Signed Cookie 생성은 아래 문서를 참고하여 만든다.

http://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html


4.2 Signed URL로 비디오 파일을 요청한다. Signed URL은 암호화된 CloudFront-Policy, CloudFront-Signature와 위의 3.2에서 발급된 CloudFront-Key-Pair-Id를 포함하고 있다. 

Signed URL생성은 아래 문서를 참고 한다.

http://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html


API에서 생성하는 Signed URL 구성은 다음과 같다.


http://도메인 이름/{Path가 포함된 file명}?Policy={암호화된 Custom Policy값}&Signature={암호화 된 signature값}&Key-Pair-Id={Access Key ID값}



위의 방법을 통해 S3내의 HLS파일을 받아와 플레이어에서 재생시킬 수 있다. 현재 진행중인 프로젝트에서는 html의 video태그와 hls.js를 이용하여 라이브스트리밍을 가능하게 하였다.

마치며...
AWS에서 제공하는 Product로 구성해본 동영상 스트리밍 서비스는 HLS파일이 있다면 매우 간단하고 빠르게 구성하여 서비스 가능하다. 또한 CloudFront설정에서 Signed Cookie와 Signed URL사용으로 파일 보안까지 유지 할 수 있다. 물론 HLS파일이 준비되어있다는 가정 하에 구성한것이라 간단한 작업을 통해 구성될 수 있었다. AWS Elastic Transcoder를 이용하여 Video파일을 HLS파일로 Transcoding을 할 수 있는데 이것은 다음번 포스팅에서 다루도록 하겠다.


'Amazon Web Services' 카테고리의 다른 글

AWS CloudFront 객체 무효화 방법  (0) 2016.06.24
Posted by 알 수 없는 사용자
,

텔레그램 봇으로 음성채팅 하기

- Telegram Bot for Text to Speech (TTS)






지난번 포스팅에서 Chrome Speech를 활용해서 웹 기반 어플에서 말하기 기능을 쉽게 사용하는 방법에 대해서 포스팅 했습니다. 


기존 기능을 테스트 해보다가,  메신저에서 여자사람 목소리를 친구에게 보내면 재미 있겠다 싶어서 (여자 목소리로 욕을 보내면 재미있을것 같.. ㅎ) 무작정 만들어 보기로 했습니다.


일단 연동 가능한 메신저 후보군은 많은데, 그중에서 많이들 쓰시는 카톡/Line은 등록하고 하는게 귀찮을것 같고, 개발자에게 무지 친화적인 텔레그램으로 맛만 보기로 결정했습니다.


오늘은 만드는 과정은 차후에 알려 드리기로 기약하며, 결과물과 경험에 대한 공유를 하고자 합니다. 


1. 텔레그램

다들 아시리라 믿습니다.  항간에 보안에 용의한 메신저라고 국가적 보안크리에 반발하여 다들 가입 러쉬가 이뤄졌던 외산 메신저 입니다. 최근에 미국 FBI등 여러 국가 기관에서도 보안검열 같은 움직임에서 조금 이라도 자유로워 지기 위해서  사용자들이 이쪽으로 많이들 갔죠.


저는 보안에 좀 너그러운 상태라서, 굳이 이민까지는 생각하지 않았는데, 오픈소스를 지향하는 개발자로, "오픈되어 있는 개발환경"에 대한 필요성 때문에 올해 가입해서 테스트 용도로 사용중입니다.


2. 텔레그램과 외부 (나의) 프로그램의 연동

텔레그램에서 외부 프로그램과 연계는 중간에 가상의 대화친구인 봇(bot)이라는 대리인을 구현하여 사용할수 있습니다.  여기서 봇(Bot)은 로봇의 준말로 생각하시면 되고, Telegram과 대화를 대신하는 기계/콜백 프로그램으로 생각하면 됩니다.  봇(bot)에 대한 제약은 거의 없는 편이고, 취향에 맞게 개인 서버에 심어서 텔레그램 서버에 제공하면 됩니다. 봇은 크게 2가지 방법으로 준비 할수 있는데, 가장 간단하게는 

1) telegram-cli 라는 텔레그램의 프로토콜을 리버스 엔지니어링으로 만든 환경을 사용하는것이고 


2) Telegram Bot API라는 official platform/library 기능을 활용하여 연동할수 있습니다.  


저희는 이것 저것 손볼께 있어서 그 나마 확장용이한 Telegram Bot API를 활용했습니다.  


일반적으로 bot을 만들고 텔레그램에 *무료*로 등록하고 나면 (저희의 경우 isaybot) 누구나 대화 친구처럼 추가해서 사용가능합니다.  


Note:  다른 메신저는 사용가능한 앱이 뭔지 알려주는 앱스토어 같은게 존재 하는데, 텔레그램은.. 아... 애석하게도 그런게 없습니다.  그냥 사용자가 지인을 통해서 그 봇의 존재에 점조직처럼 알음알음 퍼집니다. 앱을 열심히 만드는 사람의 경우 홍보의 이슈가 있어서 피곤하고 약간은 문제죠.  ^^;  차후 바뀔수도 있을꺼라고 사료됩니다. 



3. 사용법 


3.1 봇(bot) 추가

일단 텔레그램 앱이 여러분의 스마트폰에 설치가 되어 있다고 가정을 하겠습니다.   특정 봇(bot)을 추가하려면, 대화상대 추가와 똑같이 생각하면 됩니다.  대화상대 추가하듯이,  텔레그램 친구목록의 위쪽에 돋보기(Search)를 누르면, 두번째와 같은 화면이 나옵니다.  그창의 맨위 입력부분에 "isaybot"이라고 치면 아래와 같이  isaybot이 보입니다.  그럼, 봇을 선택하여 추가하세요. 





 


isaybot을 누구나 추가할수 있는 가상의 대화상대/친구로 생각하면 됩니다. 




3.2 isaybot 사용하기

isaybot이 대화상대로 추가되면,  맨 처음으로 아래에 나타나는 [ start ] 버튼을 눌러서 시작합니다.  이후에는 언제든지 친구리스트에서 isaybot을 선택하여 봇과 대화를 시작하면 됩니다. 우리 isaybot의 경우에는 제일 처음 내리는 /change 명령(command)을 통해서 음성대화를 하기 위한 환경세팅이 끝납니다.





/change 명령어는  말하고 싶은 언어를 선택하는건데,   /change라고 치면 위와 같은 사용자 키보드가 뜹니다.  위의 그림 처럼, 사용자 키보드에서 isaybot이 한국음성으로 말하게 하고 싶으면, /koKR을 선택하면 됩니다.  

Note:  목소리는 언어별로 약 40여개 지원 합니다.  





한국어 음성으로 설정이 언어설정이 끝난 후, 마지막으로 Message (입력창)에 아무글이나 적어 보세요.  저는  친구를 놀려 먹기 좋은 "오빠 라면먹고 가세요"를 쳐봤습니다 ㅎ  


그러면 위의 그림과 같이 서버에 입력된 글을 보내서, 잠시후 입력한 글을 여자사람 음성을 만들어서 다시 내게 보내줍니다.    보내준 메시지에 파란 플레이 버튼을 눌러주면, "오빠 라면먹고 가세요"가 음성으로 나옵니다.


혼자만 듣기 아깝죠?  친구에게 텔레그램으로 보내보세요. ^^  음성 메시지의 오른쪽에 보면 화살표 버튼이 있습니다.  그걸 누르면 친구목록 뜨며, 친구 이름을 선택하여 보내기 버튼만 누르면 됩니다.


재미있죠? ㅋ



4. 확장 사용법:  "inline"  isaybot


위의 isaybot을 친구와 대화하는 방식으로 사용하는 방법 말고, 친구 추가 없이 다른 사람과 대화중에 사용가능하는 방법이 있습니다.    텔레그램에서는 이걸 "inline" bot 이라고 하는데,  아무 대화창에서 "@"로 시작하는 명령어를 날리면 되는데, "@" 명령으로는 봇의 이름을 사용하면 됩니다.  




가령, isaybot을 inline 봇으로 사용하고 싶은경우,  위의 그림처럼 @isaybot을 대화 입력창에 치고,  글 내용을 치고 잠시 머물면, 위와 같이 팝업 메뉴가 뜹니다.   이후 언어중 하나를 눌러주면, 아래와 같이 새로운 링크를 포함한 메세지(Facebook Open Graph)가 대화창에 나타납니다. 




위 수신된 메세지 본문의 그림을 눌러주면 음성을 들어 볼수 있는 웹플레이어가 뜹니다.    참고로, 팝업 플레이어는  본분의 그림을 눌렀을때만 뜹니다.  반면 링크를 누르면,  추가적인 새 웹창이 뜨면서 플레이어가 뜹니다.  (텔레그램에서는 PC나 태블릿인 경우 팝업플레이어가 지원되지 않고, 웹플레이어만 지원됩니다.)  


여기에서 플레이 버튼을 누르면 수신된 내용을 음성으로 들어 볼수 있습니다.


5. 마치며


봇의 이해를 위해 재미로 만들어본 서비스입니다.   

가입없고 계정따위는 없는  무료 서비스이니 부담없이 쓰셔도 좋습니다. ㅎ


화창한 봄날에

화려한 벗꼬ㅊ엔딩을 간절히 기다리는 

가망없는 벗에게 

봇으로 여자 목소리를 흘려보내보세요.

잘하면 꽁짜술 한잔 하실수 있습니다. 



- 골름골름



PS  isaybot을 만드는데, 이번에도 forcemax님과 mo님이 수고해 주셨습니다. 감사합니다.





Posted by 알 수 없는 사용자
,

chrome speech synthesis service 개발기

- "크롬을 음성합성 서버"로 사용해보자







"사장님, 스마트 미러가 리눅스에서 잘 안돼요. 어떻하죠?"

.

.

.

작년 말에 접하게 된 마이크로소프트의 에반군이 만든 garage 프로젝트인 스마트미러(Smart Mirror) 에서 확인 했었고, 거의 모든 오픈소스 스마트 미러 프로젝트는 라즈베리파이(RPi)등의 Arm기반 보드에서 "리눅스"로 돌리고 있었기 때문에 믿기 힘든 비보였습니다.


"쫌! 잘해봐. 말이돼냐? (썩소)"  "아니예요, 실제 잘 안된다고 어디서 본것도 같아요.(떨리는 눈빛)"


'에이 설마, 또 초짜 주우우니어 호빗 개발자의 닥질..'  여전히 그 생각이였고, 솔직히 다른 OS에서 다되는데 리눅스에서 안된다는 건 약간은 리눅스(마이프레셔스!)를 데탑으로 끌어 안고 사는 한때 호빗 개발자였던 골름의 밥상에 돌 던진듯한 느낌을 받는... 


그래도 한번 속는셈 치고 들어나 보기로 했습니다.


"그래 뭐가 안된다는 건데?(썩소2)"       "아, 제가 이번에 연동한게 유투브, 지도API, 어쩌구 저쩌구..."

"아 그러니까 뭐가 안된다는 건데?(확신찬 썩소썩소썩소)"           ".. 그러니까.. 저.. 말하는게 안되요!"


"응?!?  혹시 말하기 기능 넣었어?(반짝반짝)"   "..네.."  (이 시점에서 소으니:골름 = 1:0!) 



바로 소으니는 맥에서 잘되는걸 보여줬고, 리눅스에서는 안되는것도 보여줬다. (2:0!)


"아.. 그..러네.  그래도 니가 비동기 방식의 javascript 쓰다가 뭔가 잘못한거?" (쓸데없는 의심, 3:0!)


"네,  그런데 일단 코드가 너무 간단해서... 잘못하기 힘든데요?"







크롬에서 음성합성 예제: HTML5 Speech Synthesis API 사용

========================================





여기서 말하기 기능이라는 것은 '음성합성' 또는 'Speech Synthesis'라고 불립니다.  다들 아시겠지만, 우리가 은행이나 콜센터에 전화를 걸었을 때 자동으로 대답을 해주는 약간 어색한 사람 목소리를 위장한 마디마디 리코딩된 기계음 등이 이 부류입니다.   



코드군: 

var utterance = new SpeechSynthesisUtterance('Hello, 세상');

var voices = window.speechSynthesis.getVoices();


utterance.voice = voices.filter(function(voice) { return voice.name == 'Google 한국의'; })[0];


window.speechSynthesis(utterance);



'잉, 코드군이 너무 간단한데? ' 


뒷목이 뻑뻑한 느낌이 들더군요. 지은죄가 있는지라 몇일 구글군의 힘을 빌어 뒷북 뒤지기를

시작했는데, 음성합성을 쓰기 위해서 엔지니어링 관점에서 몇가지 알고 있어야 될것들이 나왔습니다.




음성합성(Speech Synthesis) 간략정리

=========================


0. Speech Synthesis는 나름 긴역사가 있다.  특히 예전에 sphinxsearch검색하면 검색결과 밀어 

버리고 쓸데 없이 나오던 sphinx도 speech 관련해서 꽤 유명한 놈이더라. (제대로 잡설!)


1. 웹브라우저가 사용할수 있는 Speech Synthesis API는  Speech Recognition API와 나름 2년이나 되었다.  (since google chrome 33+, 현재 쓰고 있는 버젼은 48+)

구글 크롬이야 당연히 지원하고 있었고, 사파리도 지원하고 브라우저들이 다들 지원하는 분위기다.


2.  위의 내용 1을 순진하게 믿고 테스트 하다보면, 지금 그닥 쓸만한 놈은 chrome이다.  

     그리고 된다는 SSML은 아직 안된다.  SSML은 음성합성을 XML로 표기하여 끝말올리기, 반복하기 등을 표기할수 있는 방법입니다.    


3.  그리고 결정적인, Speech Synthesis가 "리눅스에서는 안되고, 맥에서는 된다"는 틀렸다.  



정확한 정보는 "(목소리가 없기 때문에) chromium에서는 안되고, chrome에서는 된다" 이다.  (앗싸.  3:1!)


3번은 알고 나면 허무하지만, 약간의 보충설명이 필요합니다. 그래서 조금 내용을 살펴 보겠습니다.





Chromium은 Chrome과 다르기 때문에 

구글의 완성도 높은  아름다운 목소리를 가져올수 없습니다.

======================================



원래 웹브라우저의 Speech Synthesis API에 대한 표준화 문서를 보면,

Speech Synthesis API는 API이지 실제 voice라는 리소스는 웹브라우저가 

지원(provision)할수도 있고, OS가 지원하는 네이티브 리소스로 (따라서 chrome external) 

voice를 사용할 수도 있습니다. (양자택일!)



그런데, 대부분의 우리가 수행했던 Speech Synthesis의 테스트는 

구글 크롬(default로 날아오는 voice는 google이 제공)했기 때문에 문제가 없었고, 

쓸수 있는 API만 있지만, chromium은 google의 voice API 키가 없기 때문에, 

말할 '목소리'가 없습니다. 


기계가 목소리가 없어서 인간이 안되고 결국 허무하게 여기서 거품으로 끝난다는건 어디서 많이본 

동화같습니다.(아이씨- 언더더씨 네요.)





그럼 소으니가 말했던 스마트 미러가 맥은 되고 리눅스에서는 목소리가 안나오는 이유는 뭘까요?  

네. 우리가 쓴 node.js의 electron은 (예전에는 ATOM으로 불렸었죠) chrom"ium"의 분신이고

따라서 보이스 실물 리소스가 존재하지 않습니다. 구글에서 허락없이 땡겨올수 없기 때문이죠.  

하지만, Mac에서 제공하는 네이티브 목소리가 있기 때문에 맥(electron)에서는 잘 되었던거고,

리눅스(electron)에서는 안된겁니다.  여기서 "댕~"하는 상황은 리눅스의 chrome에서는 되니까

더 헛갈린겁니다.  알고나면, 구글의 chrome이니까.  구글 목소리니까 당연한거죠.


즉, 확실한건 chrome != chromium에서 생기는 문제인거요. 


아, 참고로 chromium을 걍 컴파일 해서 쓸까 (electron) 했는데요, 저같은 생각을

하는 골름들이 무지 많나 봅니다. chromium 사이트에 노란색 볼드체 으로 

이렇게 적혀 있네요. ㅎ


https://www.chromium.org/developers/how-tos/api-keys





"Do NOT post to the various Chromium groups/mailing lists for questions about the Speech API."


(헐- 넹. 골름골름)



Chrome에서 사용 가능한 목소리들은 OS별로 살짝 다릅니다. 
========================================

실제 가장 많이들 쓰시는 Windows 10(7,8도 비슷할겁니다)에서 chrome을 사용하면 
운영체제가 제공하는 네이티브목소리 (언어별로 하나씩 있는듯 보입니다!) 한개만 
"Lang"환경에 딱 맞춰서 추가 사용가능하며, 크롬에서는 가지고 있는 목소리
다주세요 라고 하면 구글 목소리 리스트에 딸랑 한개 더 얹어서 나옵니다.  맥의 
경우에는 맥이 제공하는 목소리들 전체를 "Lang"환경을  고려하지 않고 모두 다 선택할수 
있게 주즈륵 보태서 보여줍니다.  
(아, 나름 맥의 목소리 리스트도 구글군같이 아름답습니다) 


그럼 모바일 환경에서는 어떨까요?  일단 안드로이드의 크롬에서는 구글의 많은 언어별 
목소리가 리스트로는 다 사용가능한것 처럼 나옵니다. 이건 근데 나름 함정입니다. 
다른 언어의 목소리를 선택하더라도 같은 목소리 한개의 목소리만 나오는데, 우리나라의 
경우(ko-KR)를 예로 들면, 한국 여성분의 목소리 하나로 통일되어 나옵니다. 
다른 목소리를 듣고 싶으시면, 안드로이드의 OS언어환경을 바꾸시면 그 환경에
맞는 한개의 목소리만 나옵니다.  즉 동시에 두개의 언어의 목소리는 들을수 
없습니다.  이런 접근은 Windows의 접근이랑 비슷합니다.
(네. 착한 구글군이 요즘은 많이 다르네요.  아마도 단일 언어 사용자가 대부분인 OS 
환경을 고려한 배려이겠지만서도, 선택 따위는 니가가라 하와이~네요. OS가 되는 순간, 
약간 거만한 느낌이 듭니다. 쩝.)  

참 여담으로 애플사의 iPad 에서는 chrome이 뭐가 잘못되었는지 소리가 안나더군요.  
그리고 ChromeOS/ChromeBit는 없어서 테스트 못해봤습니다.

Note:  그리고 약간 더 헛갈리는건 다같은 chrome이라도 안드로이드의 목소리 
이름(voice name)이 데탑용 OS에서 와는 다르게 나옵니다.  예를들어, 
원도우,맥,리눅스 OS에서는 구글의 우리나라 목소리는 "Google 한국의"(ko-KR) 인데 
한국어일때는 "대한민국" 한국 으로 나오고, 영어일때는 심지어 
"Korean South Korea"(ko_KR)로 나옵니다.  

범용적 웹어플 만들때 무지 곤란할것 같습니다.


그럼, 크로미엄(chromium)기반 또는 
스마트 미러에서 목소리가 나오게 하려면 어떻게 해야 할까요?
===================================================

힘듭니다. 대신 정품 무료 chrome을 쓰시면 됩니다. 하지만, kiosk같이 원도우 매니저의 기능으로 
웹앱을 만드시려면, 또는 저희같이 node.js electron.js 를 쓰려면 얄짜없이 OS에서 
제공하는 목소리를  fallback됩니다. 

근데 이렇게 대충 하다보면 개발비 백만원짜리 거울아거울아 탄생도 가능합니다.  두둥. 

이건 여러모로 봅잡하죠. 그래도 꼭 하시고 싶으시면 OS를 구분으로 제가 생각할수 있는 몇가지 
옵션을 생각해 볼수 있습니다.  일단 제 개인적인 생각이니 참고만 하시면 좋겠네요.  
(가정: 모든 OS에서 node.js electron은 돕니다.)    

1) 원도우로 한다.   
   일단 제일 싸고 입맛에 맞는 저렴한 Intel Stick PC (아톰 기반) 나 패드를 약 10만원에 구입합니다.
   원도우8 깔려있으니 걍 쓰거나 7월전에 빨리 10으로 공짜 업그레이드 합니다.  작고 이쁘고 나쁘지 
   않은 옵션인듯 보입니다. (RPi2관련 약 2배 정도 가격으로 생각하시면 되지만서도)

2) 맥으로한다.  
  미친척하고 1)에 해킨토시를 설치한다. 근데요, 아톰은 설치가 안된다는 이야기가 있던데요. 
  이런 도전은 정신건강에 해로울수 있습니다.

3) 리눅스로 한다. 
    아, 그런데 RPi/odroid가 안되네요. 으..   Intel Stick PC도 안되네요.  (위설명 참조) 으...
   3)이 안된다는것  심히 골름골름합니다. 그래서 RPi는 구글님이 chrome을 안주니 
     (chromium만 존재) 포기 하더라도,  인텔에서 안되는건 진짜 못참겠습니다.  

(아, RPi qemu로 x86 emul 하면 어떨지는 모르겠네요. OS2개 크롬(미엄) 2개? ㅎ)
     

 포기하기는 좀 그렇고, 뭔가 하면 될것도 같은데요?




Note:  참, 여기 한번 가보세요. http://labs.naver.com/ 
      이번 스마트 미러 프로젝트에 필요한 모든 기술을 다 똬악 모아서 하고 있네요. ㅎ
      나름 열심히 잘하는것 같기는 합니다.  음성인식/음성합성/기계번역등은 앞으로 IT의 발전에
      중요한 공공재와 같다고  생각합니다.  그런 취지에서 보면 정말 칭찬해주고 싶습니다.  
      어째튼, 막써야 되는 공공재를 약간 조심스럽고 고급스럽게 접근하는게 제 취향은 아닌듯 보입니다.


그럼 내 데스크탑 Chrome을 서버로 써서, 
"Chrome이 대신 말하게" 하면 어떨까요?=============================




이렇게 하면, 위의 인텔PC 기반에서 리눅스(마이프레셔스!)에서 돌릴수 있습니다.
그리고 여차하면, RPi를 그냥 쓰고 말하기를 딴데로 보낼수도 있습니다. 
(물론 생각해 보면  다시 택배 받을수도 있을겁니다. WebRTC? ㅋ 가난하게 살다보면 뭐..)



어째튼, Chrome을 서버로 쓰는걸 만들기로 해봅니다, 골름골름~



그래서 Chrome을 웹 보이스 서버로 세워봤습니다.
==================================

준비물:

0) 스피커 달린 Intel PC + 마이프레셔스  (뭐 개발용 아무거나)
1) 웹서버 (node.js, express 씁시다. npm install 좋던데요?)
2) 대신 말해줄 google chrome (네 여기 까지는 구글군이 꽁짜로 줍니다)

여기서 문제는 1)과 2)의 연결 문제인데요, 제가 동굴에서 물고기를 쌩으로 자바(script) 먹을 때랑은
다른 새로운 세상이 열렸더군요. socket.io라는 그물(socket)으로 편하게 잡을수 있더군요.

그래서 그걸로 1)과 2)를 연결하면 되겠더군요.

... 그리고  결과물이 여기 있습니다.  코드는 이것저것 빌려왔는데, 
만들다 보니 살짝 재미있는 장난감이 나왔습니다.


쓸데없는 소리 이제 그만!  Show Me! Please talk to me!

======================================





1)  기본테스트:   


너그러운 마음에서 데모 한번 봐주시고,  


http://speech.embian.com/



2)  확장테스트:


재미로 준비한 추가 데모 꼭 해보시고, 한번 쭉 소리나는거 들으시고, 

*setting: 의 en-GB 를 ko-KR로 바꿔 들어 보세요 ㅎ

(강추! 우리집 꼬마가 좋아합니다.)

중국어/영어/일어/스페인어등 언어 공부하시는 분들 무료로 활용법을 찾으시면

만든 골름은 무지 감사할것 같습니다. 


http://speech.embian.com/rap



3)  혹시 수정이나 설치 필요하신 분 계시면 github에서 오픈소스로 제공합니다.

https://github.com/embian-inc/chrome-speech-synthesis



아, 외로운 친구의 PC/폰에 크롬띄워놓고 이성의 목소리로 "밥 먹으로 가요"를 

날려볼수 있습니다.  퍽이나 재미집니다.  골름골름~




맺음말

=====


동굴에 들어간지 오래 되어 소스가 날것이라 전혀 이쁘지는 않습니다. 

지나가던 저희 개발자 호빗 무리들이 무지 비웃었습니다. 


하지만, 골름은 사랑받기 위해서 

태어난 한때 호빗이였던 아이입니다.              이뻐해 주시면 좋겠네요. (최종스코어:  3:2!)


그럼 전 가족부양하러 물고기 잡으러 다시 동굴로 돌아갑니다.긴글 읽어 주셔서 감사합니다. 


마이프레셔스, 골름골름~

  


ps 결국 구글님이 무료로 열어줘서 편하게 쓰지 않을까 생각합니다. 언젠가는 ^^ 

아님 네이버님, 왓쓴님 이라도.  아니면 누군가는 문익점 되서 디지탈씨앗 몇개 날라야죠, 뭐. 






References:


Standard for Web Speech Synthesis

* https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#examples-synthesis


Standard for SSML

* http://stackoverflow.com/questions/21952736/the-right-way-to-use-ssml-with-web-speech-api

* https://www.w3.org/TR/speech-synthesis11/#edef_emphasis


Main Code of Speech Synthesis API Example

* http://blog.teamtreehouse.com/getting-started-speech-synthesis-api



Posted by 알 수 없는 사용자
,

12월 중순 쯤 회사내에 흥미로운 동영상이 공유 되었는데 바로 smart-mirror 라는 프로젝트였습니다. 아래 동영상을 보시면 smart-mirror에서 사용자의 음성으로 지도나 philips hue 전등을 컨트롤 하는 모습을 보실 수 있을 것입니다. 되게 fancy해 보이지 않나요? smart-mirror에서 사용한 언어는 javascript이며  speech recognition library로는 annyang 을 사용하고 있었습니다.


[  smart-mirror[링크]


회사 내에서도 우리도 해보자라는 의견이 나오기도 했고 마침 이전 프로젝트도 끝나고 시간이 남아 Garage Project로 smart-mirror를 하게 되었습니다.2주 동안 진행했던 이 프로젝트의 1단계 목표는 아래와 같습니다.

첫번째, smart-mirror 한글화 

두번째, 재미있는 기능(youtube search, 지하철 도착 정보, Sound Cloud 음악 재생 등) 추가 


이 프로젝트에서 추가로 사용한 API는 다음과 같습니다. 

1. Youtube Data API 

2. 서울시 지하철 도착정보 open API 

3. Sound Cloud API  


smart-mirror는 소프트웨어 측면보다 하드웨어 측면에서 준비하는 시간이 걸렸습니다.


준비물(원하는 결과물에 따라 가격이 달라질 수 있습니다)

물품 

가격 (단위: 원)

회사에 안쓰고 굴러다니던 오래된 태블릿

 0

philips hue 전등

 279,000

고대유물이 되어 방치 되었던 서버랙 유리 문짝

 0

절연테이프

 1300

아크릴 (가로: 40cm , 세로 : 50cm)  1개 

 10,000

미러필름 1m~2m

 18,000

 총 비용 

 308,300


하드웨어 구성을 살펴 보면 라즈베리파이 2, USB microphone, 모니터, one-way mirror, philips hue 전등으로 구성되어 있었는데  라즈베리파이 2 + 모니터  대신 사용한지 오래된 노트북이나 태블릿 등을 사용하였고, philips hue 전등은 프리스비에서 구매하였습니다. 한가지 남은게 있다면  one-way mirror가 관건이었습니다. 현재 한국에서 one-way mirror를 구하는 것이 어려울 뿐만 아니라 상당히 비싼 가격에 판매되고 있어서 대체 할 만한 것을 계속 찾아보다 유리에 미러필름을  붙였습니다. 

미러필름의 판매처는 다음 링크에서 확인하세요.[사이트내에 가격이 30m가 180,000원, 1m~2m가 18,000원에 판매 되고 있습니다. ]


 evancohen의 smart-mirror

 embian의 smart-mirror

 라즈베리파이 2, USB microphone, 모니터 

  사용한지 오래된 노트북이나 태블릿 

  one-way mirror 

 아크릴 + 미러필름 or 유리 + 미러필름 or 유리 액자 + 미러 필름 


미러필름을 붙이는데 상당히 애를 먹었습니다. 특히 아크릴에 경우 반나절 정도 지나자 기포가 올라오는 단점이 있어서 유리에 미러필름을 붙였습니다. 





[one-way mirror 제작 과정]



[절연테이프를 붙인 one-way mirror 뒷면]

[one-way mirror 앞면]


2주 동안 작업한 이 프로젝트의 최종 결과물은 다음과 같습니다.


[스마트 미러] 


코드는 다음 링크에서 확인하실 수 있습니다. Github : https://github.com/embian-inc/smart-mirror-ko.git

시연동영상은 다음과 같습니다.



현재 smart-mirror는 mac,window,ubuntu 환경에서 모두 사용 가능하며 android의 경우 다음링크를 참고하세요. 

'Smart-Mirror' 카테고리의 다른 글

텔레그램 봇으로 음성채팅 하기  (2) 2016.04.10
chrome speech synthesis service 개발기  (2) 2016.02.23
Posted by 알 수 없는 사용자
,

"E2E Monitor 프로젝트"가 끝난 후 고도화 작업이 진행되었습니다. 

 "E2E Monitor 프로젝트 회고"포스팅을 보면, 프로젝트 진행 당시 빠른 시간 안에 결과물을 만들어서 검증하기 위해 추적 정보 생성기를 "수동 추적 방식"으로 개발하였습니다. 하지만 "수동 추적 방식"은 모니터링 대상 시스템에 바로 적용이 어렵기 때문에 E2E Monitor의 최우선 과제로 "자동 추적 방식"을 꼽았습니다. 따라서 자연스럽게 Back-end 고도화는 "BCI(Byte Code Instrumentation)기법을 사용한 자동 추적 정보 생성기 개발" 이 되었습니다.


고도화 부분

E2E Monitor 프로젝트는 아래 <그림1.>처럼 크게 3가지의 구성요소로 나뉘는데요,


<그림 1. E2E Monitor 구성요소>


이 중에 추적 정보 생성기에 대해 "자동 추적 방식"을 사용할 수 있도록 고도화를 진행하였습니다. 


추적 정보 생성기 개발

자동 추적 방식을 도입하기 위해 BCI 기법을 사용한 여러 가지 모니터링 툴을 조사하던 중 ASM 기반으로 구현되어있는 Java Agent 프로그램인 Byteman을 접하게 되었습니다.

Byteman은 재컴파일이나 재구동 없이 실행 중인 어플리케이션에 Bytecode를 변형, 주입 및 제거 가능한 기능을 가지고 있습니다. Byteman에서 사용하는 DSL(Domain-Specific Language)로 "Rule" base script를 생성하여 동적으로 디버깅 코드를 디버깅 대상 Application에 적용 가능합니다. 

즉, Byteman을 도입하면 "Rule" Script를 통해 E2E Monitor에서 필요한 정보를 모을 수 있는 추적정보 생성기를 모니터링 대상 Application에 동적으로 적용 가능한 것입니다. 이러한 이점 때문에  Byteman을 도입, 자동 추적 정보 생성기를 개발하였습니다. 


자동 추적 정보 생성기가 수집하는 정보

기존에 개발했던 수동 추적 정보 생성기에서 생성한 정보들을 전부 수집 및 생성할 수 없었지만, 사용자 프로그램에 표시하기 위한 기본정보가 추출됨을 확인하였습니다.

자동 추적 정보 생성기에서 추출할 수 있었던 정보는 다음과 같습니다.

1. 하나의 네트워크 통신의 시작과 끝

2. 하나의 네트워크 통신을 처리하는 데 걸린 시간

3. 네트워크 Request 종류, URI, 파라미터 이름, 파라미터값 -> 고도화에서 추가된 정보

4. 현재 모니터링 하고 있는 Application의 이름

5. 네트워크 통신 처리 시 수행된 Method 이름

6. 네트워크 통신 시퀀스 정보(네트워크 통신 또는 DB 질의가 발생한 경우 Call Stack처럼 수집) -> 고도화에서 추가된 정보

7. DB 쿼리와 수행 시간 -> 고도화에서 추가된 정보

8. E2E Monitor에서 추적에 필요한 필수 정보를 HTTP 통신 시 사용하는 Client 헤더에 자동으로 Inject

9. Throw된 Exception 기록


Emulator에 자동 추적 정보 생성기를 실행하여 E2E Monitor의 사용자 프로그램이 어떻게 표현해 주는지 확인해 보았습니다. 

먼저 수동 추적 생성기를 적용한 경우 사용자 프로그램은 아래와 같이 표현됩니다.

<그림 1. 수동 추적 정보 수집기를 사용한 경우 볼 수 있는 정보>

다음은 자동 추적 정보 수집기를 사용한 경우 표현입니다.

<그림 2. 자동 추적 정보 수집기만을 사용한 경우 볼 수 있는 정보>

수동 추적 정보 수집기가 보여주는 정보에 비해서 빈약한 정보를 보여주고 있지만, 자동으로 수집된 정보는 사용자에게 대략적인 네트워크 플로우를 보여줄 수 있는 수준입니다. 


마무리

이번 고도화에서 모니터링 대상 시스템에 BCI 기법을 도입한 자동추적 정보 수집기를 동적으로 적용 할 수 있게 하였습니다. 기본적인 정보를 자동 수집하여 사용자 프로그램에서 표현이 가능했지만, 추가로 모은 정보를 표현하지 못한 부분이 있었습니다. 이는 추적정보 처리기와 사용자 프로그램이 같이 개발 되어야 했기 때문입니다. 이 부분은 향후 개발 계획에 넣어 놓고 이번 고도화를 마무리 지었습니다.

E2E Monitor는 이제 기존의 수동 정보 수집 방식에 더하여 자동 정보 수집 방식까지 갖추게 되었습니다. E2E Monitor v3.0을 기대하며 이번 포스팅을 마칩니다.


Posted by 알 수 없는 사용자
,

얼마전에 마무리 되었던 E2E Monitor 프로젝트의 고도화 작업이 있었습니다. 이 작업에 제가 참여하게 되었는데요.

(*혹시 E2E Monitor에 대해 궁금하시다면 다음 링크를 참조해 주세요!)

E2E Monitor 고도화 작업은 크게 두가지로 나뉘었습니다. 


첫번째, BCI(Byte Code Instrument) 작업

두번째, E2E Monitor UI 고도화 → 저랑 종민씨가 담당했던 부분


이번 글에는 저랑 종민씨가 담당했던 E2E Monitor UI 고도화 작업에 대한 이야기를 풀어볼까 합니다. 

E2E Monitor UI 고도화 작업의 목표는 Dashboard 개인화였습니다. Dashboard 개인화란 운영자마다 또는 시스템 마다 보고 싶은 정보가 조금씩 다를 수 있기 때문에 사용자들이 원하는 데로 Dashboard를 편집 할 수 있도록 하는 것입니다.

본격적으로 작업을 시작하기 전에 Dashboard UI와 관련된 자료를 찾아 보기 시작 했고 Dashboard 개인화를 하는데 참고한 오픈소스는 아래와 같습니다.


1. http://nickholub.github.io/angular-dashboard-app/#/

이 오픈 소스의 경우에는 사용자들이 원하는 위젯을 추가 삭제할 수 있도록 구현 되어있었습니다. 아쉬운 점이라면 정렬이 되지 않아 다소 산만해 보이는다는 점입니다. 


[nickholub - angular-dashboard-app]



2. http://angular-dashboard-framework.github.io/angular-dashboard-framework/#/sample/01

이 오픈 소스의 경우에는 사용자가 위젯을 추가 삭제 할 수 있고, 일정한 비율로 정렬 할 수 있으며 , 원하는 위치로 drag&drop 할 수 있도록 구현되어 있었습니다. 


[angular-dashboard-framework]


위 2가지 오픈소스의 장점을 참고해 만들었던 E2E Monitor의 대략적인 스토리보드 중 하나는 아래와 같습니다.



[E2E Monitor  스토리보드]


이렇게 스토리 보드를 작성하고, 약 1개월 동안 개발을 하였습니다. 

E2E Monitor 2.0에는 Responsive Web, Dashboard Customizing, Widget Modularization 등의 기능을 추가로 개발하였는데요.

Dashboard Customizing에서는 편집모드에서 Dashboard 하나 하나를 이루고 잇는 그래프들을 하나의 위젯이라 생각하고 Drag&drop을 하는 기능이 필요했고, 이 와 관련된 라이브러리로 사용했던 것이 SortableJS입니다.

angular-dragdropng-sortable 같은 라이브러리도 고려 하였으나 가장 많이 사용하기도 하고, 사용하기도 쉽고, 문서도 잘 되있어 SortableJS를 사용하게 되었습니다. 


그래서 Dashboard를 Customizing할 수 있는 E2E Monitor는 다음과 같습니다. 




Demo는 http://e2edemo.embian.com/#/e2emDashboard 에서 확인 하실 수 있습니다.




[E2E-Monitor v1.0 

 [E2E-Monitor v2.0]   


추후 고려해야 할 사항 


개발 완료 후 회사 분들과 함께 논의를 한 결과 좀 더 개선 해야 할 사항과 의견들이 있었습니다. 

첫번째, Performance 측면에서 문제가 없을까?

두번째,활용의 측면에서 Widget에 대한 설명이 명확하지 않다.

세번째,Dashboard에서 한번에 여러 서비스를 관제하게 될 경우를 고려해 보자 

.

.


 이러한 사항은 추후 E2E-Monitor v3.0에서 적용해 볼 계획입니다.  


Posted by 알 수 없는 사용자
,

E2E-Monitor와 Pinpoint를 비교한 Slide자료 입니다. 비교시 사용한 Pinpoint 버전은 1.5.0 입니다.

더불어, 아래 데모 사이트에서 E2E-Monitor를 체험 해 보실 수 있습니다.

데모 사이트 바로가기 : http://e2edemo.embian.com/



참고 자료: 

https://github.com/naver/pinpoint

http://d2.naver.com/helloworld/1194202


Posted by 알 수 없는 사용자
,

"E2E-Monitor 개발 프로젝트 회고" 마지막 글이 되겠네요.

마지막으로 다룰 내용은 E2E-Monitor의 Back-end 부분에 대한 이야기 입니다.

초기에 설계했던 시스템 구조에서부터 프로젝트 완료 당시의 변화된 시스템 구조까지, 그 변화 과정을 살펴 보면서 왜 구조가 이렇게 변경되어 왔는지, 그리고 거기에 사용했던 솔루션들은 어떤 기준으로 도입했는지에 대해서 이야기해 볼까 합니다.



E2E-Monitor의 시스템 구성과 사용했던 기술들


처음에 고객사로부터 받은 요구 사항은 상당히 구체적인 것처럼 보이면서도 한편으로는 모호한 것들이 많은 상태였습니다.

가장 먼저 필요했던 것은, 고객의 요구 사항에 대해서 저희가 정확하게 이해하고 있는지에 대한 확인 작업이었습니다.

그래서 일단, 1차적으로 분석한 요구 사항을 바탕으로 "시스템 구조도"를 작성해 보기로 했습니다.

모호했던 부분들은 우선 나름대로의 상상력을 동원해 가며 채워 넣고, 나중에 고객사에게 확인을 받기로 했습니다.



첫번째 시스템 구조도

아래의 그림이 E2E-Monitor의 첫번째 시스템 구조도 입니다.


[그림 1. E2E-Monitor 시스템 구조도 - v1]


Log Transmission Layer는 모니터링 대상이 될 시스템으로부터 추적 정보를 전달 받는 부분입니다.

구조도를 보시면 Log Collector와 Polling Processor가 각각 Message Queue로 데이터를 보낼 수 있도록 연결되어 있는 것을 보실 수 있습니다.

Log Collector와 Polling Processor를 함께 둔 이유는, 당시에는 대상 시스템에서 어떤 방식으로 추적 정보를 전달받을 수 있을지 몰랐기 때문입니다.

그래서 일단 Push 방식과 Polling 방식 두가지 모두를 처리할 수 있는 구조를 생각하게 되었습니다.

그리고, Message Queue를 임시 저장소로 사용함으로써 여러가지 전달 방식에 따라 유동적으로 대처할 수 있도록 설계했습니다.


Log Process Layer는 수집된 추적 정보를 분석하고 재가공해서 저장소에 저장하는 부분입니다.

Log Pre-processor는 Message Queue에서 추적 정보를 가져와 저장소에 저장하고 CEP Engine으로 데이터를 전달 하는 역할을 합니다.

CEP Engine(실시간 이벤트 분석, 처리 솔루션)은 Log Pre-processor로부터 전달 받은 데이터에서 특정 이벤트 또는, 이벤트 패턴이 발견되면 데이터를 Log Post-processor로 전달합니다.

Log Post-processor는 CEP Engine으로 부터 전달 받은 데이터의 유형에 따라 사용자에게 바로 메세지를 보내거나 저장소에 저장하는 역할을 담당하게 됩니다.

그리고 웹 클라이언트에게 화면에 보여줄 데이터를 전송하는 API 서버도 이 Layer에 두었습니다.


그 외 데이터를 저장소하기 위한 Data Layer, 사용자가 웹브라우저를 통해 접근할 수 있는 Presentation Layer를 분리 시켜놓았습니다.


첫번째 시스템 구조도는 비록, 이 후 많은 변경이 이루어지긴 했지만, 고객사의 요구사항 분석이나, 고객사와의 업무 범위를 조율하는데 많은 도움이 되었고, 시스템의 골격을 잡는 데 큰 역할을 했습니다.




두번째 시스템 구조도

다음에 있는 구조도는 고객사와의 업무 범위 조율 및 요구 사항 협의가 어느정도 마무리 된 다음에 작성된 것으로, E2E-Monitor의 두번째 시스템 구조도 입니다.


[그림 2. 요구 사항 협의 후 수정된 시스템 구조도 - v2]


첫번째 구조도와 달라진 점을 찾아볼까요?

우선 첫번째 시스템 구조에 있던 Polling processor가 없어졌습니다.

기존 대상 시스템들을 확인한 결과, 모든 시스템들이 Log Collector를 통해 Message Queue로 추적 정보를 보내는데 문제가 없는 것으로 확인되었습니다.

그래서 추적 정보를 수집하는 것은 Log Collector로 단일화 하기로 하고, Polling processor는 구조도에서 제외했습니다.

다음으로 달라진 점은 CEP Engine을 빼고 그자리에 Log Filter와 WebSocket 모듈이 추가된 부분입니다.

CEP Engine을 추가하는 것은, 필요 이상으로 개발 비용 및 기간이 증가할 수 있다는 점과 CEP Engine 운영 인력 부제등의 문제가 주요 이유로 작용했습니다.

그대신 간단하게 CEP Engine의 역할을 할 수 있도록 간단하게 Log Filter를 구현하고 실시간 서비스를 위해 WebSocket 모듈을 추가해 놓았습니다.

그리고 데이터 저장소 부분은 MySQL이나 PostgreSQL같은 RDBMS가 아닌 Elastic Search을 사용하기로 했습니다.



Elastic Search 도입 이유

Elastic Search를 사용하기로 한 가장 큰 이유는 데이터 분산 저장 때문이었습니다.

E2E-Monitor는 대상 시스템에 종속적인 시스템입니다.

대상 시스템에서 발생하는 모든 이벤트를 저장해야 하고, 시스템 Scale-out 가능성에 대비해야 합니다.

이러한 특성을 만족시키기 위해 가장 신경썻던 부분은 데이터 저장소 부분이었습니다.

원활한 Scale-out을 위해서는 늘어나는 데이터량에 대응할 수 있는 Write 성능과 데이터 분산 저장이 필요했습니다.

MySQL이나 PostgreSQL같은 오픈소스 DB로는 Write 성능도 일정 수준 이상 높이기 힘들었고(스토리지를 SSD를 쓰면 될것 같은데 비용이 문제), 데이터도 분산해서 저장할 수 없었습니다.

결국 Data Sharding 기술을 이용하는 솔루션을 사용해야 했는데, 오픈소스 진영을 솔루션들 중에서 Data Sharding을 지원하는 솔루션으로 고려 대상이 되었던 것이 MongoDB와 Elastic Search였습니다.

두가지 솔루션 모두 시스템 Scale-out과 데이터 Sharding을 지원합니다.

이제 두가지 솔루션 중 어떤 것이 E2E-Monitor에 더 적합한 솔루션인지 이것저것 고려해보고 결정하는 일이 남았습니다.

두가지 솔루션중 Elastic Search를 선택한 이유는 E2E-Monitor가 주로 사용해야 할 쿼리 패턴 때문이었습니다.

E2E-Monitor에서 사용해야 할 쿼리의 대부분은 Grouping, Sorting, Searching 기능들이었습니다.

관제를 위해 필요한 데이터는 넉넉하게 잡아도 두달치 정도면 충분 할 것으로 예상했습니다. 

옛날 데이터까지 모두 저장할 필요가 없었습니다. 

최근 데이터만 저장하고 있으면서 데이터 Aggregation과 Searching 쿼리를 주로 사용 하기에는 MongoDB보다는 Elastic Search가 더 적합한 솔루션이라고 판단했습니다.




시스템 구조도 최종본

두번째 시스템 구조도가 완성된 시점에는 요구사항 수집 및 분석은 거의 마무리 된 상태였습니다.

시스템 구조도의 최종본은 시스템 설계를 완료하면서 함께 완성되었습니다.

불확실했던 부분들이 확실히 지고, 구체적인 기능들이 명세화 되면서 실제 구현해야 될 시스템의 모습이 Diagram위에 그 모습을 드러내기 시작했습니다.


완성된 시스템의 구조도는 다음과 같습니다.

[그림 3. 최종 시스템 구조도 - v3]


마지막 시스템 구조도에서는 일단 Log Pre-processor가 MQ Consumer로 이름이 바뀌었습니다.

실제 기능에 맞는 직관적인 이름을 주는 것이 개발중에 이루어지는 커뮤니케이션에 더 효율적일 것이라는 판단때문이었습니다. 

그리고 두번째 시스템 구조도에 있었던 Log Filter와 WebSocket 모듈을 모두 빠졌습니다.

실시간 이벤트 패턴 검색 기능 및 알람 기능개발 비용 및 일정 때문에 우선순위에서 계속 밀리다가 결국에는 기능 자체를 없에는 것으로 결정되었습니다. (고도화 계획에 포함)


초기에 계획에 없다가 마지막에 추가된 모듈도 있습니다.

새로 추가된 Log Composer는 Transaction에 대한 통계를 내기 위한 모듈입니다. 

이 모듈이 추가되기 전까지 E2E-Monitor는 하나의 Request에 대한 처리 결과를 하나의 데이터로 취급했었습니다.

예를 들어 "/user/join"이라는 하나의 Request에 대한 처리 과정을 span이라고 부르고, 이 span에 대한 통계 데이터를 보여주기로 했습니다.

하지만, 여러차례 논의 과정을 거치면서 span에 대한 정보만으로는 전체적인 서비스의 흐름을 파악하기 힘들다는 결론을 내리게 됩니다.

이제 E2E-Monitor는 하나의 논리적인 Action을 구성하는 여러개의 span을 하나의 Transaction으로 보고, 이 Transaction을 기준 데이터로 사용하기로 합니다.

Transaction이라는 것이 여러개의 span들로 구성되어 있기 때문에 span들을 Grouping하고 Transaction에 대한 정보를 추가로 생산해 내기 위해서는 새로운 모듈이 필요하게 되었고, 그래서 추가된 모듈이 Log Composer입니다.

Log Composer는 Span 데이터를 Grouping하고 재구성해서 새로운 Transaction 정보를 만들어내서 저장소에 저장하는 역할을 합니다.



PostgreSQL 도입 이유

Log Composer가 사용하는 저장소를 보시면 Elastic Search와 함께 PostgreSQL이 있는 것을 보실 수 있습니다.

두번째 시스템 구조에서는 없던 PostgreSQL을 새로 추가한 이유는 통계 데이터를 저장하기 위해서 입니다.

단순 환경 설정 값들과, 영구적으로 보관해야 하는 Transaction 통계 데이터를 저장하기 위한 공간으로, 고객사에서 기존에 사용하고 있던 PostgreSQL사용하기로 했습니다.



최종 시스템 구조도에서는 변경된 구조를 반영한 것 뿐만 아니라, 각 모듈에서 실제로 사용할 구체적인 솔루션들에 대한 내용도 추가되었습니다.


LogStash 도입 이유

Log Collector에서 사용한 LogStash는 대상 시스템과의 Coupling을 최소화하기 위해 사용했습니다.

대상 시스템에서 바로 다른 저장소로 데이터를 전송하는 것보다는, 대상 시스템은 추적 정보를 파일에 적게 하고, 파일에 적힌 데이터는 다른 프로그램이 읽어서 전송하게 함으로써, E2E-Monitor와 대상 시스템간의 Coupling이 줄 수 있도록 설계했습니다.

그리고 Log파일을 읽어서 Message Queue로 전송하는 일은 LogStash가 하도록 했습니다.

LogStash는 Fleuntd나 기타 다른 솔루션으로 대체가 가능한데, 저희에게는 가장 손이 익은 솔루션이 LogStash라서 선택하게 되었습니다.


Kafka 도입 이유

Message Queue는 Kafka를 사용하기로 했는데, 가장 많이 사용되고 있는 Rabbit MQ 대신 Kafka를 사용한 이유는, Kafka가 실시간 대용량 분산 Message 처리에 특화되어 있기 때문이었습니다.

그리고 이미 고객사에서 Message Queue로 Kafka를 사용하고 있기 때문에 도입하는데 아무런 문제가 없었습니다.


시스템 구조도 최종본은 실제 시스템 개발이 들어가기 바로 전에 완성되었습니다.

그리고 다행히도 실제 개발 중에 구조도가 바뀌진 않았습니다. 

만약 개발 도중 시스템 구조가 바뀌었다면, 아마도 개발 일정을 맞추지 못하는 사태가 생겼을 것 같습니다.



마무리, 진짜 프로젝트 회고

이 글을 마지막으로, E2E-Monitor 개발 프로젝트 회고 글을 모두 마쳤습니다.

이번 프로젝트는 2개월이라는 짧은 시간 동안 개발 인력 5명이라는 투입된 프로젝트였습니다.

당초 예상했던 MM이 9MM이었던 점을 감안하면, 결론적으로는 1MM이 초과되었는데, 이부분은 신입 인력 교육에 투자한 것으로 생각하기로 했습니다. (손해난 부분을 이런식으로 대충 퉁치고 넘어가기로.... ㅠ.ㅠ)

사실 3명이서 3개월 정도로 예상한 프로젝트인데, 기간이 2개월로 줄면서 어쩔 수 없이 인력을 추가 투입한 케이스라고 보시면 될 것 같습니다.

여러가지 프로젝트를 많이 해보셨던 분들은, "3개월에 3명이서 할 일""5명을 투입해서 2개월만에 끝내라"는 것이 그렇게 계산대로 쉽게 되는 일이 아니라는 것을 잘 아실겁니다.

Man-Month의 함정이라고도 하죠.

어찌되었건 기간은 촉박한데, 인력은 충분한 상황이었습니다.

그래도 어찌어찌 해서 기간안에 프로젝트를 일정대로 진행하고 완료 할 수 있었던 것은, 무리한 일정과 개발 계획 때문에 매일 매일 새벽까지 야근하면서도 웃으면서 즐겁게 일했던, 똑똑하면서도 오덕스럽고, 그리고 순박했던 우리 개발자들 때문이라고 생각합니다.

이 글을 빌려서, 함께 했던 우리 개발자들에게 감사의 뜻을 전하고 싶습니다.

김민기 부장 <smoon@embian.com>: Back-end 설계 / 개발

김정 대리 <jung@embian.com>: Back-end / API 개발

조석현 과장 <zoe@embian.com>: Front-end 개발 / 산출 문서 작성

한종민 사원 <hjm@embian.com>; Front-end 개발

그리고 저는 (주)엠비안 개발2본부장 박재영 <yam@embian.com> 이었습니다.


지금까지 긴글 읽어 주셔서 감사합니다. 


* E2E-Monitor가 실제 작동되는 모습을 보시고 싶으신 분들은 "E2E 데모"를 방문하시면 확인하실 수 있습니다.



Posted by 알 수 없는 사용자
,