56 lines
5.3 KiB
Markdown
56 lines
5.3 KiB
Markdown
---
|
||
title: 2026-06-14 일일 노트
|
||
source_type: daily-note
|
||
status: raw
|
||
tags: [daily, ca-tmpl, ca-skeleton, clean-architecture, logging, observability]
|
||
date: 2026-06-14
|
||
branches: [
|
||
feature-log-management-contract
|
||
]
|
||
---
|
||
|
||
# 2026-06-14
|
||
|
||
> Layer: `raw/daily-notes/` — 그날의 혼합 일일 기록. 그 자체는 wiki로 옮기지 않으며, `/ingest`가 promotable 항목만 추출.
|
||
|
||
## 활성 브랜치
|
||
|
||
- `feature-log-management-contract` (implemented) — [[raw/branch-notes/feature-log-management-contract]]
|
||
|
||
## 한 일
|
||
|
||
feature-log-management-contract Phase C2 전면 구현 — 문서화돼 있던 DRIFT-1~6 + sampling 전부 코드로 해소.
|
||
|
||
- 사용자 결정 2건 확정: **Q1**=dependency 실패 레벨 어댑터종류 분리(optional fail-open WARN / core HTTP ERROR), **Q2**=full HMAC pseudonymization.
|
||
- DRIFT-2 Layer 1 masking: `LogMaskingPatterns`(정규식 SSOT) → `SecretMaskingJsonGeneratorDecorator`(JSON) + `SecretMaskingMessageConverter`(`%maskedMsg`).
|
||
- DRIFT-1/D10: `logback-spring.xml` `<springProfile>` 분기(local/dev pattern vs prod JSON).
|
||
- DRIFT-3: `RequestLoggingFilter` uri_template.
|
||
- DRIFT-4: `OutboundDependencyLogger` snake_case + dependency_type + WARN + 5 callers.
|
||
- DRIFT-5: `MetricsAsyncAppender` → `log.appender.dropped.total`.
|
||
- DRIFT-6: `UserPrincipalPseudonymizer`(port) + `HmacUserPrincipalPseudonymizer`(adapter-identifier) + `PseudonymizationConfig`/`PrivacySettings`(app-bootstrap) + filter 배선.
|
||
- sampling: `SamplingTurboFilter`.
|
||
- 오케스트레이션: Task 1~4 는 `ca-implementer` 디스패치, Task 5(logback XML/custom appender/turbofilter/masking)는 API 검증(MaskingJsonGeneratorDecorator, AsyncAppenderBase, springProfile) 후 메인 에이전트 직접 구현. 리뷰 체인 3단계 ALL PASS.
|
||
|
||
## 배운 점
|
||
|
||
- `LogstashEncoder`(JSON)는 PatternLayout 을 우회 → `%replace` 마스킹 무력. JSON 은 `MaskingJsonGeneratorDecorator` 필요. → [[raw/blog-topics/logback-layer1-secret-masking-json-vs-pattern-2026-06-14]]
|
||
- `AsyncAppender` 드롭 결정론 테스트: `discardingThreshold > queueSize` 트릭. → [[raw/interviews/deterministic-logback-asyncappender-drop-metric-test-2026-06-14]]
|
||
|
||
## 트러블슈팅
|
||
|
||
- `@Component` 필터에 생성자 의존성 추가 → `@WebMvcTest` 슬라이스(`OperationalContractRuntimeTest`) 컨텍스트 로드 실패. `@Import(PseudonymizationConfig.class)` 로 해소. → [[raw/errors/webmvctest-component-filter-constructor-dep-breaks-slice-2026-06-14]]
|
||
- `ca-implementer` Task 4 디스패치가 중간 truncate(5 callers 중 2개만 수정) → 메인 에이전트가 잔여 3 callers + 4 test 단언을 직접 마무리.
|
||
- local profile 실행 시 logback status 경고 3종 발견. (1)`<conversionRule converterClass=...>` deprecated → `class` 로 교체(내 변경, 수정 완료 + `SecretMaskingMessageConverterTest` 로 `class` 등록 + 마스킹 검증). (2)`<if>`-in-`<root>` + (3)`<if condition=...>` 속성 deprecated **해소(2026-06-14, 사용자 재요청)**: Janino `<if condition='property(K).equals(V)'>` 6곳 → logback 1.5.20+ 내장 `<condition class="ch.qos.logback.core.boolex.PropertyEqualityCondition"><key>K</key><value>V</value>` (조회 경로 `OptionHelper.propertyLookup(local,context)` 가 Janino 와 동일 → `<springProperty scope=context>` 값 그대로 읽어 동작 무변경). `<root>` 내 `<if>` 3개는 logback 권고대로 `<root>` 를 top-level `<condition>+<if>` 로 감싸 un-nest(ASYNC×FILE 2×2, 한 번에 하나만 활성). **janino 의존성(build.gradle) 제거** — dead dep(소스 `condition=` 0건) + Janino 동적 코드 컴파일 보안취약(2027 제거예정) 해소. 검증: logback-core 1.5.34(`dependencyInsight`) + `bootRun`(local) `|-WARN/|-ERROR` 0건 + 정상 기동(Tomcat:8080) + local PatternLayout 분기 정상. **owner 정정**: 토글 구조는 base-template 커밋 f9ad280("ca 구조 변경") 유래, 파일 owner 는 [[raw/branch-notes/feature-log-management-contract]] (D4 logging 바인딩, 최신 touch d10a751) — 직전 `migration-startup-contract D8` 귀속은 conflation(D8 은 build.gradle 인접 `logstash-logback-encoder` 줄을 govern). 기록: owner § Audit & Findings DRIFT-7. local=human-readable PatternLayout 분기(D10)는 의도대로 동작.
|
||
|
||
## 면접·포트폴리오로 옮길 만한 것
|
||
|
||
- [[raw/interviews/deterministic-logback-asyncappender-drop-metric-test-2026-06-14]]
|
||
- [[raw/blog-topics/logback-layer1-secret-masking-json-vs-pattern-2026-06-14]]
|
||
|
||
## 내일로 넘긴 것
|
||
|
||
- D9 전용 audit appender(생산자 부재 + retention은 data-retention 소유 → 보류).
|
||
- ~~pre-existing ArchUnit 실패(`OutboundHttpSettings` B7 false-positive, commit d702572)~~ **해결(사용자 요청)**: `CleanArchitectureTest` B7 규칙 `outbound_adapter_method_returns_only_domain_or_primitives` 에 `@ConfigurationProperties` 제외 추가(기존 `@Configuration` 제외와 동일 패턴). 세팅 홀더는 외부 응답 매핑 surface 가 아니라 config 바인딩 타입 → ACL 누출 대상 아님. 규칙의 실제 보호(외부 응답 타입 누출 차단)는 그대로 — 순수 filter narrowing. `:app-bootstrap:test` 0 실패.
|
||
- ~~logback `<if>`-in-`<root>` / `condition` 속성 deprecation 정리(사용자 재요청)~~ **해결(2026-06-14)**: 트러블슈팅 §(2)/(3) — Janino→내장 `PropertyEqualityCondition` + `<root>` un-nest + janino dep 제거, `bootRun` 검증 완료.
|
||
- 사용자 커밋 대기.
|