Debug Tools

Kosmos DSL Debug Tools는 DSL 렌더링 과정과 SSR 파이프라인을 실시간으로 추적하기 위한 도구입니다. 개발자는 이 도구를 통해 렌더링 속도, Fragment 호출 순서, Cache Hit 상태를 명확히 파악할 수 있습니다.

목표: SSR 렌더링을 “블랙박스”가 아닌 “투명한 실행 로그”로 시각화하는 것.

1. 개요

Kosmos Debug Tools는 RenderContext 기반으로 작동하며, 렌더링 전후 시점별 이벤트를 후킹하여 개발자가 렌더링 흐름을 추적할 수 있도록 합니다.

Controller → Service → PageModel
   ↓
RenderContext.startTrace()
   ↓
Template / Fragment / Component render()
   ↓
RenderContext.log(tag, time)
   ↓
RenderContext.printSummary()

2. RenderContext Debug 모드

RenderContext는 Kosmos의 렌더링 컨텍스트로, 요청 단위로 언어(locale), 사용자 정보, 디버그 상태를 관리합니다.

public class RenderContext {

    private boolean debugMode = false;
    private final Map<String, Long> traceMap = new LinkedHashMap<>();

    public void enableDebug() { this.debugMode = true; }
    public boolean isDebug() { return debugMode; }

    public void trace(String tag) {
        if (!debugMode) return;
        traceMap.put(tag, System.nanoTime());
    }

    public void printSummary() {
        if (!debugMode) return;
        System.out.println("=== KOSMOS DEBUG TRACE ===");
        traceMap.forEach((k,v) -> System.out.printf("%-40s : %8.3f ms%n", k, v / 1_000_000.0));
    }
}

활성화 방법: 디버그 모드는 개발 환경(Spring profile=dev)에서 자동 활성화되며, 수동으로는 다음과 같이 지정할 수 있습니다.

RenderContext ctx = new RenderContext();
ctx.enableDebug();
HtmlComponent page = new EstimationMainPage(model);
String html = page.render(ctx);
ctx.printSummary();
출력 예시:
=== KOSMOS DEBUG TRACE ===
FragEstimateStepCategory              :    2.314 ms
FragEstimateStepFeatures              :    4.821 ms
FragEstimateStepOptions               :    3.902 ms
CompToggleGroup                       :    1.105 ms
PageTemplate.buildContent()           :    0.315 ms
----------------------------------------------
TOTAL                                 :   12.457 ms

3. Trace API

Kosmos DSL은 내부적으로 Trace API를 제공합니다. 각 Fragment나 Component는 렌더링 전후에 trace 이벤트를 남겨 성능 분석에 활용할 수 있습니다.

// 예시: Fragment에 트레이스 추가
public class FragEstimateStepFeatures implements HtmlComponent {
  @Override
  public String render(RenderContext ctx) {
    ctx.trace("FragEstimateStepFeatures:start");
    String html = El.div().css("step-features").child(...).render();
    ctx.trace("FragEstimateStepFeatures:end");
    return html;
  }
}

trace 로그는 System.out 또는 SLF4J logger에 전달되어, Spring Boot Actuator나 Logback File Appender를 통해 저장할 수 있습니다.

4. Kosmos Debug Console

브라우저에서 직접 렌더링 타임라인을 시각화하는 debug-console.js를 제공합니다. 이 스크립트는 HTML 주석으로 삽입된 <!-- KOSMOS_TRACE: ... --> 로그를 파싱해 표시합니다.

<script src="/assets/js/debug-console.js"></script>

console은 다음과 같은 기능을 제공합니다:

  • Fragment별 렌더링 시간 막대그래프
  • Cache Hit / Miss 비율 시각화
  • 렌더링 중 발생한 예외 표시
// 예시 HTML 주석 로그
<!-- KOSMOS_TRACE:FragDocsMainContent=3.85ms -->
<!-- KOSMOS_TRACE:FragDocsMainNavTree=1.22ms -->
Note: 디버그 콘솔은 RenderContext.isDebug() == true일 때만 주석을 삽입합니다.

5. DSL Validation Logger

Kosmos DSL은 잘못된 HTML 구조(예: VoidTag에 children 추가 등)를 감지하여 DslValidationLogger를 통해 경고를 출력합니다.

public class DslValidationLogger {
  public static void warn(String msg) {
    System.err.println("[KOSMOS][WARN] " + msg);
  }
}

// 사용 예
if (this instanceof VoidTag && !children.isEmpty()) {
  DslValidationLogger.warn("VoidTag cannot have children: " + tagName);
}
주의: Validation 로그는 실제 렌더링에는 영향을 주지 않지만, CI 환경에서 코드 품질 점검에 활용할 수 있습니다.

6. 성능 모니터링 (PerfStats)

Kosmos는 각 요청의 평균 렌더링 시간과 최대 소요 시간을 기록하는 PerfStats 유틸리티를 제공합니다.

public class PerfStats {
  private static final LongAdder total = new LongAdder();
  private static final AtomicLong max = new AtomicLong();

  public static void record(long nanos) {
    total.add(nanos);
    max.accumulateAndGet(nanos, Math::max);
  }

  public static void print() {
    System.out.printf("Avg: %.3f ms, Max: %.3f ms%n",
        total.sum() / 1_000_000.0, max.get() / 1_000_000.0);
  }
}

이 유틸리티는 RenderContext.trace()와 함께 사용되어 SSR 페이지의 평균 응답시간을 모니터링합니다.

7. 주의사항

  • Debug 모드는 운영 환경에서 비활성화해야 합니다.
  • Trace 출력은 I/O를 유발하므로, 렌더링 지연에 영향을 줄 수 있습니다.
  • PerfStats는 Dev/Test 단계에서만 활성화 권장.
권장 설정: spring.profiles.active=dev 환경에서만 RenderContext.enableDebug() 자동 실행.

다음으로