사용자 정의 알림 설정하기
Scouter에 대해 강조하는 것 중 하나가 "Scouter는 개발자가 가장 잘 활용 할 수 있는 APM이다" 인데요, 그 이유가 압축 해제만으로 설치가 끝나고 소규모 장비의 일부 자원으로도 잘 돌아간다는 점도 있지만 가장 중요하게 생각하는 부분은 바로 개발자에게 주어진 자유도입니다.
특히 스크립트 방식의 플러그인을 통하면 개발자가 원하는 정보를 소스의 수정없이 Scouter의 프로파일이나 xlog에 남길 수 있는데요, 이번 장에서는 이와 유사한 방식으로 스크립트를 통해 자유도 높은 알림 설정할 수 있는 기능을 소개하고자 합니다.
1. 알람 플러그인 설치 |
Scouter의 알림은 클라이언트 화면에서도 볼 수 있지만 플러그인을 설치하여 이메일이나 메신저로 확인하는 것이 좋습니다.
Scouter는 email, slack, line 메신저등의 확장 플러그인을 가지고 있으며 scouter-project의 github 페이지에서 확인할 수 있습니다.
확장 플러그인 설치는 아래 순서로 진행합니다.
- 플러그인 릴리즈 제공하는 파일들을 모두 다운로드 받는다.
- 예를 들어 slack 플러그인을 설치하려면 scouter-server-plugin-alert-slack의 릴리즈 페이지에 있는 파일을 모두 다운로드 받는다.
- scouter collector server가 설치된 디렉토리 아래의 lib 디렉토리로 받은 파일들을 모두 복사한다.
- scouter collector를 재기동 한다.
※ 설치된 plugin이 제대로 적용되는지는 collector 시작시 남는 로그를 통해 확인할 수 있습니다.
2. 기본 제공 알림 |
Scouter에서는 간편하게 설정할 수 있는 몇가지 기본 알림을 제공합니다. 목록은 아래와 같습니다.
- CPU 알림 설정 옵션
- Host agent의 옵션을 통해 설정할 수 있있음
- cpu_alert_enabled : cpu 알림을 활성화하거나 비활성화(기본 : true)
- cpu_warnig_pct : cpu waring 레벨 알림의 퍼센트(정수로 설정)
- cpu_fatal_pct : cpu fatal 레벨 알림의 퍼센트(정수로 설정)
- cpu_check_period_ms : 어느 기간동안 cpu를 체크할지를 지정
- cpu_waring_history, cpu_fatal_history : 각 레벨에 설정한 값의 초과가 몇회 발생하였을때 알림을 알릴지를 설정
- 예를 들어 cpu_fatal_pct가 90%이고 cpu_check_period_ms가 5분(300000ms), cpu_fatal_history가 3이라면 CPU가 최근 5분간 90%를 3회 넘는 경우 알림을 발송하게 됨
- cpu_alert_interval_ms : 설정 시간동안 동일한 알림을 발송하지 않음
- Memory 알림 설정 옵션
- mem_alert_enabled=false
- mem_alert_interval_ms=30000
- mem_warning_pct=80
- mem_fatal_pct=90
- Disk 사용량 알림 설정 옵션
- disk_alert_enabled=true
- disk_warning_pct=70
- disk_fatal_pct=90
3. 알림 스크립팅을 통한 고급 알림 제어 |
알림 스크립팅은 클라이언트 object view에서 collector의 컨텍스트 메뉴를 통해서 접근이 가능합니다.
아래 그림에서 Customizable Alert 메뉴를 보면 여러가지 항목이 보이는데 이는 scouter로 전송되는 카운터들을 나타냅니다. 알림은 모든 카운터에 대해 설정할 수 있으며 또한 이를 조합하여 사용할 수도 있습니다.
그러면 이해를 돕기 위해 응답시간에 대한 알림을 설정해 보도록 하겠습니다. 위 메뉴에서 Elapsed90% 항목을 선택합니다.
이러면 아래와 같은 화면이 열립니다.
※ Elapsed90% 카운터는 상위 90%의 응답시간. 평균 응답시간은 이상 현상을 발견하는데 민감성이 떨어지므로 scouter에는 90% 응답시간 카운터도 제공
왼쪽은 스크립트를 작성하는 영역, 오른쪽은 스크립트에 전달된 두개의 파라미터 $counter와 $$에 대한 도움말 화면입니다. 그리고 왼쪽 아래 영역은 이 알림에 대한 체크 주기등에 대한 설정이고 오른쪽 아래 영역은 알림 스크립트를 저장했을때 제대로 컴파일이 되는지 등을 알려주는 콘솔창입니다.
먼저 왼쪽 아래 영역의 "Alert Configuration"에서는 알림을 어떤 주기로 체크하고 이 값을 몇개나 보관할지를 설정합니다.
- history_size=150
- scouter의 카운터 값들은 2초에 하나씩 수집이 됩니다. 즉 여기에 150이라고 설정된 부분은 최근 150개까지 보관하라는 것이며 결국은 과거 300초의 데이터가 보관이 됩니다.
- 이 정보는 알림 스크립트를 작성할 때 과거데이터와 비교하기 위해 사용됩니다.
- slient_time=300
- 초단위로 설정하는 snooze 시간입니다. 즉 한번 발생한 알림은 설정된 값인 300초간 다시 발송하지 않습니다.
- check_time=2
- 초단위의 값입니다. 2초 간격으로 위 알림 스크립트를 실행하라는 설정입니다. 측정하고자 하는 값의 성격에 따라 적절히 조절하면 됩니다.
이제 알림 스크립팅을 해보도록 하겠습니다.
파라미터로 전달되는 두가지 오브젝트를 적절히 활용하여 스크립팅을 하게 됩니다.
- $counter : 카운터의 값을 얻어오거나 알림을 발송할 수 있습니다.
- $$ : 스크립팅에 필요한 몇가지 유틸리티들을 제공하는 오브젝트입니다.
스크립팅은 Java 문법을 사용하는데 몇가지 제약 사항이 있습니다.
- import 구문을 사용할 수 없으므로 java.lang에 포함된 클래스 외에는 패키지명을 포함하여 선언하여야 합니다.
- varargs를 사용할 수 없습니다. varargs를 받는 메소드에 파라미터를 전달해야 한다면 배열로 만들어 전달하여야 합니다.
일단 아래 조건으로 알림을 발송 해보겠습니다.
- 90% 응답시간이 2000ms를 넘는 경우 fatal 알림을 발송한다.
[alert1.java]
float value = $counter.getFloatValue();
if(value > 2000) {
$counter.fatal("Alert title", "msg: Elapsed is over 2000ms");
}
위 코드를 저장하고 응답시간이 2000ms를 넘게되면 클라이언트 화면에서 아래와 같은 알림을 확인할 수 있습니다. 보통은 화면에서 확인하기 보다는 알림이 연동된 메신저 등을 통해 내용을 확인하게 됩니다.
동작을 확인하였으니 알림 발송 기준에 몇 가지 조건을 더 추가하여 개선해 보도록 하겠습니다.
- 알림 메시지에 현재 값과 objName과 objType 정보를 추가로 기록
- 야간 등 트래픽이 적을때는 응답시간이 늦은 한 두개의 요청 만으로도 알림이 발생할 수 있으므로 TPS가 10 미만인 경우는 알림을 발생시키지 않도록 힘
- 알림 메시지에 현재 TPS도 기록
- $counter.getFloatValue(String counterName) 메소드로 다른 카운터 항목도 가져올 수 있습니다. TPS 값을 가져오려면 $counter.getFloatValue("TPS") 를 사용
※ counterName은 scouter client에서 해당 counter 차트를 선택하면 아래쪽 status bar에 표시됩니다.
[alert2.java]
String objType = $counter.getObjType();
String objName = $counter.getObjName();
float value = $counter.getFloatValue();
float tps = $counter.getFloatValue("TPS");
String title = "Elapsed time alert";
String message = "Elapsed is over 2000ms\n";
message += "[current value] " + value + "ms\n";
message += "[objType] " + objType + "\n";
message += "[objName] " + objName + "\n";
message += "[TPS] " + tps;
if(value > 2000 && tps > 10.0) {
$counter.fatal(title, message);
}
소수점까지 보이는 숫자가 조금 보기 좋지 않으니 $$.formatNumber() 메소드를 사용해서 조금만 더 수정해보겠습니다.
[alert3.java]
String objType = $counter.getObjType();
String objName = $counter.getObjName();
float value = $counter.getFloatValue();
float tps = $counter.getFloatValue("TPS");
String title = "Elapsed time alert";
String message = "Elapsed is over 2,000ms\n";
message += "[current value] " + $$.formatNumber(value, 0) + "ms\n";
message += "[objType] " + objType + "\n";
message += "[objName] " + objName + "\n";
message += "[TPS] " + $$.formatNumber(tps);
if(value > 2000 && tps > 10.0) {
$counter.fatal(title, message);
}
만약 컴파일 에러가 발생하면 Console 창에 "Alert rule compile error" 라고 표시되며 정상적으로 컴파일 되어 로드되면 "Alert rule detected" 라고 표시됩니다.
counter 값을 과거의 데이터와 비교해야 하는 경우도 있습니다. 이런 경우에는 $counter.getAvg(int fromAgoSec, int durationSec)를 사용합니다. 예를 들어 아래와 같은 요건으로 알림을 작성하고자 한다면 이렇게 작성합니다. Customizable alert의 TPS 메뉴를 열어 작성한 스크립트 예시입니다.
- 만약 과거 3분 이전의 30초 평균 TPS보다 현재 시점의 30초 평균 TPS가 1.5배 높다면 fatal 알림을 발송
[alert4.java]
String objType = $counter.getObjType();
String objName = $counter.getObjName();
float avgTpsCurrent = $counter.getLatestAvg(30); //latest 30s avg
float avgTps3minAgo = $counter.getAvg(180+30, 30); //3min ago 30s avg
String title = "TPS fluctuation alert";
String message = "TPS is highly(over 1.5x) incresed in 3min\n";
message += "[TPS current] " + $$.formatNumber(avgTpsCurrent) + "\n";
message += "[TPS 3min ago] " + $$.formatNumber(avgTps3minAgo) + "\n";
message += "[objType] " + objType + "\n";
message += "[objName] " + objName + "\n";
if(avgTpsCurrent > avgTps3minAgo * 1.5) {
$counter.fatal(title, message);
}
여기까지 간단한 예제들을 보여드렸는데, 여기 나온 것들을 조금만 더 조합하면 훨씬 더 멋진 알림 조건을 만들 수 있을거라 생각합니다.
알림 설정은 한번에 끝내는 것이 아니고 모니터링 하면서 민감도를 지속적으로 조절하여야 되는것 아시죠?
너무 의미없이 자주 오는 알림은 아무도 보지 않고, 그렇다고 중요한 시점에 알람이 발송되는 것을 놓쳐서도 안됩니다. 지금까지 소개한 알림 스크립팅을 활용한다면 다양한 카운터의 값들과 조건을 종합적으로 판단하여 최적화된 알림을 발송할 수 있을 겁니다.
마지막으로 알림에 간단한 차트 링크를 첨부하는 예제입니다.
scouter webapi에 간단한 web chart 기능이 있습니다. 이 web chart를 링크로 제공하는 예제이며, 조금 복잡하지만 차근히 보시면 이해가 될 겁니다. 특별히 더 설명드리지는 않겠습니다.
알림 메시지에 알림이 발생한 시점의 차트, 현재 시점의 차트, 그리고 일일 차트에 대한 링크를 넣어보도록 하겠습니다.
여기서는 일단 webapi server를 따로 띠우지 않고 collector에 embedded된 상태로 사용하겠습니다. 이를 위해서는 collector에 net_http_server_enable 과 net_http_api_enabled 옵션이 true가 되어 있어야 합니다. 이를 설정하고 collector를 재기동 하면 6180 port를 통해 webapi에 접근할 수 있습니다.
(만약 webapi server를 사용하고 있다면 6188 port를 통해 접근하게 됩니다.)
[alert5.java]
String counterName = "Elapsed90%";
String objType = $counter.getObjType();
String objName = $counter.getObjName();
float value = $counter.getFloatValue();
float tps = $counter.getFloatValue("TPS");
String widgetUrl = "http://my-scouter-webapi-ip:6180/widget/simple/counter.html?source=";
java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("yyyyMMdd");
long now = System.currentTimeMillis();
String today = dateFormat.format(new java.util.Date(now));
String yesterday = dateFormat.format(new java.util.Date(now-24*60*60*1000));
String counterApi = counterName + "/ofType/" + objType;
counterApi += "?startTimeMillis=" + (now-600*1000L);
counterApi += "&endTimeMillis=" + now;
String counterApiLatest = counterName + "/latest/600/ofType/" + objType;
String dayStatApi = "stat/" + counterName + "/ofType/" + objType;
dayStatApi += "?startYmd=" + yesterday;
dayStatApi += "&endYmd=" + today;
String title = "Elapsed time alert";
String message = "Elapsed is over 2,000ms\n";
message += "[current value] " + $$.formatNumber(value, 0) + "ms\n";
message += "[objType] " + objType + "\n";
message += "[objName] " + objName + "\n";
message += "[TPS] " + $$.formatNumber(tps) + "\n";
message += "[On-time chart]\n";
message += widgetUrl + java.net.URLEncoder.encode(counterApi) + "\n";
message += "[Current chart]\n";
message += widgetUrl + java.net.URLEncoder.encode(counterApiLatest) + "\n";
message += "[Daily chart]\n";
message += widgetUrl + java.net.URLEncoder.encode(dayStatApi);
if(value > 2000 && tps > 10.0) {
$counter.fatal(title, message);
}
알림이 발생하면 다음과 같은 알림 메시지를 받게 됩니다.
이제 알림으로 전송된 메시지의 링크를 누르면 아래와 같은 차트를 볼수 있습니다.
출처 : http://gunsdevlog.blogspot.com/2018/05/scouter-customizable-alert.html
'IT 이야기 > Scouter' 카테고리의 다른 글
Scouter Paper 설치 및 활용 (0) | 2019.12.13 |
---|---|
Scouter XLog 활용 - 상세기능 (0) | 2019.12.13 |
Scouter Active Service와 XLog (0) | 2019.12.12 |
Scouter 기본 항목 모니터링(2/2) (0) | 2019.12.12 |
Scouter 기본 항목 모니터링(1/2) (0) | 2019.12.12 |
댓글