# Vav2Player - Testable Hybrid Logging Architecture Design ## 🎯 **λͺ©ν‘œ** - **ν™•μž₯ κ°€λŠ₯ν•œ λ‘œκΉ…**: λ‹€μ–‘ν•œ 좜λ ₯ λŒ€μƒ 지원 (Console, Debug, Network, File) - **MVVM ν˜Έν™˜**: Model-ViewModel-View νŒ¨ν„΄κ³Ό μ™„λ²½ 톡합 - **ν…ŒμŠ€νŠΈ κ°€λŠ₯**: Unit Testμ—μ„œ λ‘œκΉ… λ™μž‘ 검증 κ°€λŠ₯ - **개발자 μΉœν™”μ **: κ°„λ‹¨ν•œ API둜 μ–΄λ””μ„œλ“  μ‰½κ²Œ μ‚¬μš© ## πŸ—οΈ **μ•„ν‚€ν…μ²˜ ꡬ쑰** ### **전체 ꡬ쑰도** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ View Layer β”‚ β”‚ ViewModel β”‚ β”‚ Model Layer β”‚ β”‚ (LogMessagePage)│◄────(LogPageViewModel)│◄──── (LogManager) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ILogOutput Interface β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ ConsoleLogOutputβ”‚ DebugLogOutput β”‚ FileLogOutput β”‚NetworkLog β”‚ β”‚ (stdout) β”‚ (VS Output) β”‚ (.log file) β”‚(future) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### **μ»΄ν¬λ„ŒνŠΈ κ°„ 관계** ``` [VideoPlayerControl] β”‚ β–Ό [LogManagerProvider::GetInstance()] ─┐ β”‚ β”‚ (Production) β–Ό β–Ό [Real LogManager] ◄──── or ───► [Mock LogManager] (Testing) β”‚ β–Ό [ILogOutput Implementations] ``` ## πŸ”§ **핡심 μ»΄ν¬λ„ŒνŠΈ** ### **1. Model Layer** #### **ILogManager (Interface)** ```cpp class ILogManager { public: virtual void LogInfo(const std::wstring& message, const std::wstring& source) = 0; virtual void LogVideoLoad(const std::wstring& filename, bool success) = 0; virtual void AttachLogOutput(std::unique_ptr output) = 0; // ... 기타 λ‘œκΉ… λ©”μ„œλ“œ }; ``` #### **LogManager (μ‹€μ œ κ΅¬ν˜„μ²΄)** - Singleton νŒ¨ν„΄ - ILogManager μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„ - 닀쀑 ILogOutput 관리 - Thread-safe 둜그 데이터 μ €μž₯ #### **MockLogManager (ν…ŒμŠ€νŠΈμš©)** - ILogManager μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„ - 둜그 호좜 기둝 및 검증 κΈ°λŠ₯ - Unit Testμ—μ„œ λ‘œκΉ… λ™μž‘ 검증 ### **2. Infrastructure Layer** #### **LogManagerProvider (Global Access)** ```cpp class LogManagerProvider { public: static ILogManager& GetInstance(); // Production: LogManager, Test: MockLogManager static void SetInstance(std::shared_ptr mock); // Testμ—μ„œ Mock μ£Όμž… static void ResetToDefault(); // Test ν›„ 정리 }; ``` #### **ILogOutput (좜λ ₯ μΈν„°νŽ˜μ΄μŠ€)** ```cpp class ILogOutput { public: virtual void OutputLog(const LogMessage& message) = 0; virtual void SetLogLevel(LogLevel level) = 0; virtual std::wstring GetName() const = 0; }; ``` #### **κ΅¬ν˜„μ²΄λ“€** - **ConsoleLogOutput**: stdout μ½˜μ†” 좜λ ₯ - **DebugLogOutput**: Visual Studio 좜λ ₯ μ°½ (OutputDebugString) - **FileLogOutput**: 파일 λ‘œκΉ… - **NetworkLogOutput**: λ„€νŠΈμ›Œν¬ λ‘œκΉ… (ν–₯ν›„ ν™•μž₯) ### **3. Presentation Layer** #### **LogMessagePageViewModel (ν–₯ν›„ κ΅¬ν˜„)** - LogManager와 View μ‚¬μ΄μ˜ 바인딩 - Observable Collection 관리 - UI μƒνƒœ 관리 (ν•„ν„°, μžλ™ 슀크둀 λ“±) #### **LogMessagePage (View)** - 순수 XAML μ„ μ–Έν˜• UI - ViewModel에 데이터 바인딩 ## πŸ“‹ **μ‚¬μš© 방법** ### **Production μ½”λ“œμ—μ„œ** ```cpp class VideoPlayerControl { void LoadVideo(const std::wstring& filePath) { // μ–΄λ””μ„œλ“  κ°„λ‹¨ν•˜κ²Œ λ‘œκΉ… LogManagerProvider::GetInstance().LogInfo(L"Loading video: " + filePath, L"VideoPlayer"); // λΉ„λ””μ˜€ λ‘œλ”© 둜직... bool success = LoadVideoFile(filePath); LogManagerProvider::GetInstance().LogVideoLoad(filePath, success); } }; ``` ### **MainWindowμ—μ„œ μ΄ˆκΈ°ν™”** ```cpp class MainWindow { MainWindow() { // LogManager μ΄ˆκΈ°ν™” 및 좜λ ₯ μ„€μ • auto& logManager = LogManager::GetInstance(); logManager.InitializeDefaultOutputs(); // Console + Debug 좜λ ₯ μžλ™ μΆ”κ°€ // μ„ νƒμ μœΌλ‘œ 파일 λ‘œκΉ… μΆ”κ°€ logManager.AttachLogOutput(LogOutputFactory::CreateFileOutput(L"app.log")); } }; ``` ### **Unit Testμ—μ„œ** ```cpp TEST_METHOD(VideoPlayerControl_LoadVideo_ShouldLogCorrectly) { // Arrange - Mock LogManager μ£Όμž… auto mockLogManager = std::make_shared(); LogManagerProvider::SetInstance(mockLogManager); VideoPlayerControl player; // Act player.LoadVideo(L"test.mp4"); // Assert - λ‘œκΉ… 호좜 검증 Assert::AreEqual(2, mockLogManager->GetLogCallCount()); Assert::IsTrue(mockLogManager->WasMethodCalled(L"LogInfo")); Assert::IsTrue(mockLogManager->WasMethodCalled(L"LogVideoLoad")); Assert::IsTrue(mockLogManager->WasMessageLogged(L"Loading video")); // Cleanup LogManagerProvider::ResetToDefault(); } ``` ## βœ… **μž₯점** ### **개발 νŽΈμ˜μ„±** - **μ „μ—­ μ ‘κ·Ό**: `LogManagerProvider::GetInstance()`둜 μ–΄λ””μ„œλ“  μ‚¬μš© - **κ°„λ‹¨ν•œ API**: λ³΅μž‘ν•œ μ˜μ‘΄μ„± 전달 λΆˆν•„μš” - **νƒ€μž… μ•ˆμ „**: 컴파일 νƒ€μž„μ— λ‘œκΉ… λ©”μ„œλ“œ 검증 ### **ν™•μž₯μ„±** - **ν”ŒλŸ¬κ·ΈμΈ μ•„ν‚€ν…μ²˜**: μƒˆλ‘œμš΄ ILogOutput κ΅¬ν˜„μ²΄ μΆ”κ°€ 용이 - **닀쀑 좜λ ₯**: Console + Debug + File + Network λ™μ‹œ 좜λ ₯ κ°€λŠ₯ - **κ°œλ³„ μ„€μ •**: 좜λ ₯λ³„λ‘œ 둜그 레벨 독립 μ„€μ • ### **ν…ŒμŠ€νŠΈ κ°€λŠ₯μ„±** - **Mock 지원**: MockLogManager둜 λ‘œκΉ… λ™μž‘ μ™„λ²½ 검증 - **격리된 ν…ŒμŠ€νŠΈ**: ν…ŒμŠ€νŠΈ κ°„ 둜그 μƒνƒœ 격리 - **검증 API**: 둜그 호좜 횟수, λ©”μ‹œμ§€ λ‚΄μš©, νŒŒλΌλ―Έν„° 검증 ### **MVVM ν˜Έν™˜μ„±** - **Model**: LogManagerκ°€ 데이터와 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 관리 - **ViewModel**: UI 바인딩과 ν”„λ ˆμ  ν…Œμ΄μ…˜ 둜직 뢄리 - **View**: 순수 μ„ μ–Έν˜• UI ## πŸ”„ **ν™•μž₯ κ³„νš** 1. **LogMessagePageViewModel κ΅¬ν˜„**: ViewModel νŒ¨ν„΄ μ™„μ„± 2. **Network Logging**: 원격 둜그 μˆ˜μ§‘ μ„œλ²„ 연동 3. **Log Filtering**: 동적 둜그 필터링 UI 4. **Performance Logging**: μ„±λŠ₯ λ©”νŠΈλ¦­ μ „μš© λ‘œκΉ… 5. **Structured Logging**: JSON 기반 ꡬ쑰화 λ‘œκΉ… ## 🎯 **κ²°λ‘ ** 이 ν•˜μ΄λΈŒλ¦¬λ“œ μ•„ν‚€ν…μ²˜λŠ”: - **Production**: κ°„νŽΈν•œ Singleton μ ‘κ·Ό - **Testing**: μ™„λ²½ν•œ Mock 지원 - **Architecture**: MVVM νŒ¨ν„΄ μ€€μˆ˜ - **Extensibility**: ν”ŒλŸ¬κ·ΈμΈ 기반 ν™•μž₯μ„± 을 λͺ¨λ‘ λ§Œμ‘±ν•˜λŠ” 졜적의 λ‘œκΉ… μ†”λ£¨μ…˜μ„ μ œκ³΅ν•©λ‹ˆλ‹€.