-
Notifications
You must be signed in to change notification settings - Fork 1
hikari, tomcat 모니터링 코드 추가 #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e72c534
1dbbc56
b91f4a7
f19aa3d
7f9a50e
0c7cd50
dd851d2
c098a0c
2a7290c
fbca9f3
4e67e9e
a4eb0a9
e70e82b
9b7b803
00f3532
6f829d9
931b37c
cbd71ef
bd75fde
0165d50
14c8c57
f5d6eea
17ab978
a5704cb
c1f0134
e1916ba
4797300
95b7613
eef3202
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package com.example.Jinus.monitor; | ||
|
|
||
| import com.zaxxer.hikari.HikariDataSource; | ||
| import com.zaxxer.hikari.HikariPoolMXBean; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.scheduling.annotation.Scheduled; | ||
| import org.springframework.stereotype.Component; | ||
|
|
||
| @Component | ||
| @Slf4j | ||
| public class HikariCPMonitor { | ||
|
|
||
| private final HikariDataSource dataSource; | ||
|
|
||
| @Autowired | ||
| public HikariCPMonitor(HikariDataSource dataSource) { | ||
| this.dataSource = dataSource; | ||
| } | ||
|
|
||
| @Scheduled(fixedRateString = "${monitor.pool.status.rate.ms:60000}") // 상태 출력 주기 (기본 1분) | ||
| public void logHikariStatus() { | ||
| if (dataSource != null) { | ||
| HikariPoolMXBean poolMXBean = dataSource.getHikariPoolMXBean(); | ||
|
|
||
| int total = poolMXBean.getTotalConnections(); | ||
| int active = poolMXBean.getActiveConnections(); | ||
| int idle = poolMXBean.getIdleConnections(); | ||
| int waiting = poolMXBean.getThreadsAwaitingConnection(); | ||
|
|
||
| log.info("[HikariCP 상태] 전체: {} / 사용 중: {} / 유휴: {} / 대기 중: {}", | ||
| + total, active, idle, waiting); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,47 @@ | ||||||||||||
| package com.example.Jinus.monitor; | ||||||||||||
|
|
||||||||||||
| import lombok.extern.slf4j.Slf4j; | ||||||||||||
| import org.apache.catalina.connector.Connector; | ||||||||||||
| import org.apache.coyote.ProtocolHandler; | ||||||||||||
| import org.apache.coyote.AbstractProtocol; | ||||||||||||
| import org.apache.tomcat.util.threads.ThreadPoolExecutor; | ||||||||||||
| import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; | ||||||||||||
| import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; | ||||||||||||
| import org.springframework.scheduling.annotation.Scheduled; | ||||||||||||
| import org.springframework.stereotype.Component; | ||||||||||||
|
|
||||||||||||
| import java.util.concurrent.Executor; | ||||||||||||
|
|
||||||||||||
| @Component | ||||||||||||
| @Slf4j | ||||||||||||
| public class TomcatThreadMonitor { | ||||||||||||
|
|
||||||||||||
| private final ServletWebServerApplicationContext context; | ||||||||||||
|
|
||||||||||||
| public TomcatThreadMonitor(ServletWebServerApplicationContext context) { | ||||||||||||
| this.context = context; | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| @Scheduled(fixedRateString = "${monitor.pool.status.rate.ms:60000}") // 상태 출력 주기 (기본 1분) | ||||||||||||
| public void logTomcatThreadPoolStatus() { | ||||||||||||
| if (context.getWebServer() instanceof TomcatWebServer tomcatWebServer) { | ||||||||||||
| Connector connector = tomcatWebServer.getTomcat().getConnector(); | ||||||||||||
| ProtocolHandler handler = connector.getProtocolHandler(); | ||||||||||||
|
|
||||||||||||
| if (handler instanceof AbstractProtocol<?> protocol) { | ||||||||||||
| Executor executor = protocol.getExecutor(); | ||||||||||||
|
|
||||||||||||
| if (executor instanceof ThreadPoolExecutor threadPoolExecutor) { | ||||||||||||
| int max = threadPoolExecutor.getMaximumPoolSize(); | ||||||||||||
| int poolSize = threadPoolExecutor.getPoolSize(); | ||||||||||||
| int active = threadPoolExecutor.getActiveCount(); | ||||||||||||
| long taskCount = threadPoolExecutor.getTaskCount(); | ||||||||||||
| long completedTaskCount = threadPoolExecutor.getCompletedTaskCount(); | ||||||||||||
|
|
||||||||||||
| log.info("[Tomcat 스레드] MaxPoolSize: {}, PoolSize: {}, 활성: {}, TaskCount: {}, 완료: {}", | ||||||||||||
| + max, poolSize, active, taskCount, completedTaskCount); | ||||||||||||
| } | ||||||||||||
|
Comment on lines
+41
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the unexpected '+' character in the logging statement There's an unexpected '+' character at the beginning of line 42 that will cause a compilation error. log.info("[Tomcat 스레드] MaxPoolSize: {}, PoolSize: {}, 활성: {}, TaskCount: {}, 완료: {}",
- + max, poolSize, active, taskCount, completedTaskCount);
+ max, poolSize, active, taskCount, completedTaskCount);📝 Committable suggestion
Suggested change
|
||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,46 +1,16 @@ | ||
| package com.example.Jinus.service.userInfo; | ||
|
|
||
| import com.example.Jinus.entity.userInfo.CollegeEntity; | ||
| import com.example.Jinus.repository.userInfo.CollegeRepository; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
| import org.springframework.stereotype.Service; | ||
|
|
||
| @Service | ||
| public class CollegeService { | ||
| private static final Logger logger = LoggerFactory.getLogger(CollegeService.class); | ||
| private final CollegeRepository collegeRepository; | ||
|
|
||
| public CollegeService(CollegeRepository collegeRepository) { | ||
| this.collegeRepository = collegeRepository; | ||
| // logger.info("CollegeService 실행"); | ||
| } | ||
|
|
||
| public String getCollegeName(int collegeId) { | ||
| // logger.info("getCollegeName 실행"); | ||
| CollegeEntity collegeEntity = collegeRepository.findById(collegeId).orElse(null); | ||
| // logger.info("collegeEntity: {}", collegeEntity); | ||
|
|
||
| if (collegeEntity != null) { | ||
| // logger.info("collegeEng: {}", collegeEntity.getCollegeEng()); | ||
| return collegeEntity.getCollegeEng(); // 학과 영어 이름 리턴(테이블 찾기 위함) | ||
| } else { | ||
| logger.debug("CollegeService: collge를 찾을 수 없습니다."); | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| public boolean checkEtcValue(int collegeId) { | ||
| CollegeEntity collegeEntity = collegeRepository.findById(collegeId).orElse(null); | ||
| return collegeEntity.isEtcValue(); | ||
| } | ||
|
|
||
| // collegeId에 해당하는 campusId 찾기 | ||
| public int getCampusId(int collegeId) { | ||
| // logger.info("getCampusId 실행"); | ||
| int campusId = collegeRepository.findCampusId(collegeId); | ||
| // logger.info("campusId: {}", campusId); | ||
|
|
||
| return campusId; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add null check for poolMXBean
While there's a null check for the dataSource, there's no check for poolMXBean before accessing its methods, which could lead to a NullPointerException.
if (dataSource != null) { HikariPoolMXBean poolMXBean = dataSource.getHikariPoolMXBean(); + + if (poolMXBean == null) { + log.warn("HikariPoolMXBean is null, cannot monitor connection pool"); + return; + }