Skip to content

Conversation

@kwon204
Copy link
Contributor

@kwon204 kwon204 commented Feb 6, 2025

#️⃣ 연관된 이슈>

📝 작업 내용> 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

  • 서버의 로그 환경 세팅
    • 로컬, 개발 환경에서는 콘솔에 로그
    • 배포 환경에서는 파일에 로그 저장
  • 요청, 응답, 응답 시간 로그하는 필터 추가
  • 필터들을 FilterConfig로 관리
    • SecurityConfig 삭제

🙏 여기는 꼭 봐주세요! > 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

Summary by CodeRabbit

  • New Features

    • Introduced enhanced request filtering with improved logging capabilities that capture key details of API calls.
    • Added an adaptable logging configuration that tailors output for both development and production environments, ensuring clearer operational insights.
  • Bug Fixes

    • Removed outdated JWT authentication configuration to streamline security processes.
  • Refactor

    • Streamlined filtering setup to consolidate authentication and logging processes, promoting a more maintainable and efficient configuration.

@kwon204 kwon204 added the 🛠️ BE Backend label Feb 6, 2025
@kwon204 kwon204 added this to the 1차 스프린트 milestone Feb 6, 2025
@kwon204 kwon204 self-assigned this Feb 6, 2025
@kwon204 kwon204 requested a review from efdao as a code owner February 6, 2025 01:56
@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2025

Walkthrough

The changes introduce a new configuration class, FilterConfig, which registers two filters: a logging filter and a JWT authentication filter, defining their order of execution. A new LogFilter class is added to process and log HTTP requests selectively. Additionally, an old security configuration file responsible for JWT filter registration has been removed. A new logging configuration file, logback-spring.xml, has been added to manage logging behavior based on the active Spring profiles.

Changes

File(s) Change Summary
backend/src/main/java/.../config/FilterConfig.java
backend/src/main/java/.../security/SecurityConfig.java
Added FilterConfig to register LogFilter (order 1) and JwtAuthFilter (order 2); removed SecurityConfig, which previously handled JWT filter registration.
backend/src/main/java/.../logging/LogFilter.java
backend/src/main/resources/.../logback-spring.xml
Added new LogFilter for logging HTTP request details selectively and introduced logback-spring.xml for environment-specific logging configurations.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant LogFilter
    participant JwtAuthFilter
    participant Controller

    Client->>LogFilter: HTTP Request
    Note over LogFilter: Log request details and check URI
    LogFilter->>JwtAuthFilter: Forward filtered request
    JwtAuthFilter->>Controller: Validate JWT and process request
    Controller-->>JwtAuthFilter: Response
    JwtAuthFilter-->>LogFilter: Response passed along
    LogFilter-->>Client: HTTP Response
Loading

Suggested reviewers

  • efdao

Poem

I'm a bunny with a hop in my step,
New filters and logs make my heart adept.
From LogFilter's keen watch to JWT's might,
Our code now hops in order just right.
Old files have gone, new ones bloom bright—
A joyful leap forward, coding delight! 🐰

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
backend/src/main/java/endolphin/backend/global/config/FilterConfig.java (1)

13-19: Align URL pattern with LogFilter's path filtering

The URL pattern "/*" matches all requests, but LogFilter's shouldNotFilter method only processes paths starting with "/api/v1". Consider updating the URL pattern to match the filter's behavior.

-        filterRegistrationBean.addUrlPatterns("/*");
+        filterRegistrationBean.addUrlPatterns("/api/v1/*");
backend/src/main/java/endolphin/backend/global/logging/LogFilter.java (1)

14-28: Enhance logging details and timing precision

Consider the following improvements:

  1. Use System.nanoTime() for more precise timing
  2. Add request headers and query parameters for better debugging
  3. Include response headers in the log
-        long startTime = System.currentTimeMillis();
+        long startTime = System.nanoTime();
         log.info("Incoming Request: [{}] {} {}",
             request.getMethod(), request.getRequestURI(),
+            request.getQueryString() != null ? "?" + request.getQueryString() : "");
 
         filterChain.doFilter(request, response);
 
-        long endTime = System.currentTimeMillis();
+        long endTime = System.nanoTime();
         log.info("Incoming Response: [{}] {}, {}, {} ms",
             request.getMethod(), request.getRequestURI(),
             response.getStatus(),
-            endTime - startTime);
+            (endTime - startTime) / 1_000_000.0);
backend/src/main/resources/logback-spring.xml (2)

4-8: Consider making log path configurable and adding MDC support

  1. The log path should be configurable through environment variables or application properties
  2. Consider adding MDC support for request tracking (e.g., correlation ID)
   <property name="CONSOLE_LOG_PATTERN"
-    value="%d{yyyy-MM-dd HH:mm:ss}:%-4relative %highlight(%-5level) %magenta(${PID:-}) [%thread] %cyan(%logger{36}) - %msg%n" />
+    value="%d{yyyy-MM-dd HH:mm:ss}:%-4relative %highlight(%-5level) %magenta(${PID:-}) [%thread] %cyan(%logger{36}) [%X{correlationId}] - %msg%n" />
   <property name="FILE_LOG_PATTERN"
-    value="%d{yyyy-MM-dd HH:mm:ss}:%-4relative %-5level ${PID:-} [%thread] %logger{36} - %msg%n" />
+    value="%d{yyyy-MM-dd HH:mm:ss}:%-4relative %-5level ${PID:-} [%thread] %logger{36} [%X{correlationId}] - %msg%n" />
-  <property name="LOG_PATH" value="/var/logs/myapp"/>
+  <property name="LOG_PATH" value="${LOG_PATH:-/var/logs/myapp}"/>

26-47: Consider using AsyncAppender for better performance

In production, consider wrapping the RollingFileAppender with an AsyncAppender to prevent logging from blocking the main thread.

   <springProfile name="prod">
+    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
+      <appender-ref ref="FILE" />
+      <queueSize>512</queueSize>
+      <discardingThreshold>0</discardingThreshold>
+      <includeCallerData>false</includeCallerData>
+      <neverBlock>true</neverBlock>
+    </appender>

     <root level="info">
-      <appender-ref ref="FILE" />
+      <appender-ref ref="ASYNC" />
     </root>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 870c9a9 and 510b9d2.

📒 Files selected for processing (4)
  • backend/src/main/java/endolphin/backend/global/config/FilterConfig.java (1 hunks)
  • backend/src/main/java/endolphin/backend/global/logging/LogFilter.java (1 hunks)
  • backend/src/main/java/endolphin/backend/global/security/SecurityConfig.java (0 hunks)
  • backend/src/main/resources/logback-spring.xml (1 hunks)
💤 Files with no reviewable changes (1)
  • backend/src/main/java/endolphin/backend/global/security/SecurityConfig.java
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Send PR Notification to Reviewers
🔇 Additional comments (3)
backend/src/main/java/endolphin/backend/global/config/FilterConfig.java (1)

22-28: Consider restricting JWT authentication to API endpoints

The JWT authentication filter is currently applied to all requests ("/*"). Consider restricting it to API endpoints if authentication is only needed for API calls.

Could you confirm if JWT authentication should be applied to all endpoints or just API endpoints?

backend/src/main/java/endolphin/backend/global/logging/LogFilter.java (1)

30-33: LGTM!

The path filtering logic is clear and correctly implemented.

backend/src/main/resources/logback-spring.xml (1)

10-24: LGTM!

The non-prod configuration with console logging and debug levels is appropriate for development environments.

@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return !request.getRequestURI().startsWith("/api/v1");
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p2; Config에 url pattern으로 추가하는게 좋아 보입니다.

@kwon204 kwon204 closed this Feb 6, 2025
coderabbitai bot added a commit that referenced this pull request Feb 6, 2025
Docstrings generation was requested by @kwon204.

* #97 (comment)

The following files were modified:

* `backend/src/main/java/endolphin/backend/global/config/FilterConfig.java`
* `backend/src/main/java/endolphin/backend/global/logging/LogFilter.java`
@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2025

Note

Generated docstrings for this pull request at #102

@kwon204 kwon204 reopened this Feb 6, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
backend/src/main/java/endolphin/backend/global/logging/LogFilter.java (2)

29-33: Consider improving time measurement precision.

The current implementation might lose precision when converting nanoseconds to milliseconds. Consider using TimeUnit for more accurate conversion:

-            (endTime - startTime) / 1_000_000.0);
+            TimeUnit.NANOSECONDS.toMillis(endTime - startTime));

Don't forget to add the import:

import java.util.concurrent.TimeUnit;

16-35: Consider adding request body logging for debugging.

For debugging purposes, it might be helpful to log request bodies. Consider adding conditional request body logging (e.g., only in non-production environments or for specific content types).

+    private boolean shouldLogBody(HttpServletRequest request) {
+        String contentType = request.getContentType();
+        return contentType != null && 
+               (contentType.contains("application/json") || 
+                contentType.contains("application/xml"));
+    }
+
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
         FilterChain filterChain) throws ServletException, IOException {
         long startTime = System.nanoTime();
         String correlationId = UUID.randomUUID().toString();
         MDC.put("correlationId", correlationId);
+
+        if (shouldLogBody(request)) {
+            String requestBody = request.getReader().lines()
+                .collect(Collectors.joining(System.lineSeparator()));
+            log.debug("Request Body: {}", requestBody);
+        }

Don't forget to add the import:

import java.util.stream.Collectors;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 510b9d2 and 128b11a.

📒 Files selected for processing (3)
  • backend/src/main/java/endolphin/backend/global/config/FilterConfig.java (1 hunks)
  • backend/src/main/java/endolphin/backend/global/logging/LogFilter.java (1 hunks)
  • backend/src/main/resources/logback-spring.xml (1 hunks)
🔇 Additional comments (5)
backend/src/main/java/endolphin/backend/global/config/FilterConfig.java (2)

13-19: LGTM! LogFilter registration looks good.

The LogFilter is correctly registered with order 1 and appropriate URL pattern for API endpoints.


21-28: Consider restricting JwtAuthFilter to API endpoints.

The JwtAuthFilter is currently applied to all endpoints ("/"). Consider restricting it to API endpoints ("/api/v1/") for consistency with LogFilter, unless there's a specific requirement to authenticate all endpoints.

backend/src/main/java/endolphin/backend/global/logging/LogFilter.java (1)

20-25: LGTM! Request logging setup looks good.

Good use of correlation ID and MDC for request tracking.

backend/src/main/resources/logback-spring.xml (2)

40-46: LGTM! Async appender configuration looks good.

Good configuration of the async appender with:

  • Appropriate queue size
  • No discarding of events
  • Never blocking behavior

26-38: Ensure proper log file permissions in production.

The RollingFileAppender will create log files in production. Ensure that:

  1. The application has write permissions to the log directory
  2. Log files have appropriate permissions for security

Add this to your deployment checklist:

value="%d{yyyy-MM-dd HH:mm:ss}:%-4relative %highlight(%-5level) %magenta(${PID:-}) [%thread] %cyan(%logger{36}) %X{correlationId} - %msg%n" />
<property name="FILE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss}:%-4relative %-5level ${PID:-} [%thread] %logger{36} %X{correlationId} - %msg%n" />
<property name="LOG_PATH" value="/var/logs/myapp"/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider making log path configurable.

The log path is hardcoded. Consider making it configurable through Spring properties:

-  <property name="LOG_PATH" value="/var/logs/myapp"/>
+  <springProperty scope="context" name="LOG_PATH" source="logging.file.path" defaultValue="/var/logs/myapp"/>

Then add to your application.properties/yaml:

logging:
  file:
    path: /var/logs/myapp

Copy link
Collaborator

@efdao efdao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다

@kwon204 kwon204 merged commit 49606ed into dev Feb 6, 2025
1 check passed
@kwon204 kwon204 deleted the feature/be/logging branch February 6, 2025 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ BE Backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants