Split View: IDE별 디버깅 완전정리: VS Code · IntelliJ IDEA · PyCharm 브레이크포인트, 실행 구성, 프로파일링
IDE별 디버깅 완전정리: VS Code · IntelliJ IDEA · PyCharm 브레이크포인트, 실행 구성, 프로파일링
이 글은 디버깅 실전 시리즈 5편 중 3편이다.
IDE 디버깅은 "설정"이 절반이다
좋은 IDE를 쓰는데도 디버깅이 느린 이유는 대부분 같다.
- 실행 구성이 매번 달라 재현이 흔들림
- 브레이크포인트를 무작정 많이 찍음
- 프로파일링을 장애 후반에야 시작함
아래 설정을 팀 표준으로 맞추면 디버깅 속도가 눈에 띄게 빨라진다. IDE마다 개념은 같지만 설정 방식이 다르므로, 각 IDE별 구체적인 방법을 정리했다.
IDE별 디버깅 기능 비교
| 기능 | VS Code | IntelliJ IDEA | PyCharm |
|---|---|---|---|
| 실행 구성 파일 | .vscode/launch.json | .run/*.xml / .idea | .run/*.xml / .idea |
| 조건부 브레이크포인트 | 우클릭 → Edit Condition | 우클릭 → Condition | 우클릭 → Condition |
| Logpoint (중단 없는 로그) | 우클릭 → Add Logpoint | Evaluate and Log (Shift+Click) | Evaluate and Log |
| Exception Breakpoint | Run → Add Exception BP | Run → View Breakpoints → + | Run → View Breakpoints → + |
| Watch Expression | Debug 패널 → Watch | Variables 패널 + Watches | Variables 패널 + Watches |
| Evaluate Expression | Debug Console 입력 | Alt+F8 (디버그 중) | Alt+F8 (디버그 중) |
| Hot Reload | 일부 확장 지원 | HotSwap (JVM) 내장 | Django/Flask 자동 리로드 |
| 원격 디버깅 | launch.json attach 설정 | Remote Debug Configuration | Remote Debug Configuration |
| 내장 프로파일러 | 확장 의존 | Ultimate 내장 (CPU/Memory) | Professional 내장 |
| 멀티프로세스 디버깅 | compound launch | Compound Run Config | Compound Run Config |
IDE별 추천 확장/플러그인
| 용도 | VS Code | IntelliJ IDEA | PyCharm |
|---|---|---|---|
| 에러 하이라이트 | Error Lens | 내장 | 내장 |
| Git 변경 추적 | GitLens | 내장 Git Blame | 내장 Git Blame |
| REST API 테스트 | REST Client / Thunder Client | HTTP Client (내장) | HTTP Client (내장) |
| Docker 디버깅 | Docker Extension | Docker Plugin | Docker Plugin |
| 데이터베이스 | SQLTools | Database Tools (내장) | Database Tools (내장) |
| 테스트 실행 | Test Explorer UI | 내장 Test Runner | 내장 pytest Runner |
| AI 어시스턴트 | GitHub Copilot / Continue | AI Assistant (내장) | AI Assistant (내장) |
| 코드 품질 | SonarLint | SonarLint Plugin | SonarLint Plugin |
| 원격 개발 | Remote - SSH / WSL | Gateway / Remote Dev | Gateway / Remote Dev |
디버깅 키보드 단축키 비교
| 작업 | VS Code (Mac) | VS Code (Win/Linux) | IntelliJ / PyCharm (Mac) | IntelliJ / PyCharm (Win/Linux) |
|---|---|---|---|---|
| 디버그 시작 | F5 | F5 | Ctrl+D | Shift+F9 |
| 실행 (디버그 없이) | Ctrl+F5 | Ctrl+F5 | Ctrl+R | Shift+F10 |
| Step Over | F10 | F10 | F8 | F8 |
| Step Into | F11 | F11 | F7 | F7 |
| Step Out | Shift+F11 | Shift+F11 | Shift+F8 | Shift+F8 |
| Continue (재개) | F5 | F5 | Cmd+Opt+R | F9 |
| Toggle Breakpoint | F9 | F9 | Cmd+F8 | Ctrl+F8 |
| Evaluate Expression | Debug Console | Debug Console | Alt+F8 | Alt+F8 |
| Stop | Shift+F5 | Shift+F5 | Cmd+F2 | Ctrl+F2 |
| Run to Cursor | - | - | Opt+F9 | Alt+F9 |
1) VS Code
실행 구성 (launch.json) 상세 예시
{
"version": "0.2.0",
"configurations": [
{
// Python FastAPI 디버깅
"name": "Python: FastAPI",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": ["app.main:app", "--reload", "--port", "8000"],
"console": "integratedTerminal",
"envFile": "${workspaceFolder}/.env",
"justMyCode": true // 라이브러리 코드 스킵 (false로 바꾸면 진입 가능)
},
{
// Node.js Express/NestJS 디버깅
"name": "Node: API Server",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/dist/index.js",
"preLaunchTask": "npm: build", // 빌드 후 실행
"runtimeArgs": ["--inspect-brk"],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"envFile": "${workspaceFolder}/.env",
"console": "integratedTerminal"
},
{
// Node.js 실행 중인 프로세스에 연결
"name": "Attach to Node",
"type": "node",
"request": "attach",
"port": 9229,
"restart": true, // 프로세스 재시작 시 자동 재연결
"sourceMaps": true
},
{
// Go Delve 디버깅
"name": "Go: Launch API",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/api",
"env": {
"GO_ENV": "development"
},
"args": ["-config", "config.dev.yaml"]
},
{
// Next.js 서버 사이드 디버깅
"name": "Next.js: Server",
"type": "node",
"request": "launch",
"runtimeExecutable": "npx",
"runtimeArgs": ["next", "dev"],
"sourceMaps": true,
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
},
{
// pytest 디버깅 (특정 테스트)
"name": "Python: pytest Current File",
"type": "debugpy",
"request": "launch",
"module": "pytest",
"args": ["${file}", "-v", "--no-header"],
"console": "integratedTerminal",
"justMyCode": false // 테스트 시 라이브러리 내부도 확인
}
],
"compounds": [
{
// 프론트+백엔드 동시 디버깅
"name": "Full Stack",
"configurations": ["Python: FastAPI", "Next.js: Server"]
}
]
}
브레이크포인트 활용법
조건부 브레이크포인트 설정 방법:
1. 라인 번호 좌측 클릭으로 브레이크포인트 설정
2. 브레이크포인트 우클릭 → "Edit Breakpoint..."
3. 조건 유형 선택:
- Expression: user.id === "U-9999" (조건이 true일 때만 중단)
- Hit Count: 100 (100번째 호출에서 중단)
- Log Message: "userId={user.id} total={total}" (중단 없이 로그만)
Exception Breakpoint 설정 방법:
1. Run → Add Configuration → 또는 Debug 패널 → BREAKPOINTS 섹션
2. "Add Function Breakpoint" 또는 언어별 Exception BP 추가
- Python: "Raised Exceptions" / "Uncaught Exceptions" 체크
- Node.js: "All Exceptions" / "Uncaught Exceptions" 체크
멀티프로세스 디버깅
// tasks.json — 디버그 전에 실행할 빌드 태스크
{
"version": "2.0.0",
"tasks": [
{
"label": "Start Docker DB",
"type": "shell",
"command": "docker compose up -d postgres redis",
"problemMatcher": []
}
]
}
launch.json의 compounds 설정으로 여러 프로세스를 동시에 디버깅할 수 있다. 프론트엔드와 백엔드를 동시에 실행하고, 각각에 독립적인 브레이크포인트를 설정할 수 있다.
프로파일링
- JS/TS: DevTools Performance/Memory (F12 → Performance 탭)
- Python: 터미널에서 py-spy 연동, 또는 debugpy의 profiling 옵션
- 추천 확장: Error Lens (인라인 에러 표시), GitLens (변경 이력 추적)
2) IntelliJ IDEA
Run/Debug Configuration 상세 예시
필수 표준화 항목:
1. JVM 옵션: -Xmx512m -XX:+HeapDumpOnOutOfMemoryError
2. 환경변수 파일: .env 또는 EnvFile 플러그인 연결
3. 활성 프로파일: -Dspring.profiles.active=dev
4. Working directory: $MODULE_DIR$ (모듈 루트 고정)
5. Before launch: Build 태스크 자동 실행 확인
<!-- .run/SpringBootApp.run.xml — Git에 포함하여 팀 공유 -->
<component name="ProjectRunConfigurationManager">
<configuration name="Spring Boot API" type="SpringBootApplicationConfigurationType">
<module name="api" />
<option name="SPRING_BOOT_MAIN_CLASS" value="com.example.ApiApplication" />
<option name="ACTIVE_PROFILES" value="dev" />
<envs>
<env name="DB_HOST" value="localhost" />
<env name="DB_PORT" value="5432" />
</envs>
<option name="VM_PARAMETERS"
value="-Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/" />
</configuration>
</component>
원격 디버그는 "Attach to process"보다 고정 포트 설정을 권장한다.
Remote Debug Configuration 설정:
1. Run → Edit Configurations → + → Remote JVM Debug
2. Host: localhost, Port: 5005
3. Command line arguments 복사하여 서버 실행 시 적용
4. "Auto restart" 체크하면 서버 재시작 시 자동 재연결
브레이크포인트 고급 기능
IntelliJ 브레이크포인트 고급 옵션 (우클릭 → More):
1. Condition: orderId.equals("ORD-1234")
→ 조건이 true일 때만 중단
2. Log message to console: "Processing order: " + orderId
→ 중단 없이 디버그 콘솔에 출력 (Logpoint)
3. Evaluate and log: order.getItems().size()
→ 표현식을 평가하고 결과를 로그로 출력
4. Remove once hit: 한 번 걸리면 자동 제거
→ 초기화 코드처럼 한 번만 확인할 때 유용
5. Disable until hitting another breakpoint
→ 특정 조건에 도달한 후부터 활성화 (체이닝)
6. Instance filter: 특정 객체 인스턴스에서만 중단
→ 멀티스레드 환경에서 특정 요청만 추적
Exception Breakpoint 설정:
1. Run → View Breakpoints (Cmd+Shift+F8 / Ctrl+Shift+F8)
2. + → Java Exception Breakpoints
3. NullPointerException, IllegalStateException 등 선택
4. "Caught exception" / "Uncaught exception" 체크
5. Class filters로 내 패키지만 필터링: com.example.*
멀티스레드 디버깅
멀티스레드 디버깅 설정:
1. 브레이크포인트 우클릭 → Suspend policy 설정
- All: 모든 스레드 중단 (기본값)
- Thread: 해당 스레드만 중단, 나머지는 계속 실행
2. Threads 패널에서:
- 각 스레드의 스택 트레이스 확인
- 스레드 간 전환하여 변수 상태 비교
- "Resume thread" 로 특정 스레드만 재개
3. 데드락 감지:
- Debug 패널 → 우클릭 → "Detect Deadlock"
- 자동으로 데드락 관련 스레드와 Lock 정보 표시
프로파일링
IntelliJ 내장 프로파일러 (Ultimate):
1. Run → Profile (CPU/Memory 선택)
2. 또는 실행 아이콘 옆 드롭다운 → "Profile with IntelliJ Profiler"
3. 결과:
- Flame Graph: 핫스팟 시각화
- Call Tree: 호출 관계별 시간 분포
- Method List: 함수별 총 시간/자체 시간
- Timeline: 시간축 기반 스레드별 활동
JFR 파일 분석:
1. .jfr 파일을 IntelliJ에서 직접 열기
2. Flame Graph / Call Tree로 상위 10개 함수부터 분석
3. Allocation 탭에서 메모리 할당 핫스팟 확인
3) PyCharm
실행 구성 상세 예시
PyCharm Run Configuration 표준화:
1. Django 서버:
- Type: Django Server
- Host: 0.0.0.0, Port: 8000
- Environment variables: .env 파일 연결
- Additional options: --settings=config.settings.dev
2. FastAPI (uvicorn):
- Type: Python
- Module name: uvicorn
- Parameters: app.main:app --reload --port 8000
- Working directory: $PROJECT_DIR$
- EnvFile 플러그인으로 .env 로드
3. pytest (단위 테스트):
- Type: pytest
- Target: tests/unit/
- Additional arguments: -v --tb=short
- Environment variables: TESTING=true
4. pytest (통합 테스트):
- Type: pytest
- Target: tests/integration/
- Additional arguments: -v --tb=long -x
- Environment variables: DB_HOST=localhost
# conftest.py에서 테스트용 디버그 설정
import pytest
@pytest.fixture(autouse=True)
def debug_sql_queries(settings):
"""테스트 중 SQL 쿼리 로그 출력"""
settings.DEBUG = True
settings.LOGGING = {
'version': 1,
'handlers': {'console': {'class': 'logging.StreamHandler'}},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
}
}
}
브레이크포인트 고급 활용
PyCharm 브레이크포인트 옵션:
1. Condition + Hit Count 조합:
- Condition: len(items) > 100
- 활성화 조건: Hit count >= 5
→ 아이템이 100개 초과인 요청이 5번째 이상일 때만 중단
2. Django/FastAPI 엔드포인트 진입점에 우선 배치:
- View 함수 첫 줄
- serializer.is_valid() 직후
- ORM 쿼리 실행 직전
3. Evaluate and Log:
- 브레이크포인트 우클릭 → "Evaluate and log"
- 예시: f"user={request.user}, method={request.method}"
- 중단 없이 디버그 콘솔에 출력
# 조건부 브레이크포인트 실전 예시
def process_batch(items):
for i, item in enumerate(items):
# PyCharm에서 이 라인에 조건부 BP 설정:
# Condition: item.status == "ERROR" and i > 50
# → 50번째 이후의 ERROR 아이템에서만 중단
result = transform(item)
save(result)
멀티스레드/멀티프로세스 디버깅
PyCharm 멀티스레드 디버깅:
1. Thread 패널에서 활성 스레드 목록 확인
2. 스레드 선택하여 개별 스택 트레이스 확인
3. 브레이크포인트의 Suspend policy:
- All Threads: 모든 스레드 중단
- Thread: 해당 스레드만 중단
Django + Celery 동시 디버깅:
1. Compound Run Configuration 생성
2. 구성 1: Django Server (runserver)
3. 구성 2: Python → celery -A config worker -l debug
4. 양쪽에 독립적 브레이크포인트 설정 가능
# gunicorn 멀티워커 디버깅 — 단일 워커로 제한
# gunicorn.conf.py
workers = 1 # 디버깅 시 워커 1개로 제한
timeout = 300 # 브레이크포인트에서 멈춰도 타임아웃 안 되게
accesslog = '-' # stdout으로 로그 출력
프로파일링
PyCharm 내장 프로파일러 (Professional):
1. Run → Profile 'configuration name'
2. 또는 실행 아이콘 옆 → "Profile"
3. 결과 분석:
- Call Graph: 함수 호출 관계와 시간 시각화
- Statistics: 함수별 호출 횟수/총 시간/자체 시간 테이블
- 느린 함수 클릭 → 소스코드로 바로 이동
Line Profiler 연동:
1. pip install line-profiler
2. @profile 데코레이터를 느린 함수에 적용
3. kernprof -l -v script.py 실행
4. 결과: 함수 내 각 라인별 실행 시간/호출 횟수
cProfile 통합:
1. Run → Profile → cProfile 선택
2. 결과를 .prof 파일로 저장
3. snakeviz로 시각화: snakeviz output.prof
# memory_profiler로 메모리 사용량 라인별 분석
from memory_profiler import profile
@profile
def load_dataset():
data = [] # 시작: 50 MiB
for chunk in read_chunks():
processed = transform(chunk) # 여기서 +200 MiB → 누수 의심
data.append(processed)
return data # 최종: 800 MiB
IDE 공통 베스트 프랙티스
1) 디버그 프로필을 코드처럼 관리
.vscode/launch.json,.run/,.idea일부 템플릿을 저장소에 포함- 팀원 온보딩 시 "실행 버튼 한 번"으로 재현 가능하게
.gitignore에서 개인 설정은 제외하되, 공통 실행 구성은 커밋
# .gitignore 예시
# IntelliJ — 개인 설정 제외, 공통 실행 구성은 포함
.idea/*
!.idea/runConfigurations/
!.idea/codeStyles/
# VS Code — launch.json은 포함
.vscode/*
!.vscode/launch.json
!.vscode/tasks.json
!.vscode/extensions.json
2) 브레이크포인트 계층화
- Level 1 (진입/경계): Controller/View 진입, 외부 API 호출 직전/직후. 항상 먼저 설정한다.
- Level 2 (분기 조건): if/switch 분기, 유효성 검사. 원인이 좁혀지면 설정한다.
- Level 3 (내부 루프): 반복문 내부. 반드시 조건부로만 설정한다.
3) 프로파일링을 조기 시작
- "느리다" 체감하면 바로 60초 샘플링. 감으로 최적화하면 잘못된 곳을 고치게 된다.
- flamegraph 상위 3개 핫스팟 함수부터 집중. 나머지는 효과가 미미하다.
- 최적화 전/후 프로파일을 비교하여 개선 효과를 수치로 검증한다.
4) 재현 스크립트 자동화
- Makefile/npm script/pytest marker로 고정
- 실행 인자 누락으로 인한 "내 로컬만 됨" 방지
- docker compose로 DB/캐시 등 의존 서비스 자동 실행 포함
# Makefile 예시
.PHONY: debug test profile
debug-api:
docker compose up -d postgres redis
python -m debugpy --listen 5678 --wait-for-client -m uvicorn app.main:app --reload
debug-test:
pytest -x --pdb -v tests/
profile-api:
py-spy record -o profile.svg --pid $$(pgrep -f uvicorn)
장애 대응용 종합 체크리스트
디버그 환경 준비
- 실행 구성(launch.json / Run Configuration)이 팀 표준에 맞게 설정되어 있는가?
- 환경변수 파일(.env)이 올바르게 연결되어 있는가?
- Source map / 디버그 심볼이 활성화되어 있는가?
- 필요한 확장/플러그인이 설치되어 있는가?
브레이크포인트 전략
- Exception breakpoint가 활성화되어 있는가? (NPE, TypeError 등)
- 진입점(Level 1)에 브레이크포인트를 먼저 설정했는가?
- 루프 내 브레이크포인트에 조건을 설정했는가?
- Logpoint를 활용하여 서비스 중단 없이 값을 확인했는가?
재현 및 관측
- 같은 입력으로 재현되는가?
- Request ID로 전체 경로 추적되는가?
- Watch Expression에 핵심 변수를 등록했는가?
- Evaluate Expression으로 가설을 즉시 검증했는가?
프로파일링
- CPU 프로파일을 캡처했는가?
- 메모리 프로파일(heap dump/snapshot)을 확인했는가?
- flamegraph에서 상위 핫스팟을 식별했는가?
- 최적화 전/후 수치 비교를 했는가?
해결 후 후속
- 근본 원인(root cause)을 식별하고 문서화했는가?
- 회귀 테스트를 작성했는가?
- 디버그 실행 구성을 업데이트하여 저장소에 커밋했는가?
- 팀에 원인과 재발 방지 방법을 공유했는가?
IDE 디버깅 트러블슈팅 FAQ
IDE에서 디버깅할 때 자주 마주치는 문제와 해결 방법을 정리했다.
| 증상 | 원인 | 해결 |
|---|---|---|
| 브레이크포인트가 회색(unverified) | 소스맵 경로 불일치 또는 빌드 안 됨 | outFiles/소스맵 경로 확인, 재빌드 후 재시작 |
| 브레이크포인트 히트가 안 됨 | 다른 프로세스/포트에 연결됨 | attach 설정의 port/pid 확인, lsof -i :9229 |
변수값이 undefined/<optimized out> | 컴파일러 최적화, minification | Go: -gcflags="all=-N -l", JS: 소스맵 활성화 |
| "Cannot connect to runtime" | 프로세스가 디버그 모드로 안 떴음 | --inspect/-agentlib:jdwp 옵션 확인 |
| Watch에서 "Expression not available" | 스코프 밖이거나 인라인 최적화 | 해당 스코프까지 step-into 후 재시도 |
| Hot Reload 후 브레이크포인트 안 걸림 | 재로드 후 매핑이 깨짐 | 디버거 재시작, 또는 브레이크포인트 재설정 |
| Docker 컨테이너 디버깅 연결 실패 | 포트 매핑 누락 또는 바인드 주소 문제 | -p 5005:5005 확인, 0.0.0.0 바인딩 확인 |
원격 디버깅 퀵스타트 — IDE별 비교
원격 서버에 디버거를 붙이는 최소 설정을 IDE별로 비교한다. 상세 가이드는 원격 디버깅 실전 가이드를 참고한다.
| 단계 | VS Code | IntelliJ IDEA | PyCharm |
|---|---|---|---|
| 1. SSH 터널 | ssh -N -L 5005:127.0.0.1:5005 user@server | 동일 | 동일 |
| 2. IDE 설정 | launch.json attach 타입 추가 | Run > Edit Configurations > Remote JVM Debug | Run > Edit Configurations > Python Remote Debug |
| 3. 경로 매핑 | localRoot/remoteRoot 또는 pathMappings | 자동 (같은 프로젝트) 또는 module classpath | Path mappings 설정 |
| 4. Attach | F5 (해당 설정 선택) | Debug 버튼 | Debug 버튼 |
| 비용 | 무료 | Ultimate 라이선스 | Professional 라이선스 |
결론
IDE는 편집기가 아니라 문제 탐지 장비다. 실행 구성/브레이크포인트/프로파일링을 표준화하면, 개인 역량이 아니라 팀 시스템으로 디버깅 속도를 끌어올릴 수 있다.
빠른 디버깅은 천재성이 아니라, 잘 설계된 IDE 습관에서 나온다.
팀원 누구나 "실행 버튼 한 번"으로 문제를 재현하고, 브레이크포인트 하나로 원인을 좁히며, 프로파일링 결과로 근거를 남길 수 있어야 한다. 그것이 IDE 디버깅의 궁극적인 목표다.
실전 장애 사례는 언어×프레임워크 장애 사례집에서, 원격 디버깅 전체 절차는 원격 디버깅 실전 가이드에서 확인할 수 있다.
IDE Debugging Playbook: VS Code, IntelliJ IDEA, and PyCharm
This post is part 3 of a 5-part debugging series.
Why this guide matters
Most debugging failures are not caused by missing tools, but by missing workflow discipline:
- reproducibility (same input, same env, same version)
- observability (logs + metrics + traces + breakpoints)
- hypothesis-driven narrowing (one change at a time)
This article focuses on execution patterns that work under production pressure.
Practical workflow
- Freeze reproduction conditions.
- Add breakpoint/logpoints only on boundaries.
- Capture one profile (CPU or memory) before changing code.
- Verify fix with regression test + replay scenario.
- Record root cause and prevention rule in team docs.
Operational checklist
- Reproducible command/script exists.
- Failure signal is measurable (error rate/latency/memory).
- Profiling artifact is attached (flamegraph/heap/thread dump).
- Rollback strategy is prepared before risky deploy.
- Postmortem includes prevention action owner and due date.
Korean original
For deeper examples and Korean explanations, read the original:
Quiz
Q1: What is the main topic covered in "IDE Debugging Playbook: VS Code, IntelliJ IDEA, and
PyCharm"?
Part 3 of the debugging series. A practical, copy-paste-friendly guide with reproducible steps, breakpoint strategy, profiling checkpoints, and team-level checklists.
Q2: Why this guide matters?
Most debugging failures are not caused by missing tools, but by missing workflow discipline:
reproducibility (same input, same env, same version) observability (logs + metrics + traces +
breakpoints) hypothesis-driven narrowing (one change at a time) This article focuses on execu...
Q3: Explain the core concept of Practical workflow.
Freeze reproduction conditions. Add breakpoint/logpoints only on boundaries. Capture one profile
(CPU or memory) before changing code. Verify fix with regression test + replay scenario. Record
root cause and prevention rule in team docs.
Q4: What are the key aspects of Operational checklist?
[ ] Reproducible
command/script exists. [ ] Failure signal is measurable (error rate/latency/memory). [ ] Profiling
artifact is attached (flamegraph/heap/thread dump). [ ] Rollback strategy is prepared before risky
deploy.
Q5: How does Korean original work?
For deeper examples and Korean explanations, read the original:
/blog/devops/2026-03-07-devops-debugging-by-ide-vscode-intellij-pycharm