diff --git a/src/main/java/com/rainbowletter/server/petinitiatedletter/adapter/out/infrastructure/PetInitiatedLetterGenerator.java b/src/main/java/com/rainbowletter/server/petinitiatedletter/adapter/out/infrastructure/PetInitiatedLetterGenerator.java index 6b3c990..bd4ade2 100644 --- a/src/main/java/com/rainbowletter/server/petinitiatedletter/adapter/out/infrastructure/PetInitiatedLetterGenerator.java +++ b/src/main/java/com/rainbowletter/server/petinitiatedletter/adapter/out/infrastructure/PetInitiatedLetterGenerator.java @@ -27,16 +27,15 @@ public class PetInitiatedLetterGenerator { public GeneratedLetterContent generate(Pet pet) { final AiSetting aiSetting = loadSettingPort.loadPetInitiatedLetterSetting(); Pet.PetId petId = pet.getId(); - log.info("[편지 작성 메소드 호출] petId={}", petId); + long threadId = Thread.currentThread().getId(); + + log.info("[편지 작성 메소드 호출] petId={}, threadId={}", petId, threadId); if (Boolean.TRUE.equals(aiSetting.getUseABTest())) { final Map results = new EnumMap<>(PromptType.class); for (AiPrompt prompt : aiSetting.getPrompts()) { - String content = callAiClientPort.call(new AiClientCommand(prompt, List.of(pet))) - .getResult() - .getOutput() - .getContent(); + String content = callAiWithLogging(prompt, pet, petId, threadId); results.put(prompt.getType(), content); } @@ -56,13 +55,8 @@ public GeneratedLetterContent generate(Pet pet) { } else { AiPrompt selectedPrompt = aiSetting.getSelectedPrompt(); - log.info("[callAiClientPort.call 메소드 호출] petId={}", petId); - String content = callAiClientPort.call(new AiClientCommand(selectedPrompt, List.of(pet))) - .getResult() - .getOutput() - .getContent(); + String content = callAiWithLogging(selectedPrompt, pet, petId, threadId); - log.info("[callAiClientPort.call 메소드 호출 종료] petId={}", petId); return new GeneratedLetterContent( content.substring(0, 20), content, @@ -72,4 +66,21 @@ public GeneratedLetterContent generate(Pet pet) { ); } } + + private String callAiWithLogging(AiPrompt prompt, Pet pet, Pet.PetId petId, long threadId) { + long start = System.currentTimeMillis(); + log.info("[OpenAI 호출 시작] petId={}, threadId={}, promptType={}, timestamp={}", + petId, threadId, prompt.getType(), start); + + String content = callAiClientPort.call(new AiClientCommand(prompt, List.of(pet))) + .getResult() + .getOutput() + .getContent(); + + long end = System.currentTimeMillis(); + log.info("[OpenAI 응답 완료] petId={}, threadId={}, promptType={}, duration={}ms", + petId, threadId, prompt.getType(), (end - start)); + + return content; + } } \ No newline at end of file diff --git a/src/main/java/com/rainbowletter/server/petinitiatedletter/application/domain/service/GeneratePetInitiatedLetterEventHandler.java b/src/main/java/com/rainbowletter/server/petinitiatedletter/application/domain/service/GeneratePetInitiatedLetterEventHandler.java index 4a6c360..7dd94c0 100644 --- a/src/main/java/com/rainbowletter/server/petinitiatedletter/application/domain/service/GeneratePetInitiatedLetterEventHandler.java +++ b/src/main/java/com/rainbowletter/server/petinitiatedletter/application/domain/service/GeneratePetInitiatedLetterEventHandler.java @@ -13,8 +13,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionPhase; import org.springframework.transaction.event.TransactionalEventListener; @@ -29,8 +27,9 @@ public class GeneratePetInitiatedLetterEventHandler { private final SlackErrorReportService slackErrorReportService; @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) - @Transactional(propagation = Propagation.REQUIRES_NEW) public void handleGeneratePetInitiatedLetters(GeneratePetInitiatedLetterEvent event) { + log.info("[이벤트 핸들러 시작] threadId={}, eventSize={}", Thread.currentThread().getId(), event.letterIds().size()); + for (Long letterId : event.letterIds()) { PetInitiatedLetter letter = petInitiatedLetterJpaRepository.findById(letterId) .orElseThrow(() -> new RainbowLetterException("선편지를 찾을 수 없습니다: " + letterId)); @@ -43,6 +42,15 @@ public void handleGeneratePetInitiatedLetters(GeneratePetInitiatedLetterEvent ev GeneratedLetterContent generatedLetterContent = petInitiatedLetterGenerator.generate(pet); letter.generate(generatedLetterContent); + // 각 편지 요청 간 3초 딜레이 + try { + log.info("[딜레이 시작] petId={}, threadId={}, sleep=3000ms", letter.getPetId(), Thread.currentThread().getId()); + Thread.sleep(3000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.warn("[딜레이 중단됨] petId={}, threadId={}", letter.getPetId(), Thread.currentThread().getId()); + } + } catch (Exception e) { letter.markAsFailed(); log.error("선편지 AI 생성 실패, letterId={}", letter.getId(), e);