제니퍼 APM

다운로드 4
업데이트 2026. 10. 30.

쿼리 명령어

화면은 지금 무슨 일이 일어나는지 보기에 좋지만, 하루치 지표를 기준선과 비교하거나 이상 구간과 정상 구간의 애플리케이션을 나란히 놓는 일은 쿼리가 낫습니다. 이 앱은 JENNIFER 데이터를 읽는 쿼리 명령어 9개를 더합니다.

  • 콘솔 명령어 7개 - JENNIFER 콘솔 접속 프로파일(콘솔 계정)로 콘솔 화면과 같은 데이터를 읽습니다. 성능 이상의 원인을 좁혀 가는 순서대로 쓰도록 만들어졌고, AI 에이전트 원인 분석도 이 명령어들을 씁니다. 앱 1.1.2610.0 이상에서 제공합니다
  • 토큰 명령어 2개 - JENNIFER APM 접속 프로파일(Open API 토큰)로 트랜잭션과 실행 중인 서비스를 읽습니다

명령어별 옵션과 출력 필드 전체는 스토어의 확장 명령어 탭에 있습니다. 이 페이지는 명령어를 어떤 순서로 엮어 쓰는지를 다룹니다.

명령어 개요

명령어프로파일단계하는 일기간
jennifer-instances콘솔대상도메인과 인스턴스 목록. 기간을 주면 그 기간에 데이터를 보낸 인스턴스(지금은 중지된 것 포함)생략하면 지금 등록된 인스턴스
jennifer-metrics콘솔감지인스턴스별 지표 시계열(5분 또는 1시간 버킷). 한 행이 시각 × 인스턴스 × 지표 하나기본 1시간, 최대 31일
jennifer-problems콘솔판정JENNIFER가 스스로 판정한 문제의 분·유형·인스턴스별 건수기본 1시간, 최대 1일
jennifer-app-summary콘솔범위구간별 애플리케이션 호출·에러·응답시간 요약기본 1시간, 최대 1일
jennifer-errors콘솔범위인스턴스별 에러 유형별 건수(기간 합계)기본 1시간, 최대 31일
jennifer-xview콘솔증거개별 트랜잭션(X-View 점). 끝난 트랜잭션 하나가 한 행기본 10분, 최대 1일
jennifer-profile콘솔원인트랜잭션 하나의 호출 프로파일(메서드, SQL, 외부 호출, 에러, GAP)트랜잭션의 수집 시각으로 찾음
jennifer-apm-transaction-time토큰-기간 안에 끝난 트랜잭션의 구간별 소요시간과 에러 유형duration 또는 from·to 필수
jennifer-apm-active-service-list토큰-지금 실행 중인 서비스 목록현재 시점

토큰 명령어로는 콘솔 명령어가 읽는 통계, 문제 판정, 애플리케이션 요약, 트랜잭션 프로파일을 읽을 수 없습니다. 원인 분석에는 콘솔 명령어를 씁니다.

원인 분석 흐름

콘솔 명령어는 대상 → 감지 → 판정 → 범위 → 증거 → 원인 순서로 엮어 씁니다. 앞 단계의 결과가 다음 단계의 기간, 인스턴스, 애플리케이션을 정합니다. 아래 예시의 domain_id=1000, 시각, txid는 자기 환경의 값으로 바꿉니다.

1. 대상 - jennifer-instances

모든 콘솔 명령어는 domain_id를 받습니다. 먼저 도메인과 인스턴스 ID를 확인합니다.

jennifer-instances

인스턴스는 재시작하면 같은 이름에 새 인스턴스 ID로 돌아옵니다. 지난 시간을 분석할 때는 기간을 주어 사라진 예전 ID까지 찾습니다.

jennifer-instances domain_id=1000 duration=1d
| search registered == false
| fields instance_id, instance_name, status

2. 감지 - jennifer-metrics

하루치 지표로 지표·인스턴스별 기준선(평균, 표준편차)을 구하고, 최근 30분이 거기서 얼마나 벗어났는지 z-score로 봅니다. |z|가 3 이상이면 이상으로 봅니다.

jennifer-metrics domain_id=1000 duration=1d metrics=service_time,service_rate,service_err_count,sys_cpu,heap_usage,active_service
| eval recent = if(_time >= dateadd(now(), "min", -30), value, null)
| stats avg(value) as base_mean, stddev(value) as base_sd, avg(recent) as recent_avg by metric, instance_id, instance_name
| eval z = if(base_sd > 0, round((recent_avg - base_mean) / base_sd, 2), 0)
| search abs(z) >= 3
| eval abs_z = abs(z)
| sort limit=20 -abs_z

이상이 언제 시작됐는지는 버킷마다 z-score를 붙여 봅니다.

jennifer-metrics domain_id=1000 duration=1d metrics=service_time
| join metric, instance_id [
    jennifer-metrics domain_id=1000 duration=1d metrics=service_time
    | stats avg(value) as base_mean, stddev(value) as base_sd by metric, instance_id
  ]
| eval z = if(base_sd > 0, round((value - base_mean) / base_sd, 2), 0)
| search z >= 3
| sort limit=50 -z
| fields _time, instance_name, metric, value, base_mean, z

3. 판정 - jennifer-problems

찾은 시각에 JENNIFER가 무엇을 어느 인스턴스의 문제로 판정했는지 확인합니다. 인스턴스의 중지·재시작·재접속은 그 인스턴스 지표의 공백이나 급변을 설명해 줍니다.

jennifer-problems domain_id=1000 from=20261026045000 to=20261026051000
| sort _time

결과가 0행이면 실패가 아니라 그 기간에 JENNIFER가 찾은 문제가 없다는 뜻입니다.

4. 범위 - jennifer-app-summary, jennifer-errors

이상 구간과 직전 구간의 애플리케이션을 비교해, 호출·에러·응답시간이 달라진 애플리케이션을 찾습니다.

jennifer-app-summary domain_id=1000 from=20261027020000 to=20261027040000 span=1h
| eval period = if(_time >= date("20261027030000", "yyyyMMddHHmmss"), "incident", "baseline")
| stats sum(calls) as calls, sum(errors) as errors, sum(total_response_time) as total by application, period
| eval avg_rt = round(total / calls, 1)

에러가 늘었다면 전날 같은 시간과 비교해 새로 늘어난 에러 유형을 찾습니다.

jennifer-errors domain_id=1000 from=20261027090000 to=20261027100000
| stats sum(count) as count by instance_name, error_type_name
| join type=left instance_name, error_type_name [
    jennifer-errors domain_id=1000 from=20261026090000 to=20261026100000
    | stats sum(count) as before_count by instance_name, error_type_name
  ]
| eval before_count = nvl(before_count, 0), increase = count - before_count
| sort limit=20 -increase

5. 증거 - jennifer-xview

좁힌 구간의 느리거나 실패한 트랜잭션을 나열하고, 응답시간 중 SQL, 외부 호출, CPU가 차지한 몫을 봅니다. 기간은 문제 전후 몇 분으로 짧게 잡습니다.

jennifer-xview domain_id=1000 duration=10m min_response_time=3000
| sort limit=20 -response_time
| fields _time, instance_name, application, response_time, sql_time, external_call_time, cpu_time, error_name, txid
jennifer-xview domain_id=1000 from=20261027030000 to=20261027031000 min_response_time=1000
| stats count, avg(response_time) as rt, avg(sql_time) as sql, avg(fetch_time) as fetch, avg(external_call_time) as ext, avg(cpu_time) as cpu by application
| sort limit=10 -rt

6. 원인 - jennifer-profile

대표 트랜잭션을 골라 그 행의 domain_id, txid, collection_time, response_time을 가져옵니다.

jennifer-xview domain_id=1000 duration=10m
| sort limit=1 -response_time
| fields domain_id, txid, collection_time, response_time, application

그 값을 jennifer-profile에 넘겨 가장 오래 걸린 SQL과 외부 호출을 찾습니다.

jennifer-profile domain_id=1000 txid=-2980609390376924461 collection_time=1792972233338 response_time=482
| search type == "SQL" or type == "TX_CALL"
| sort limit=10 -elapsed_ms
| fields no, type, name, start_ms, elapsed_ms, share, parameters

같은 SQL이 반복되는 N+1 쿼리는 SQL별로 묶어 봅니다.

jennifer-profile domain_id=1000 txid=-2980609390376924461 collection_time=1792972233338
| search type == "SQL"
| stats count, sum(elapsed_ms) as total_ms, max(elapsed_ms) as max_ms by name
| sort -total_ms

elapsed_ms는 중첩 호출을 포함하므로 바깥 메서드가 안쪽 호출의 시간을 덮습니다. 가장 바깥 메서드보다 가장 깊은 행이나 SQL, TX_CALL 행에서 원인을 찾습니다. 큰 GAP은 프로파일되지 않은 코드나 락, 대기에서 쓴 시간입니다.

토큰 명령어

토큰 명령어는 수집기와 같은 Open API로 읽습니다. 수집기가 테이블에 쌓는 것과 같은 트랜잭션을 수집 없이 바로 볼 때, 또는 지금 실행 중인 서비스를 볼 때 씁니다.

jennifer-apm-transaction-time domain_id=1000 duration=10m
jennifer-apm-active-service-list domain_id=1000

공통 옵션

옵션쓰는 명령어내용
profile전체접속 프로파일 이름. 생략하면 쓸 수 있는 해당 유형 프로파일을 모두 사용합니다
domain_id전체(jennifer-instances는 선택)도메인 ID(sid). jennifer-instances로 확인합니다
instance_idsjennifer-metrics, jennifer-problems, jennifer-errors, jennifer-xview, jennifer-apm-transaction-time쉼표로 구분한 인스턴스 ID. 생략하면 기간 안에 데이터를 보낸 인스턴스 전체
instance_idjennifer-apm-active-service-list인스턴스 ID 하나. 생략하면 도메인 전체
duration기간을 받는 명령어현재 시각까지의 최근 기간. s(초), m(분), h(시), d(일) 단위
from, to기간을 받는 명령어yyyyMMddHHmmss. 뒷자리를 생략하면 0으로 채웁니다. from이 duration보다 우선하고, to를 생략하면 현재 시각입니다
limitjennifer-metrics, jennifer-errors, jennifer-xview, jennifer-profile최대 행 수
Note
domain_id는 콘솔마다 다릅니다. 같은 숫자라도 다른 콘솔에서는 다른 도메인이거나 없는 도메인입니다. 그래서 콘솔 명령어에 domain_id를 주면 프로파일이 하나여야 하고, 쓸 수 있는 JENNIFER 콘솔 프로파일이 여럿이면 profile 옵션으로 하나를 지정해야 합니다.

에러 코드

대역대상
207900-207905토큰 명령어: 프로파일 없음, 프로파일 필요, from·to·domain_id 필요, 인스턴스 ID 형식 오류
207910-207919콘솔 명령어 공통: 프로파일 없음, 프로파일 필요, domain_id 없음·형식 오류, instance_ids 형식 오류, limit 형식 오류, domain_id를 줬는데 프로파일이 여럿
207920-207929jennifer-instances
207930-207939jennifer-metrics
207940-207949jennifer-problems
207950-207959jennifer-xview
207960-207969jennifer-profile
207970-207979jennifer-app-summary
207980-207989jennifer-errors

콘솔 명령어는 콘솔 호출이 실패하면 쿼리를 오류로 끝냅니다. 결과가 0행이면 실패가 아니라 정말로 데이터가 없다는 뜻입니다. 반면 토큰 명령어는 호출 오류를 서버 로그에만 남기므로, 결과가 비어 있으면 접속 프로파일과 네트워크도 함께 확인하세요.

알아 둘 것

명령어내용
콘솔 명령어 전체조회만 합니다. 어떤 명령어도 콘솔의 설정이나 상태를 바꾸지 않습니다
jennifer-metrics인스턴스가 보고하지 않은 버킷도 0으로 옵니다. 0이 연속되면 유휴보다 중지나 미수집일 가능성이 큽니다. 아직 끝나지 않은 버킷은 나오지 않습니다. 도메인 전체 합계 행은 없고 인스턴스별 행만 나옵니다
jennifer-problems해상도는 1분이고 문제가 있던 분만 나옵니다
jennifer-app-summary도메인 전체를 애플리케이션별로 요약하며 인스턴스별로 나누지 않습니다. avg_sql_time과 avg_external_call_time은 트랜잭션당이 아니라 SQL 1회, 외부 호출 1회당 평균입니다. 호출 합계는 일일 시스템 성능 통계의 호출 건수와 같습니다
jennifer-xview결과가 오래된 것부터 오므로 limit에 걸리면 기간의 뒤쪽이 빠집니다. 결과가 정확히 limit 행이면 잘린 것입니다. 하루치는 작은 서버에서도 수십만 행에 이릅니다
jennifer-xview쿼리를 취소해도 콘솔 서버는 요청한 기간의 데이터를 끝까지 보냅니다. 기간을 짧게 잡고 min_response_time이나 errors_only=t로 줄이세요
jennifer-profile트랜잭션은 jennifer-xview 행의 collection_time으로 찾습니다. 몇 초 차이는 괜찮지만 1분 이상 어긋나면 찾지 못해 오류가 납니다. _time이나 end_time을 넘기지 마세요
jennifer-apm-transaction-time제니퍼 Open API가 한 번에 1분씩만 주므로 기간을 1분 단위로 나눠 호출합니다. 기간이 길면 호출 수가 그만큼 늘어납니다