1. 연동 시작하기 — 어느 쪽을 쓸지와 인증
이 가이드로 하는 일
APM 이 모은 데이터를 다른 시스템에서 가져다 씁니다. 사내 포털에 성능 지표를 함께 띄우거나, 보고서를 자동으로 만들거나, 다른 감시 도구와 연동할 때 씁니다. 콘솔 화면에서 볼 수 있는 그래프는 거의 모두 API 로도 받을 수 있습니다.
응답은 모두 JSON 입니다.
먼저 고를 것 — JSON API 와 PromQL 중 어느 쪽인가
APM 은 성격이 다른 두 가지 연동 방법을 제공합니다. 이 가이드의 1~6장이 하나이고, 7장의 PromQL 이 다른 하나입니다. 인증 방법부터 응답 형식까지 다르므로 시작하기 전에 어느 쪽인지 정하십시오.
한 줄 판단 — 데이터를 바꿔야 하면 JSON API, 그래프로 보거나 계산해야 하면 PromQL 입니다.
| JSON API (1~6장) | PromQL (7장) | |
|---|---|---|
| 할 수 있는 일 | 조회 + 등록·수정·삭제 | 조회만 |
| 인증 | 세션 쿠키 (로그인 API 로 받습니다) | 세션 쿠키도 되고, Metric Explorer 화면은 API 접근 키를 씁니다 |
| 응답 형식 | APM 전용 JSON | 표준 Prometheus 형식 |
| 대상 지정 | 경로에 그룹·IP·인스턴스를 적습니다 | 라벨 matcher ({instance_id="…"}) |
| 집계 | mean · sum · max · min 네 가지 | rate · topk · quantile · *_over_time 등 |
| 시리즈 간 계산 | 안 됩니다 — 받아서 직접 계산합니다 | 쿼리 안에서 됩니다 (100 - cpu_idle) |
| 구성 정보 조회 | 됩니다 (2장) | 안 됩니다 — 지표만 |
| 사용자·권한 관리 | 됩니다 (4~6장) | 안 됩니다 |
JSON API 를 쓰는 경우
- 설정을 바꿔야 할 때 — 사용자 등록, 그룹 권한 변경, 애플리케이션 그룹 관리. PromQL 로는 할 수 없습니다.
- 무엇을 모니터링 중인지 알아야 할 때 — 그룹·인스턴스 목록 조회(2장)
- 사내 포털·업무 시스템에 지표 몇 개를 숫자로 얹을 때 — 값 하나를 받아 그대로 쓰면 되므로 쿼리 문법을 익힐 필요가 없습니다
- 정해진 지표를 정해진 기간으로 뽑아 보고서를 만들 때
PromQL 을 쓰면 무엇이 좋은가
1. Grafana 에 그대로 붙습니다. 응답이 표준 Prometheus 형식이라 Grafana 의 Prometheus 데이터소스에 APM 주소만 넣으면 끝입니다. 어댑터를 만들 필요가 없고, 이미 쓰던 Grafana 대시보드 자산을 그대로 재사용할 수 있습니다. 별도의 Prometheus 서버·익스포터·스크레이프 설정도 필요 없습니다 — APM 한 곳에서 수집·저장·질의가 끝납니다.
2. 계산을 서버가 대신합니다. "GC 가 잦은 상위 5개 인스턴스", "CPU 사용률(= 100 - idle)",
"힙 1GB 초과 인스턴스만" 같은 조건을 쿼리 한 줄로 표현합니다. JSON API 로 하려면 전체를
받아 와서 연동 프로그램이 직접 계산해야 합니다 — 코드도 늘고 주고받는 데이터도 늘어납니다.
topk(5, rate(jvm_gc_gcCount[5m])) # GC 빈도 상위 5개
avg by (instance_id) (jvm_heap_heapUsed) # 인스턴스별 평균 힙
100 - cpu_idle # CPU 사용률
3. 지표를 몰라도 찾을 수 있습니다. 메트릭 이름·라벨 목록을 조회하는 API 가 있어 어떤
데이터가 있는지 뒤져 볼 수 있습니다. JSON API 는 {ns} · {name} 을 미리 알아야 합니다.
브라우저에서 쓰는 Metric Explorer 화면도 함께 제공됩니다.
4. 라벨로 자릅니다. instance_id · ip_addr · agent_type 같은 라벨로 조건을 걸어
원하는 대상만 뽑고 원하는 기준으로 묶습니다. JSON API 는 경로에 대상을 적는 방식이라
"WAS 이면서 특정 그룹" 같은 조합이 어렵습니다.
5. rate · increase 가 빠르고 정확합니다. APM 은 수집 시점에 변화량(delta)으로
저장하므로 쿼리할 때는 단순 합산만 합니다. 표준 Prometheus 의 counter reset 보정 문제도
없습니다.
바꿔 말하면 이런 때는 PromQL 이 아닙니다 — 설정을 바꿔야 하거나(등록·수정·삭제), 모니터링 대상 구성 목록이 필요할 때입니다. 그건 JSON API 만 됩니다.
함께 쓰기도 합니다
두 방법은 배타적이지 않습니다. 흔한 조합은 JSON API 로 대상 목록을 받아 화면을 구성하고, 그 대상의 그래프는 PromQL 로 그리는 것입니다. 인증은 각각 따로 받으면 됩니다.
1~6장의 인증 — API 키를 헤더에 넣는 방식이 아닙니다. 먼저 로그인 API 를 호출해 세션 쿠키를 받고, 이후 요청에 그 쿠키를 함께 보냅니다.
1) POST /monitoring/api/auth/login → 응답 헤더의 쿠키(__KSMSID__)를 받는다
2) GET /monitoring/api/… → 그 쿠키를 담아 요청한다
쿠키를 빠뜨리면 데이터 대신 로그인 요구 응답이 옵니다. 연동 프로그램을 만들 때는 쿠키를 보관했다가 재사용하고, 만료되면 다시 로그인하도록 만드십시오.
이 가이드의 구성
| 장 | 무엇을 다루나 |
|---|---|
| 1장 (이 장) | 어느 쪽을 쓸지 고르는 기준, 로그인·인증과 확인 방법 |
| 2장 | 무엇을 모니터링 중인지 — 그룹·인스턴스 목록 |
| 3장 | 지표 데이터 조회 — 이 가이드의 핵심 |
| 4~6장 | 사용자·그룹·권한 관리 (조회뿐 아니라 등록·변경도 가능) |
| 7장 | 표준 PromQL 로 지표 조회 — Grafana·외부 도구 연동 (인증 방식이 다릅니다) |
보통 2장에서 대상 이름을 얻고 3장에서 그 대상의 지표를 조회하는 순서로 씁니다.
모든 API 에 공통인 것
응답 형식 — 성공·실패 모두 status 로 결과를 알려 줍니다. HTTP 상태 코드가 아니라
본문의 status 를 봐야 합니다.
{ "status": 200, "result": … } // 성공 — result 에 데이터가 들어 있습니다
{ "status": 401 } // 로그인이 필요합니다 (쿠키 누락·만료)
조회 API 는 result 에 데이터를 담고, 등록·수정·삭제 API 는 { "status": 200 } 만 돌려줍니다.
시각 표기 — 문서에 나오는 created · firstDate · registered 같은 값은 모두
Unix Epoch 밀리초입니다(1970-01-01 UTC 기준). 초 단위가 아니므로 1000 으로 나눠 쓰십시오.
한글 처리 — 요청·응답 모두 UTF-8 입니다. Content-Type 에 charset=UTF-8 을 붙이지
않으면 한글 이름이 깨질 수 있습니다.
이력이 남지 않고 즉시 반영됩니다. 연동 프로그램을 만들 때 는 조회로 먼저 확인하고, 시험 환경에서 검증한 뒤 운영에 올리십시오.
이 장에서는 로그인을 POSTMAN · curl · Java 라이브러리 세 가지로 확인하는 방법을 차례로 보여 줍니다. 쓰는 도구에 맞는 것만 보면 됩니다.
사용자 인증 관련 API
로그인 요청 항목
요청
| 항목 | 설명 |
|---|---|
| URL | /monitoring/api/auth/login |
| HTTP METHOD | POST |
| Content-Type | application/json |
| 파라미터 | 없음 |
| POST BODY | { "userId": "omadm", "password": "2fefb853a18e46159682c77325379156bd56cd897651cace119a31500381167a" } |
- userId : 사용자 ID
- password : SHA256으로 암호화한 패스워드를 HEX로 인코딩한 텍스트를 소문자로 변경한 문자열입니다.
- ex) https://www.xorbin.com/tools/sha256-hash-calculator 사이트에서 변환한 Hash값을 사용
응답
| 항목 | 설명 |
|---|---|
| Response Body | Response의 JSON 문자열의 내용은 다음 항목과 같습니다. |
| 정상 로그인 | { "status": 200, "result": { … } } — result 에는 콘솔용 브랜드 설정이 담깁니다 |
| 패스워드 오류 | { "status": 500, "errorCode": 102020, "reason": "API_AUTH_PASSWORD_MISMATCH_ERROR" } |
로그인 되어 있는지 체크
요청
| 항목 | 설명 |
|---|---|
| URL | /monitoring/api/auth/check |
| HTTP METHOD | GET |
| Content-Type | application/json |
| 파라미터 | 없음 |
응답
| 항목 | 설명 |
|---|---|
| Response Body | Response의 JSON 문자열의 내용은 다음 항목과 같습니다. |
| 로그인되어 있음 | { "status": 200 } |
| 로그인되어 있지 않음 | { "status":500, "errorCode":102050, "reason":"API_AUTH_NOT_LOGIN" } |
POSTMAN을 이용한 로그인 API 처리 확인 방법
사용자 인증 처리를 위한 Http Method, URL, Content-Type 설정

POST와 URL을 설정한다 Content-Type을 설정한다
로그인을 위한 사용자 정보 입력

POST Body를 설정한다
로그인 요청 및 결과 확인

응답을 확인한다 ‘Send’를 클릭합니다.
로그인 확인을 위한 URL 설정 후 요청/응답을 확인.

URL설정후 Send를 클릭한다 응답을 확인한다
CURL을 이용한 로그인 처리 API 확인 방법
로그인 요청 및 응답확인
$ curl -i -H "Content-Type: application/json" \
-d '{"userId": "omadm", "password": "2fefb853a18e46159682c77325379156bd56cd897651cace119a31500381167a"}' \
http://192.168.23.190/monitoring/api/auth/login
HTTP/1.1 200
Set-Cookie: __KSMSID__=05908742-bb0d-473b-90c1-f8d8413d7d5a;Path=/;HttpOnly
Set-Cookie: OMAPMJSESSIONID=BFAAC2FBFE828AF883F4A5A73AB8D681.khan11; Path=/monitoring; HttpOnly
Set-Cookie: KHANUSER=x3u6los95jgltq; Path=/; Max-Age=2147483647
Content-Type: application/json;charset=UTF-8
Content-Length: 352
{"status":200,"result":{"brandConfig":{ … },"start.page":""}}
응답 헤더의 Set-Cookie 중 __KSMSID__ 가 세션 쿠키입니다(앞뒤로 밑줄 두 개씩).
이 값을 다음 API 요청에 함께 보내야 요청이 처리됩니다. 나머지 쿠키
(OMAPMJSESSIONID · KHANUSER)는 연동에 쓰지 않습니다.
본문의 result 에는 콘솔 화면이 쓰는 브랜드 설정이 함께 실려 옵니다. 연동 프로그램은
status 값만 보면 됩니다.
로그인 확인 요청 및 응답
아래 로그인 확인 API에서 로그인 요청에서 응답받은 Cookie값을 설정하여 요청하여야 API 처리가 됩니다.
- 로그인 되어 있는 경우
$ curl -i --cookie "__KSMSID__=05908742-bb0d-473b-90c1-f8d8413d7d5a" \
-H "Content-Type: application/json" \
http://192.168.23.190/monitoring/api/auth/check
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Content-Length: 14
{"status":200}
- 로그인되어 있지 않은 경우
$ curl -i -H "Content-Type: application/json" \
http://192.168.23.190/monitoring/api/auth/check
HTTP/1.1 500
Content-Type: application/json;charset=UTF-8
Content-Length: 63
{"status":500,"errorCode":102050,"reason":"API_AUTH_NOT_LOGIN"}
HTTP Client 라이브러리를 이용한 로그인 처리
maven dependency 지정
Apache Commons Http Client 모듈을 사용하여 연동하고자 할 때, 다음과 같이 maven pom.xml 파일에 Dependency를 지정합니다.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
</dependency>
로그인 처리 예제 코드
아래는 HttpClient 모듈을 사용한 로그인과 로그인 상태 체크를 위한 간략한 예제 코드입니다.
주의할 점은 HttpClient 객체에 BasicCookieStore를 설정하여 Login 응답의 쿠키를 계속 사용한다는 것입니다.
package test;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class TestHttpClientCookie {
public static void main(String args[]) throws Exception {
String LOGIN_JSON_STRING = "{\n" +
"\t\"userId\": \"omadm\", \n" +
"\t\"password\": \"2fefb853a18e46159682c77325379156bd56cd897651cace119a31500381167a\"\n" +
"}";
// Cookie Store
BasicCookieStore cookieStore = new BasicCookieStore();
DefaultHttpClient client = new DefaultHttpClient();
client.setCookieStore(cookieStore);
// HTTP POST Login
HttpPost httpLoginPost = new HttpPost("http://192.168.23.14/monitoring/api/auth/login");
StringEntity requestEntity = new StringEntity(
LOGIN_JSON_STRING,
ContentType.APPLICATION_JSON);
httpLoginPost.setEntity(requestEntity);
HttpResponse loginResponse = client.execute(httpLoginPost);
System.out.println("Send Login Request");
if (loginResponse.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ loginResponse.getStatusLine().getStatusCode());
}
BufferedReader loginBufferedReader = new BufferedReader(
new InputStreamReader((loginResponse.getEntity().getContent())));
String loginOutput;
System.out.println("Login Result from Server ....");
while ((loginOutput = loginBufferedReader.readLine()) != null) {
System.out.println(loginOutput);
}
HttpGet checkRequest = new HttpGet("http://192.168.23.14/monitoring/api/auth/check");
checkRequest.setHeader("Content-Type", "application/json");
HttpResponse checkResponse = client.execute(checkRequest);
System.out.println("Send Login Check Request");
if (checkResponse.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ checkResponse.getStatusLine().getStatusCode());
}
BufferedReader checkBufferedReader = new BufferedReader(
new InputStreamReader((checkResponse.getEntity().getContent())));
String checkOutput;
System.out.println("Login Check Result from Server .... ");
while ((checkOutput = checkBufferedReader.readLine()) != null) {
System.out.println(checkOutput);
}
}
}
실행 결과
예제 코드의 실행 결과는 다음과 같습니다.
Send Login Request
Login Result from Server ....
{"status":200}
Send Login Check Request
Login Check Result from Server ....
{"status":200}
Health Check
APM 서버가 살아 있는지 확인합니다. 로그인하지 않고 부를 수 있는 유일한 API 라, 로드밸런서나 감시 도구의 상태 점검 대상으로 씁니다.
정상이면 {"status": 200} 을 반환합니다.
| 항목 | 설명 |
|---|---|
| URL | /monitoring/api/check/healthCheck |
| URL 요청 예시 | /monitoring/api/check/healthCheck |
| HTTP METHOD | GET |
| Content-Type | application/json; charset=UTF-8 |
| Body | |
| Response | {"status": 200} |