diff --git a/README.md b/README.md index c456b45..a51b2e1 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,9 @@ VITE_API_TARGET=http://localhost:18080 npm run dev 현재 지원 범위는 다음과 같습니다. -- Java 기반 Spring Boot와 로컬 단일 JVM 또는 2개 서비스 데모 +- Java 기반 Spring Boot 단일 프로젝트와 최대 10개 프로젝트의 로컬 Workspace 분석 +- 단일 JVM Trace와 동기 HTTP로 연결된 2개 Spring Boot JVM 분산 Trace 데모 +- 서비스별 Agent profile·실행 명령과 실제 `service.name` 기반 Waterfall·그래프 경계 - Spring MVC, JDBC, Lettuce 등 Java Agent가 지원하는 자동 계측 - Gradle, Maven, 실행 JAR용 Agent 명령 생성 - 메모리 기반 Trace 저장과 15초 수집 timeout @@ -170,7 +172,8 @@ VITE_API_TARGET=http://localhost:18080 npm run dev 현재 제외 범위: - Kotlin과 합성 annotation의 추측 분석 -- 메시지 큐와 비동기 consumer를 포함한 분산 Trace +- Kafka·RabbitMQ 같은 메시지 큐와 비동기 consumer Trace +- 세 개 이상 서비스의 공개 데모와 production 규모 분산 Trace 운영 - 실행 중 JVM 동적 attach - 인증, 영구 저장, sampling 관리 - production APM 운영과 AI 원인 분석 @@ -192,10 +195,12 @@ cd backend && ./gradlew test --rerun-tasks cd ../examples/distributed-trace-lab/order-service && ./gradlew test cd ../product-service && ./gradlew test cd ../../../frontend && npm run test && npm run lint && npm run build +cd .. && docker compose up --build --wait +cd frontend && npx playwright install chromium && npm run test:e2e cd .. && docker compose config && ./scripts/verify-demo.sh ``` -GitHub Actions는 backend, Trace Lab, frontend, 실제 Docker Compose E2E를 PR마다 실행합니다. +GitHub Actions는 backend, 두 Trace Lab, frontend 단위 검사, 실제 Chromium UI E2E와 Docker API 시나리오를 PR마다 실행합니다. 브라우저 E2E는 정상 Order→Product 호출과 Product PostgreSQL timeout 전파를 검증하고, `verify-demo.sh`는 cache·Redis 장애를 포함한 6개 시나리오를 검증합니다. 비데모 Spring Boot 3.4.1 프로젝트에서도 Java 224개, Controller 15개, REST endpoint 42개를 분석하고 `Controller → Redis PING` 실제 Trace를 수집했습니다. 자세한 근거는 [v0.1.1 외부 프로젝트 검증](docs/v0.1.1-external-project-validation.md)에 기록했습니다. diff --git a/docs/external-runtime-tracing-design.md b/docs/external-runtime-tracing-design.md index a7e0694..5c7e2cc 100644 --- a/docs/external-runtime-tracing-design.md +++ b/docs/external-runtime-tracing-design.md @@ -117,8 +117,17 @@ Sample traces retain the fixed StackFlow component graph. OpenTelemetry traces u ## Current Limits - Workspace analysis and Agent profile generation support up to ten local Spring Boot projects; the bundled demo runs Order and Product as two local JVMs. +- The validated distributed path is synchronous HTTP propagation from Order to Product. The collector can merge all participating `service.name` values, but three-or-more-service operation is not a published demo guarantee yet. - JVM restart is required; dynamic attach is not supported. -- Cross-service spans are collected, but service-grouped Waterfall and graph presentation is not implemented yet. +- Waterfall rows display the emitting service and explicit parent-child service boundaries. The graph groups span nodes by service and labels cross-service edges from runtime context only. +- Message brokers and asynchronous consumers are not covered by the current HTTP response plus two-second quiet-period completion rule. - No OTLP Logs ingestion. Exception details are collected only from exception events attached to OTLP spans. - No authentication, durable storage, sampling administration, or production retention. - Libraries outside Java Agent support may produce partial traces. + +## Automated Acceptance + +The Docker Compose job validates both contracts against real Java Agent spans: + +- Playwright drives the UI through a normal Order-to-Product request and a Product PostgreSQL timeout propagated as Order HTTP 504. It checks workspace selection, service boundaries, graph grouping, failure cause, Inspector detail, and mobile horizontal overflow. +- `scripts/verify-demo.sh` validates cache miss, cache hit, Redis fallback, direct PostgreSQL timeout, distributed success, and distributed timeout through the backend APIs. diff --git a/docs/product-direction-and-implementation-plan.md b/docs/product-direction-and-implementation-plan.md index b0be8f0..e5ad54f 100644 --- a/docs/product-direction-and-implementation-plan.md +++ b/docs/product-direction-and-implementation-plan.md @@ -1,8 +1,7 @@ # StackFlow Product Direction and Implementation Plan -Date: 2026-07-29 -Status: Draft -Branch context: `feat/9-external-api-target-base-url` +Date: 2026-08-28 +Status: Active ## Purpose @@ -33,46 +32,26 @@ The initial target should not be: - Production incident response. - Full APM replacement. -- Distributed tracing across microservices. +- Production-scale trace ingestion across arbitrary services. - Security-sensitive production monitoring. ## Current State -The repository already has the first runtime trace slice: +The repository now provides an end-to-end local tracing workbench: -- Spring Boot backend. -- React + Vite frontend. -- Sample product APIs. -- SSE-based live trace streaming. -- Request flow graph. -- Node detail panel. -- Response body panel. -- Recent trace history. - -The repository also has early static project analysis: - -- Analyze a Spring Boot project path. -- Detect REST controllers. -- Extract API mappings. -- Group APIs into domains. -- Summarize layers such as Controller, Service, Repository, Cache, Store, DTO, and Domain. - -The repository is adding external target execution: - -- Configure a target base URL for an analyzed Spring Boot project. -- Call the selected external endpoint through the StackFlow backend proxy. -- Compose query parameters, headers, and JSON request body for external endpoint execution. -- Show HTTP status, duration, content type, response body, and transport error message. -- Show the request summary next to the response so users can compare what was sent and what came back. -- Keep external execution results separate from runtime trace evidence. -- Preview a browser-selected local folder, while keeping explicit project path input for backend analysis because browser mode cannot reliably expose the absolute local path. +- Analyze one Spring Boot project or a workspace containing up to ten independent Gradle or Maven services. +- Detect controllers, mappings, domains, layers, infrastructure evidence, and analysis coverage warnings. +- Generate service-specific OpenTelemetry Java Agent profiles without changing target source or build files. +- Execute selected APIs through the backend proxy with a StackFlow-owned W3C `traceparent`. +- Receive OTLP HTTP/protobuf spans and render Waterfall, graph, events, failure propagation, exception detail, and response preview. +- Correlate synchronous HTTP spans across the bundled Order and Product JVMs by actual `spanId`, `parentSpanId`, and `service.name`. +- Verify the representative distributed UI flows with Playwright and the six infrastructure scenarios with Docker Compose. Current limitation: -- External project analysis and StackFlow sample runtime tracing are still separate concepts. -- Selecting an analyzed external API does not automatically mean StackFlow can trace that external app internally. -- Without instrumentation inside the external app, StackFlow can only show structure and estimated flow. -- External API execution confirms the endpoint response, but it still cannot prove the internal Controller -> Service -> Repository path. +- Runtime tracing still requires restarting each target JVM with the generated Agent command. +- The validated distributed demo is two local Spring Boot JVMs connected by synchronous HTTP. +- Message brokers, asynchronous consumers, authentication, durable storage, and production retention are not supported. ## Product Information Architecture @@ -266,7 +245,7 @@ Reason: Scope: - Turn static analysis into an instrumentation profile for a local external Spring Boot application. -- Trace one Spring Boot JVM with the OpenTelemetry Java Agent and OTLP HTTP/protobuf. +- Trace one JVM or a local workspace of synchronously connected Spring Boot JVMs with the OpenTelemetry Java Agent and OTLP HTTP/protobuf. - Keep the target project's source and Gradle/Maven files unchanged. Implementation: @@ -276,6 +255,8 @@ Implementation: - Receive standard OTLP traces through `POST /v1/traces`. - Inject a StackFlow-owned W3C `traceparent` when `POST /api/external/request` runs with trace capture enabled. - Join received spans by trace ID and build the actual graph from `spanId -> parentSpanId`. +- Analyze workspace services separately, generate one Agent profile per service, and preserve entry and participating service names. +- Complete distributed collection after the entry SERVER span, HTTP response, and a two-second quiet period, with a 15-second hard timeout. - Keep sample traces on the existing fixed graph and use a dynamic graph only for `source=OPENTELEMETRY`. - Distinguish HTTP execution failure from `TRACE_COLLECTION_TIMEOUT` when no spans arrive for 15 seconds. @@ -286,9 +267,9 @@ Reason: Limits: -- First support is local development and one Spring Boot JVM. +- Supported operation is local development; the bundled and automated distributed acceptance path uses two Spring Boot JVMs connected by synchronous HTTP. - The target JVM must be restarted with the Agent; dynamic attach is not supported. -- Distributed services, authentication, persistence, sampling controls, and production APM operation remain later phases. +- Message queues, asynchronous consumers, authentication, persistence, sampling controls, and production APM operation remain later phases. - See `docs/external-runtime-tracing-design.md` for the executable contract and metadata policy. ## Implementation Rules Going Forward @@ -306,8 +287,8 @@ The UI now separates the workflow into three evidence stages: - `Project`: static Spring structure and analysis coverage. - `Request`: API input, execution target, and HTTP response. -- `Trace`: actual OTLP Waterfall, failure propagation, response preview, and exception detail. +- `Trace`: actual OTLP Waterfall, service boundaries, failure propagation, response preview, and exception detail. -The next compatibility task is to normalize both legacy and current OpenTelemetry code semantic keys. In particular, the Java Agent can emit `code.function` while the current Inspector also expects `code.function.name`. Supporting both keys will keep class and method location summaries accurate across Agent versions. +Legacy and current OpenTelemetry code semantic keys are normalized in the frontend display layer. A non-demo Spring Boot 3.4.1 project and the two-service Order·Product workspace are both recorded acceptance paths. -After that compatibility fix, validate one non-demo Spring Boot project end to end and publish the verified state as `v0.1.1`. +The next delivery task is portfolio packaging: align public screenshots and demo media with the distributed Trace flow, document the verified limits, and publish a release from a clean, green `main`. diff --git a/examples/distributed-trace-lab/README.md b/examples/distributed-trace-lab/README.md index 4a90523..a6aff0b 100644 --- a/examples/distributed-trace-lab/README.md +++ b/examples/distributed-trace-lab/README.md @@ -21,6 +21,13 @@ docker compose up --build --wait StackFlow UI는 [http://localhost:5173](http://localhost:5173), backend는 `http://localhost:18080`에서 실행됩니다. +UI는 `/workspace/distributed-trace-lab`을 자동 분석합니다. + +1. 프로젝트 구조에서 `order-service`를 선택합니다. +2. API 요청에서 `GET /lab/orders/{orderId}` 또는 timeout endpoint를 선택합니다. +3. 기본 `orderId`인 `2001`로 `요청 보내고 Trace 보기`를 실행합니다. +4. Trace의 Waterfall과 그래프에서 `order-service → product-service` 경계를 확인합니다. + ## 분산 Trace API ```bash @@ -51,7 +58,21 @@ curl http://localhost:8092/lab/orders/2001/product-timeout - `order-service`: 주문 매핑과 Product HTTP Client 호출 - `product-service`: Redis cache, PostgreSQL 조회와 실제 query timeout -PR 2 단계의 StackFlow 기본 화면은 Order Service를 분석합니다. Workspace 전체 서비스 선택 UI는 후속 작업에서 추가합니다. 정적 workspace API는 `/workspace/distributed-trace-lab` 아래 두 서비스를 각각 분석합니다. +StackFlow는 Workspace 아래 두 서비스를 각각 분석하고 서비스 선택을 도메인·API 선택보다 먼저 표시합니다. 각 서비스의 Java Agent는 동일한 W3C Trace Context를 이어받으며, 서비스 관계는 정적 추측이 아니라 실제 span 부모·자식 관계로만 표시합니다. + +## 자동 검증 + +```bash +# 6개 API·인프라 시나리오 +./scripts/verify-demo.sh + +# 정상 분산 요청과 timeout UI 시나리오 +cd frontend +npx playwright install chromium +npm run test:e2e +``` + +Playwright는 정상 요청의 Waterfall·그래프 서비스 경계와 timeout 요청의 PostgreSQL 원인·Order 전파 경로, 390×844 화면 overflow를 검증합니다. 종료: