Flameshot
Flameshot은 Sidecar 방식으로 동작하는 경량 자동 성능 프로파일링(Profiling) 도구입니다. 대상 프로세스의 자원 사용량(CPU/메모리)을 모니터링하다가 사전 설정한 임계값에 도달하면 하위 Profiler(예: async-profiler)를 자동으로 호출하여, 비침습적으로 현장 스냅샷을 수집합니다.
핵심 기능과 원리¶
실행 모드¶
Flameshot은 Sidecar 컨테이너 방식으로 배포됩니다. 반드시 업무 메인 컨테이너(Main Container)와 같은 Pod에서 실행되어야 하며, PID 네임스페이스 공유가 활성화되어 있어야 합니다.
- 모니터링 (Monitor): Flameshot이 메인 컨테이너 내 대상 프로세스의 자원 상태를 지속적으로 폴링합니다.
- 트리거 (Trigger): 임계값(CPU > 80% 등)을 만족하거나 HTTP API 요청을 받으면 수집 작업을 시작합니다.
- 실행 (Execute): 설정된 언어 유형(현재 Java와 Go 지원)에 따라 대응하는 Profiler 도구를 호출해 대상 프로세스를 수집합니다.
- 수집 (Collect): 생성된 Profile 파일(
.jfr또는.pprof등)을 데이터 관측 센터로 업로드합니다. - 주기 수집:
FLAMESHOT_AUTO_PROFILING을 설정하면 일치하는 모든 프로세스에 대해 정기적으로 한 번씩 Profiling 데이터를 수집합니다. 기본 수집 시간은 30초이며,FLAMESHOT_AUTO_PROFILING_DURATION으로 조정할 수 있습니다. - OOM 요약: 컨테이너
oom_kill증가분이 감지되면, Flameshot은 대상 Java 프로세스의 시작 인자에서-XX:+HeapDumpOnOutOfMemoryError와-XX:HeapDumpPath=...를 자동으로 파싱하려고 시도합니다. dump 파일이 공유 볼륨에 있고 생성에 성공하면 Flameshot은 해당.hprof를 찾아 요약 로그를 업로드합니다.
적용 시나리오¶
- 운영 환경 안전망: 서비스가 CPU 급증이나 메모리 누수로 곧 장애가 나기 전에 자동으로 현장 증거를 보관합니다.
- 성능 부하 테스트 분석: 부하 테스트 플랫폼과 함께 사용해 고부하 상태의 성능 병목을 자동으로 수집합니다.
설정 상세¶
Flameshot의 모든 동작은 환경 변수로 제어됩니다. 설정은 전역 설정과 수집 정책 두 부분으로 나뉩니다.
전역 환경 변수¶
이 변수들은 Sidecar 컨테이너의 기본 동작을 제어합니다.
| 변수명 | 필수 | 기본값 | 설명 |
|---|---|---|---|
FLAMESHOT_DATAKIT_ADDR |
예 | - | DataKit의 Profiling 데이터 수신 인터페이스 주소. |
FLAMESHOT_PROFILING_PATH |
예 | /data |
공유 디렉터리 경로. 도구 라이브러리와 생성된 임시 파일을 저장하는 데 사용되며, 메인 컨테이너의 마운트와 일치해야 합니다. |
FLAMESHOT_MONITOR_INTERVAL |
아니요 | 1 |
모니터링 폴링 간격(초). |
FLAMESHOT_LOG_LEVEL |
아니요 | info |
로그 레벨. 사용 가능 값: debug, info, warn, error. |
FLAMESHOT_HTTP_LOCAL_IP |
예 | - |
Sidecar 자체 HTTP 서비스의 리슨 주소. |
FLAMESHOT_HTTP_LOCAL_PORT |
예 | 8089 |
Sidecar 자체 HTTP 서비스의 리슨 포트. |
FLAMESHOT_PROFILING_ENABLED |
아니요 | true |
JFR Profiling 사용 여부. false로 설정하면 주기, 임계값, cgroup 고수위, HTTP 수동 Profiling은 비활성화되지만 OOM 감지, hprof 업로드, 능동 Heap Dump는 유지됩니다. |
FLAMESHOT_AUTO_PROFILING |
아니요 | - | 일치하는 모든 프로세스에 대해 정기적으로 한 번씩 Profiling 데이터를 수집합니다. 최소 1분 이상이어야 하며, 예: 5분 "5m" 또는 1시간 "1h". |
FLAMESHOT_AUTO_PROFILING_DURATION |
아니요 | 30s |
정기 수집 모드에서의 단일 샘플링 시간입니다. |
FLAMESHOT_OOM_HPROF_ENABLED |
아니요 | false |
OOM 발생 후 .hprof 요약 복구 경로를 활성화할지 여부입니다. Java 프로세스에만 적용되며, 대상 JVM이 명시적으로 -XX:+HeapDumpOnOutOfMemoryError를 켜고 공유 볼륨에 있는 -XX:HeapDumpPath=...를 설정해야 합니다. 배포 설정에서 명시적으로 선언하는 것을 권장합니다. |
FLAMESHOT_OOM_HPROF_MATCH_WINDOW |
아니요 | 2m |
OOM 이벤트와 .hprof 파일 수정 시간의 매칭 윈도우입니다. |
FLAMESHOT_HPROF_UPLOAD_ENABLED |
아니요 | false |
일치하거나 직접 생성된 .hprof를 오브젝트 스토리지로 업로드할지 여부입니다. |
FLAMESHOT_HPROF_UPLOAD_PROVIDER |
아니요 | - | 오브젝트 스토리지 유형입니다. oss와 s3를 지원합니다. |
FLAMESHOT_HPROF_UPLOAD_ENDPOINT |
아니요 | - | OSS/S3 endpoint입니다. |
FLAMESHOT_HPROF_UPLOAD_REGION |
아니요 | S3 기본값 us-east-1 |
S3 region입니다. |
FLAMESHOT_HPROF_UPLOAD_BUCKET |
아니요 | - | 대상 bucket입니다. |
FLAMESHOT_HPROF_UPLOAD_ACCESS_KEY_ID |
아니요 | - | 오브젝트 스토리지 AK입니다. |
FLAMESHOT_HPROF_UPLOAD_ACCESS_KEY_SECRET |
아니요 | - | 오브젝트 스토리지 SK입니다. |
FLAMESHOT_HPROF_UPLOAD_PATH_TEMPLATE |
아니요 | {service}/{pod_name}/{timestamp}/{filename} |
오브젝트 경로 템플릿입니다. service / pod_name / pod_namespace / host / pid / timestamp / filename 등의 변수를 지원합니다. |
FLAMESHOT_HPROF_DOWNLOAD_URL_TEMPLATE |
아니요 | - | 선택적 다운로드 링크 템플릿입니다. 설정하면 이벤트에서 이 템플릿으로 hprof_download_url을 생성합니다. |
FLAMESHOT_HEAP_DUMP_ENABLED |
아니요 | false |
메모리 긴급 임계값이 명중했을 때 능동으로 Java Heap Dump를 실행할지 여부입니다. |
FLAMESHOT_HEAP_DUMP_PATH_TEMPLATE |
아니요 | {profiling_path}/dumps/{service}_{pod_name}_{pid}_{timestamp}.hprof |
로컬 Heap Dump 출력 경로 템플릿입니다. |
FLAMESHOT_HEAP_DUMP_JMAP_PATH |
아니요 | jmap |
jmap 실행 파일 경로입니다. 공식 Sidecar 이미지에는 JVM/JDK가 기본 내장되어 있지 않으므로, 능동 Heap Dump를 켤 때는 사용 가능한 jmap을 명시적으로 제공해야 합니다. |
FLAMESHOT_HEAP_DUMP_TIMEOUT |
아니요 | 120s |
Heap Dump 명령의 타임아웃 시간입니다. |
FLAMESHOT_HEAP_DUMP_COOLDOWN |
아니요 | 10m |
단일 프로세스의 능동 Heap Dump 쿨다운 시간입니다. |
FLAMESHOT_POD_MEM_LIMIT |
아니요 | - | Pod 메모리 limit이며, 단위는 Mi입니다. 설정하면 Pod limit 기준으로 메모리 사용률을 우선 계산합니다. |
FLAMESHOT_POD_CPU_LIMIT |
아니요 | - | Pod CPU limit이며, 단위는 m입니다. 설정하면 Pod CPU limit 기준으로 CPU 사용률을 계산합니다. |
FLAMESHOT_SERVICE |
아니요 | - | FLAMESHOT_PROCESSES에 service를 따로 설정하지 않아도 되며, 모두 치환됩니다. |
FLAMESHOT_TAGS |
아니요 | - | host pod_name pod_namespace를 설정하는 것을 권장합니다. 예: "host:host_name,pod_name:pod_a" |
DataKit이 DaemonSet 방식으로 배포되고 hostNetwork/hostPort로 9529를 노출하는 경우, Flameshot이 일반 Service 도메인을 통해 무작위로 전달받는 대신 현재 업무 Pod가 있는 노드의 DataKit에 직접 연결하도록 권장합니다.
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: FLAMESHOT_DATAKIT_ADDR
value: "http://$(NODE_IP):9529/profiling/v1/input"
이렇게 하면 각 업무 Pod가 Profile을 자신이 속한 노드의 DataKit로 업로드하므로, 문제 분석과 노드 로컬 수집 의미를 유지하기에 좋습니다.
수집 정책 설정 (FLAMESHOT_PROCESSES)¶
환경 변수 FLAMESHOT_PROCESSES로 모니터링 대상을 정의합니다. 이 변수의 값은 표준 JSON 배열 문자열이어야 합니다.
Kubernetes YAML에서 설정 가독성을 유지하려면, JSON 설정을 아래처럼 YAML 다중 행 문자열 문법(|)으로 작성하는 것을 강력히 권장합니다.
env:
# ... 기타 환경 변수 ...
- name: FLAMESHOT_PROCESSES
value: |
[
{
"service": "user-service",
"language": "java",
"command": "^java.*user-service\\.jar$",
"duration": "60s",
"events": "cpu,alloc",
"cpu_usage_percent": 80,
"mem_usage_percent": 80,
"mem_usage_mb": 1024,
"mem_usage_percent_emergency": 92,
"mem_usage_mb_emergency": 1536,
"heap_dump_on_memory_emergency": true,
"emergency_duration": "10s",
"tags": [
"env:prod",
"version:v1.2"
]
}
]
공통 필드 설명:
service(String): 관측 센터에 보고되는 서비스 이름입니다.language(String): 대상 프로세스 언어입니다. 현재java,go,golang을 지원합니다.command(String): 프로세스 명령행을 매칭하는 정규식입니다.duration(String): 단일 수집 시간입니다. 예:30s,1m. 주의: 실행 타임아웃의 제약을 받으므로 5분을 넘기지 않는 것이 좋습니다.emergency_duration(String): 메모리 긴급 임계값이 명중한 뒤의 빠른 수집 시간입니다.10s또는15s로 설정하는 것을 권장합니다.pprof_url(String): Go pprof HTTP 주소입니다. 예:http://127.0.0.1:6060.language가go또는golang일 때 설정해야 합니다.pprof_types(List): Go pprof 유형입니다.cpu,goroutine,heap,mutex,block을 지원하며, profile 수집기의 기존 Go pull 모드와 일치합니다.pprof_timeout(String): Go pprof 요청 타임아웃입니다.duration보다 크게 설정하는 것이 좋습니다.tags(List): 사용자 정의 태그 목록입니다.env,version등의 메타 정보를 포함하는 것을 권장합니다.cpu_usage_percent(Int): CPU 트리거 임계값(0-N)입니다. 멀티코어 환경에서는 값이 100을 넘을 수 있습니다.mem_usage_percent(Int): 메모리 사용률 평균 임계값(0-100)입니다. 최근 5개 포인트의 평균값을 기준으로 트리거합니다.mem_usage_mb(Int): 메모리 사용량 평균 임계값(MB)입니다. 최근 5개 포인트의 평균값을 기준으로 트리거합니다.mem_usage_percent_emergency(Int): 메모리 사용률 긴급 순간 임계값(0-100)입니다. 단일 포인트만 명중해도 즉시 트리거됩니다.mem_usage_mb_emergency(Int): 메모리 사용량 긴급 순간 임계값(MB)입니다. 단일 포인트만 명중해도 즉시 트리거됩니다.heap_dump_on_memory_emergency(Bool): 메모리 긴급 임계값이 명중했을 때 해당 프로세스 규칙이 능동 Heap Dump를 수행하도록 허용할지 여부입니다. 설정하지 않으면FLAMESHOT_HEAP_DUMP_ENABLED=true일 때 기본적으로 허용됩니다.cpu_usage_percent、mem_usage_percent、mem_usage_mb를 설정하지 않거나 0으로 설정하면 해당 임계값 검사는 건너뜁니다.FLAMESHOT_POD_MEM_LIMIT을 설정하면mem_usage_percent와mem_usage_percent_emergency는 호스트 관점이 아니라 Pod limit 관점으로 우선 계산됩니다.FLAMESHOT_HEAP_DUMP_ENABLED=true를 설정하면 메모리 긴급 임계값 명중 시jmapHeap Dump 작업이 발행됩니다. 이 기능은 Sidecar 내부에서FLAMESHOT_HEAP_DUMP_JMAP_PATH가 가리키는jmap을 실행할 수 있어야 합니다. 동시에 hprof 오브젝트 스토리지 업로드를 설정했다면 생성된.hprof는 계속 업로드되며, 이벤트에는hprof_object_key,hprof_download_url, 업로드 상태가 함께 포함됩니다.
언어별 안내¶
모니터링 대상 애플리케이션의 기술 스택에 따라 Flameshot은 서로 다른 하위 도구를 호출합니다.
Java 프로파일링¶
Java 애플리케이션의 경우 Flameshot은 async-profiler(linux-amd64 / linux-arm64 지원)를 내장하고 있습니다.
핵심 설정 필드 (FLAMESHOT_PROCESSES):
language: 반드시java로 설정해야 합니다.events:cpu(CPU cycles),alloc(메모리 할당),lock(락 경쟁),cache-misses,nativemem을 지원합니다. 기본값은all입니다.jdk_version: (선택) 메타데이터 표시용 JDK 버전입니다.
주의사항:
- JVM Safepoint에 의존하지 않으므로 오버헤드가 매우 낮습니다.
- OOM 후 자동으로
.hprof요약 로그를 찾아 업로드하려면, 업무 JVM에서 반드시-XX:+HeapDumpOnOutOfMemoryError를 켜고-XX:HeapDumpPath=...를 설정해야 합니다.FLAMESHOT_OOM_HPROF_ENABLED=true만 설정한다고 해서 대상 JVM의 시작 인자가 자동으로 바뀌지는 않습니다. FLAMESHOT_HEAP_DUMP_ENABLED=true를 켜면, Flameshot은 메모리 긴급 임계값이 명중했을 때jmap -dump:format=b,file=<path> <pid>를 실행해.hprof를 능동 생성합니다. 공식 Sidecar 이미지에는 JVM/JDK가 기본 내장되어 있지 않으므로, 커스텀 이미지, 도구 마운트 또는 다른 방법으로 대상 JVM과 호환되는jmap을 명시적으로 제공하고FLAMESHOT_HEAP_DUMP_JMAP_PATH로 지정해야 합니다.HeapDumpPath는 업무 컨테이너와 Flameshot Sidecar가 공동으로 마운트한 공유 디렉터리를 가리켜야 합니다. 각 프로세스마다 안정적이고 구분 가능한 dump 경로를 설정하는 것이 좋습니다. 그렇지 않으면 Flameshot이 OOM을 감지하더라도 dump 파일을 읽을 수 없습니다..hprof요약 복구와 관련된 스위치는 배포 설정에서 명시적으로 선언하는 것이 좋으며, 암묵적인 기본값에 의존하지 않는 것이 좋습니다.
Go 프로파일링¶
Go 애플리케이션의 경우 Flameshot은 업무 프로세스가 노출하는 net/http/pprof HTTP 인터페이스에서 .pprof 데이터를 가져와 DataKit로 업로드합니다.
핵심 설정 필드 (FLAMESHOT_PROCESSES):
language: 반드시go또는golang으로 설정해야 합니다.pprof_url: 업무 프로세스의 pprof HTTP 주소입니다. 예:http://127.0.0.1:6060.pprof_types:cpu,goroutine,heap,mutex,block을 지원합니다.duration:cpuprofile의 수집 시간입니다./debug/pprof/profile?seconds=<duration>에 매핑됩니다.pprof_timeout: pprof 요청 타임아웃입니다.duration보다 커야 합니다.
Go 애플리케이션 측 요구사항:
import (
"net/http"
_ "net/http/pprof"
)
func main() {
go http.ListenAndServe("127.0.0.1:6060", nil)
}
pprof_url은 Flameshot Sidecar가 실제로 접근 가능한 주소여야 합니다. 일반적으로 다음 두 가지 경우가 있습니다.
- pprof가
127.0.0.1:6060또는0.0.0.0:6060에 리슨하는 경우:http://127.0.0.1:6060으로 설정할 수 있습니다. - pprof가 Pod IP, 예를 들어
10.x.x.x:6060에만 리슨하는 경우: Downward API로 Pod IP를 주입하고http://$(POD_IP):6060으로 설정해야 합니다.
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: FLAMESHOT_PROCESSES
value: |
[
{
"service": "go-app",
"language": "go",
"command": "^/app/go-app$",
"pprof_url": "http://$(POD_IP):6060",
"pprof_types": ["cpu", "goroutine", "heap", "mutex", "block"],
"duration": "30s",
"pprof_timeout": "45s"
}
]
설정 예시:
{
"service": "go-app",
"language": "go",
"command": "^/app/go-app",
"pprof_url": "http://127.0.0.1:6060",
"pprof_types": ["cpu", "goroutine", "heap", "mutex", "block"],
"duration": "30s",
"pprof_timeout": "45s",
"tags": ["env:prod", "version:v1"]
}
주의사항:
heap、mutex、block은 delta profile 형식으로 업로드되며, 첫 번째 샘플은 기준선으로 저장되고 이러한 delta 유형은 업로드되지 않습니다.mutex와block은 기본적으로 유효한 데이터를 수집하지 않으므로, 업무 코드에서runtime.SetMutexProfileFraction과runtime.SetBlockProfileRate를 명시적으로 활성화해야 합니다.- pprof 인터페이스는 민감한 런타임 정보를 노출할 수 있으므로, Pod 내부 로컬 주소에만 리슨하고 Service나 공용 네트워크로는 노출하지 않는 것이 좋습니다.
Python 프로파일링¶
계획 중: py-spy 같은 비침습 도구를 통합할 예정입니다.
배포 안내¶
Kubernetes Sidecar 배포¶
Flameshot이 정상 동작하려면 Pod 설정이 다음 세 가지 조건을 만족해야 합니다.
- 프로세스 공간 공유 (
shareProcessNamespace: true). - 공유 저장 볼륨 (EmptyDir).
- 시스템 권한 (Capabilities).
YAML 예시:
apiVersion: v1
kind: Pod
metadata:
name: java-app-profiled
spec:
# 1. [핵심] PID 공유를 켜서 Sidecar가 Java 프로세스를 볼 수 있게 한다
shareProcessNamespace: true
volumes:
- name: shared-data
emptyDir: {}
containers:
# 업무 컨테이너
- name: my-app
image: my-app:latest
volumeMounts:
- name: shared-data
mountPath: /data # Sidecar 설정과 일치해야 함
# Flameshot Sidecar
- name: flameshot
image: pubrepo.jiagouyun.com/datakit/flameshot:latest
env:
- name: FLAMESHOT_PROFILING_PATH
value: "/data"
# ... 기타 환경 변수 ...
# 2. [핵심] ptrace 권한 부여
securityContext:
capabilities:
add: ["SYS_PTRACE"]
# 3. [핵심] 동일한 디렉터리 마운트
volumeMounts:
- name: shared-data
mountPath: /data
DataKit DaemonSet 설정 주의사항¶
DataKit이 DaemonSet 방식으로 배포되는 경우, Flameshot은 현재 노드 IP로 Profile을 업로드하는 방식을 권장합니다.
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: FLAMESHOT_DATAKIT_ADDR
value: "http://$(NODE_IP):9529/profiling/v1/input"
동시에 DataKit이 아래 조건을 만족하는지 확인해야 합니다.
-
profile 수집기가 활성화되어 있어야 하며, Profiling 업로드 인터페이스가 등록되어 있어야 합니다.
-
localhost 이외의 Profiling API 접근을 허용해야 합니다. DataKit에서 HTTP API 화이트리스트를 사용 중이라면
/profiling/v1/input을ENV_HTTP_PUBLIC_APIS에 추가해야 합니다.- name: ENV_HTTP_PUBLIC_APIS value: /otel/v1/trace,/otel/v1/metric,/otel/v1/logs,/profiling/v1/input이 변수가 이미 다른 인터페이스로 설정되어 있다면 기존 값을 직접 덮어쓰지 말고, 원래 목록 뒤에
/profiling/v1/input을 추가해야 합니다. 그렇지 않으면 다음 오류가 발생할 수 있습니다. -
DataKit 리슨 주소가 노드 IP로 접근 가능해야 합니다. DaemonSet에서 흔한 설정은
hostNetwork: true,hostPort: 9529,ENV_HTTP_LISTEN=0.0.0.0:9529입니다.
OOM HProf 요약 요구사항¶
Java 프로세스가 OOM 난 뒤 Flameshot이 자동으로 .hprof 요약을 보충 수집하게 하려면, 다음 조건을 모두 만족해야 합니다.
- 업무 JVM 시작 인자에
-XX:+HeapDumpOnOutOfMemoryError를 켭니다. - 업무 JVM 시작 인자에
-XX:HeapDumpPath=/data/...를 설정하고, 해당 경로가 공유 볼륨 안에 있어야 합니다. - Flameshot에
FLAMESHOT_OOM_HPROF_ENABLED=true를 설정합니다. - 운영 측에서 매칭 윈도우를 명확히 인지할 수 있도록
FLAMESHOT_OOM_HPROF_MATCH_WINDOW도 함께 명시적으로 설정하는 것을 권장합니다.
예:
설명:
- Flameshot은 대상 Java 프로세스의 시작 인자에서 직접
HeapDumpPath를 자동 파싱하며,.hprof경로를 별도로 지정하지 않습니다. FLAMESHOT_OOM_HPROF_ENABLED는 Flameshot 측 복구 로직만 켤 뿐, 대상 JVM에 HeapDump 관련 인자를 주입하지는 않습니다.- 대상 프로세스가
HeapDumpOnOutOfMemoryError를 켜지 않았거나HeapDumpPath가 공유 볼륨 내부에 있지 않으면, Flameshot은 OOM 이벤트만 기록할 수 있고 해당.hprof파일은 찾을 수 없습니다. - 컨테이너가 dump 완료 전에 직접 종료되면
.hprof가 여전히 생성되지 않을 수 있습니다.
Docker 로컬 테스트¶
로컬 Docker 환경에서 테스트해야 하는 경우, 아래 명령으로 Flameshot을 실행하고 대상 컨테이너를 모니터링할 수 있습니다.
전제 조건:
--pid="container:<target_id>"또는 공유 볼륨 방식을 사용해야 합니다(구체적인 Docker 버전에 따라 다름).
테스트 이미지: pubrepo.jiagouyun.com/datakit/flameshot:1.85.1-testing_testing-iss-2876
실행 명령 예시:
docker run -d \
--name flameshot-debug \
--volumes-from <YOUR_JAVA_APP_CONTAINER> \
-e FLAMESHOT_DATAKIT_ADDR="http://datakit:9529/profiling/v1/input" \
-e FLAMESHOT_PROCESSES='[{"service":"local-test","command":"java","language":"java","cpu_usage_percent":10}]' \
pubrepo.jiagouyun.com/datakit/flameshot:1.85.1-testing_testing-iss-2876
API 인터페이스 참고¶
Flameshot은 사용자가 또는 자동화 운영 스크립트가 직접 트리거할 수 있는 HTTP 인터페이스를 제공합니다.
수동 수집 트리거¶
인터페이스 주소: GET /v1/profile
의미 설명: 이 인터페이스는 모니터링 지표를 가져오는 것이 아니라, 필요할 때 Profile 데이터를 하나 생성하는 용도입니다.
요청 파라미터:
| 파라미터명 | 필수 | 설명 | 예시 |
|---|---|---|---|
pid |
둘 중 하나 | 대상 프로세스 ID입니다. command보다 우선순위가 높습니다. |
1234 |
command |
둘 중 하나 | 대상 프로세스명 정규식입니다. 대상 프로세스를 매칭하는 데 사용합니다. | ^java.*app.jar$ |
duration |
아니요 | 수집 시간입니다. 기본값은 30s입니다. |
30s |
events |
아니요 | Java 수집 이벤트 유형입니다. 기본값은 all입니다. Go 수집은 우선 pprof_types를 사용합니다. |
cpu,alloc |
사용 예시:
-
PID로 수집 트리거:
-
프로세스명 정규식으로 수집 트리거:
JFR 데이터 형식¶
다음은 몇 가지 핵심 이벤트 유형에 대한 상세 설명입니다.
| 이벤트 유형 (Event) | 대응 파라미터 | 핵심 원리 | 적용 시나리오 | 비고 |
|---|---|---|---|---|
| CPU Time | cpu | 커널 샘플링 또는 itimer를 통해 CPU가 어떤 코드 명령을 처리 중인지 주기적으로 확인합니다. | 성능 최적화: 계산 집약적인 “핫스팟 메서드”를 찾아 알고리즘 로직을 최적화합니다. | CPU에서 실제로 실행된 시간만 기록합니다. |
| Wall-clock | wall | 스레드 상태와 무관하게(실행, 대기, 블로킹) 고정 주기로 샘플링합니다. | 응답 지연 진단: I/O 블로킹, 느린 데이터베이스 호출, 네트워크 지연 등을 확인합니다. | 스레드가 “무엇을 기다리고 있는지”를 보여줍니다. |
| Allocation | alloc | TLAB(스레드 로컬 할당 캐시)의 할당 상황과 대형 객체 할당을 기록합니다. | 메모리 최적화: 메모리 흔들림을 찾고 빈번한 GC로 인한 멈춤을 줄입니다. | 현재 살아 있는 메모리 총량이 아니라 할당 동작을 기록합니다. |
| Lock | lock | synchronized 키워드에서의 경쟁과 대기 시간을 기록합니다. |
동시성 병목: 심한 락 경쟁, 스레드 교착 상태, 느린 동기화 블록 실행을 확인합니다. | 기본적으로 일정 임계값을 넘는 블로킹 이벤트만 기록합니다. |
| Cache Misses | cache-misses | 하드웨어 성능 카운터(PMU)를 이용해 L1/L2/L3 캐시 미스 횟수를 집계합니다. | 저수준 튜닝: 데이터 구조를 최적화합니다(예: CPU 친화성, false sharing 문제). | Linux 커널의 perf_events 지원이 필요합니다. |
| Context Switch | context-switches | 운영체제가 스레드를 전환하는 빈도를 기록합니다. | 자원 스케줄링 최적화: 스레드 수가 너무 많은지, 시스템 부하가 과도한지 확인합니다. | 빈번한 전환은 CPU 시간을 관리 오버헤드에 소모하게 합니다. |
| Java Methods | itimer | 커널 타이머 기반 샘플링입니다. | 호환성 모드: perf_events를 사용할 수 없는 환경(예: 일부 컨테이너)에서 CPU 샘플링 대체 수단으로 사용합니다. |
하드웨어 샘플링보다 정밀도는 약간 낮지만 호환성은 매우 좋습니다. |
alloc은 현재 존재하는 모든 메모리의 합이 아니라, 현재 샘플링 기간 동안 할당된 메모리 크기입니다.
자주 묻는 질문 및 점검¶
-
데이터를 수집할 수 없나요?
- Pod에
shareProcessNamespace: true가 켜져 있는지 확인합니다. - Sidecar에
SYS_PTRACE권한이 있는지 확인합니다. - Go 애플리케이션의 경우
pprof_url이 Flameshot Sidecar 내부에서 접근 가능한지 확인합니다. -
Go 애플리케이션은 먼저 Flameshot 컨테이너 안에서 pprof endpoint 접근 여부를 확인합니다.
-
로그에
connect: connection refused가 나타나면 해당 IP:Port에 리슨하는 프로세스가 없다는 뜻입니다. Pod 안에서 확인합니다.
LISTEN이 보이지 않으면 업무 프로세스가 pprof를 열지 않았거나 리슨 포트가 6060이 아니라는 뜻입니다.60602 ... ESTABLISHED같은 연결만 보이는 것은 6060이 리슨 중이라는 의미가 아닙니다. - pprof가 Pod IP에서 리슨하는 경우pprof_url은http://$(POD_IP):6060으로 설정해야 합니다. loopback 또는 모든 주소에서 리슨하는 경우http://127.0.0.1:6060을 사용할 수 있습니다. - Pod에
-
파일이 업로드되지 않나요?
FLAMESHOT_PROFILING_PATH가 두 컨테이너 사이에 올바르게 마운트되어 있는지 확인합니다.- 시스템이 파일 생명주기를 자동 관리하므로, 수집이 끝나면 임시 파일 삭제를 시도합니다.
- Go 수집은
.pprof를 메모리 첨부 방식으로 직접 업로드하므로 일반적으로 로컬 디스크 기록에 의존하지 않습니다. Go 수집 로그에 이미upload to DataKit err가 보인다면, 우선 DataKit가 반환한 HTTP 상태 코드와 응답 본문을 확인해야 합니다. -
DataKit가
403을 반환하고datakit.publicAccessDisabled를 포함한다면/profiling/v1/input이 non-localhost에 허용되지 않은 것입니다. DataKit 설정에 다음을 추가하세요. -
DataKit가
input "profile" is not enabled for API "/profiling/v1/input"를 반환한다면 DataKit에서 profile 수집기가 활성화되지 않은 것입니다. 다음을 활성화하세요.
-
정규식 설정이 너무 번거롭습니다
- JAVA 애플리케이션의 프로세스명은 모두
java이므로,"command":"java"와"language": "java"만 설정해도 모든 JAVA 애플리케이션을 매칭할 수 있습니다. - 특정 애플리케이션만 설정하려면 정규식은 반드시 지정해야 합니다.
- JAVA 애플리케이션의 프로세스명은 모두
변경 이력 (Changelog)¶
0.2.2 (2026-5-12)¶
문제 수정¶
- 수정
- Profiling 보고 메타데이터에서
tags_profiler가host,env,version,service등의 태그를 중복 기록할 수 있던 문제를 수정했습니다.
- Profiling 보고 메타데이터에서
- 조정
- 고수위
jcmd스냅샷 기능과 관련 설정 항목을 제거했습니다. - cgroup 메모리 압력 트리거 시 관측 필드를 추가해, 임계값, cgroup 현재값, 상한값을 더 쉽게 확인할 수 있게 했습니다.
- 고수위
0.2.1 (2026-2-11)¶
새 기능¶
- 개선
- 컨테이너 환경에서 자원 설정 크기를 임계값 계산의 기준값으로 사용합니다.
0.2.0 (2026-2-4)¶
새 기능¶
- 설정 추가
- 환경 변수
FLAMESHOT_AUTO_PROFILING으로 정기 Profiling 실행을 설정할 수 있습니다.
- 환경 변수
- 기능 개선
- 설정 임계값을 최적화했습니다.
0.1.0 (2025-12-17)¶
Flameshot의 첫 정식 버전으로, 컨테이너 환경의 Java 애플리케이션에 자동 성능 프로파일링 기능을 제공하는 데 집중했습니다.
새 기능¶
- 핵심 아키텍처:
- Kubernetes Sidecar 모드 배포를 지원하며, 공유 PID 네임스페이스를 활용해 비침습 모니터링을 구현합니다.
- Linux AMD64와 ARM64 멀티 아키텍처 실행을 지원합니다.
- 언어 지원:
- Java:
async-profiler와 깊게 통합되어 CPU, Alloc, Lock 등 다양한 이벤트 수집을 지원합니다. - 대상 컨테이너의 JDK 환경을 자동 감지하고 적응하는 기능을 지원합니다.
- Java:
- 트리거 메커니즘:
- 임계값 트리거: CPU 사용률 (
cpu_usage_percent)과 메모리 사용률/사용량 (mem_usage_percent/mem_usage_mb) 기반의 자동 트리거를 지원합니다. - API 트리거: HTTP 인터페이스
GET /v1/monitor를 제공하며, PID 또는 정규식으로 프로세스명을 매칭해 수동 트리거할 수 있습니다.
- 임계값 트리거: CPU 사용률 (
- 데이터 통합:
- 생성된
.jfr또는 플레임 그래프 데이터를 DataKit으로 자동 보고할 수 있습니다. - 환경 변수
FLAMESHOT_PROCESSES로 다중 프로세스 모니터링 전략과 태그(tags)를 유연하게 구성할 수 있습니다.
- 생성된