일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- vaadin
- Kotlin
- SSL
- table
- SPC
- mapreduce
- react
- SQL
- xPlatform
- 공정능력
- es6
- JavaScript
- Android
- Express
- mybatis
- plugin
- GIT
- window
- IntelliJ
- Sqoop
- Eclipse
- MSSQL
- NPM
- R
- 보조정렬
- tomcat
- Python
- Java
- Spring
- hadoop
- Today
- Total
DBILITY
spring boot actuator + embedded mongodb 본문
Spring Starter Project로 생성시 spring-boot 버전은 2.1.8.RELEASE.
Actuator는 App 운영시 모니터링 및 매트릭 수집의 역할을 한다.
대표적으로 다음과 같은 endpoint가 있으며 기본적으로 shutdown을 제외하고 모두 활성화되어 있다.
path | Description |
/beans | 초기화된 모든 spring bean 목록 |
/env | 설정가능한 환경속성 목록으로 환경변수 및 설정파일의 속성을 포함 |
/health | 상태정보 |
/info | 사용자 임의 정보 |
/logger | 로거설정정보 표시,수정 |
/metrics | 메트릭 정보표시( 메모리사용량, 실행중인 쓰레드 수 REST Method Response Time 등 ) |
/httptrace | http trace정보( last 100 http request) |
application.properties에 설정을 통해 endpoint 노출,비노출을 설정가능하며 기본적으로 health,info경로만 노출되어 있다.
endpoint 목록은 https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html 확인가능하다.
다음은 beans,env,logger를 제외하고 모두 노출하는 설정이다.
management.endpoints.web.exposure.exclude=beans,env,logger
management.endpoints.web.exposure.include=*
actuator를 적용하기 위해선 pom에 spring-boot-starter-actuator dependancy를 추가한다.
/info 경로에 git 커밋정보 노출을 위해 build 섹션 plugins에 git-commit-id-plugin 아래와 같이 추가해야 한다.
build시 classpath 최상위에 git.properties가 생성된다.
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<configuration>
<failOnNoGitDirectory>false</failOnNoGitDirectory>
</configuration>
</plugin>
/actuator/info 요청시 {"git":{"commit":{"time":"2019-09-04T09:27:24Z","id":"c1495f5"},"branch":"master"}} 와 같은 정보가 포함되게 된다.
App 빌드정보 노출을 원할 경우 다음과 같이 spring-boot-maven-plugin을 수정해 META-INF/build-info.properties가 자동생성 되도록 한다.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
<goal>repackage</goal>
</goals>
<configuration>
<additionalProperties>
<java.target>${maven.compiler.target}</java.target>
<time>${maven.build.timestamp}</time>
</additionalProperties>
</configuration>
</execution>
</executions>
</plugin>
/actuator/info 요청시 {"build":{"version":"0.0.1-SNAPSHOT","java":{"target":"1.8"},"artifact":"spring-restful","name":"spring-restful","group":"com.dbility.cloud","time":"2019-09-04T12:48:42Z"}}와 같은 정보가 포함되게 된다.
/health api는 디스크사용량, 메일서비스, JMS, 데이터소스, 몽고디비나 카산드라 같은 NoSQL을 모니터링한다.
기본은 STATUS:UP만 제공된다.
상세정보를 확인하려면, application.properties에 다음과 같이 추가하며. 선택 값은 [always,never,when-authorized]가 있다.
management.endpoint.health.show-details=always
/actuator/health 요청시 {"status":"UP","details":{"diskSpace":{"status":"UP","details":{"total":208274305024,"free":36507033600,"threshold":10485760}}}} 와 같이 디스크 정보가 포함된다.
embeded 몽고디비의 health정보 확인을 위해 다음과 같이 dependency를 추가한다. 몽고디비 사용법은 따로 학습이 필요하다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</dependency>
/actuator/health 요청시 {status":"UP","details":{"diskSpace":{"status":"UP","details":{"total":208274305024,"free":36195037184,"threshold":10485760}},"mongo":{"status":"UP","details":{"version":"3.5.5"}}}} 와 같이 몽고디비정보가 포함된다.
/metrics api 호출시 다음과 같이 항목명만 출력이 된다.
{
"names": [
"jvm.memory.max",
"jvm.threads.states",
"jvm.gc.memory.promoted",
"jvm.memory.used",
"jvm.gc.max.data.size",
"jvm.gc.pause",
"jvm.memory.committed",
"system.cpu.count",
"logback.events",
"http.server.requests",
"tomcat.global.sent",
"jvm.buffer.memory.used",
"tomcat.sessions.created",
"jvm.threads.daemon",
"system.cpu.usage",
"jvm.gc.memory.allocated",
"tomcat.global.request.max",
"tomcat.global.request",
"tomcat.sessions.expired",
"jvm.threads.live",
"jvm.threads.peak",
"tomcat.global.received",
"process.uptime",
"tomcat.sessions.rejected",
"process.cpu.usage",
"tomcat.threads.config.max",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"tomcat.global.error",
"tomcat.sessions.active.current",
"tomcat.sessions.alive.max",
"jvm.gc.live.data.size",
"tomcat.threads.current",
"jvm.buffer.count",
"jvm.buffer.total.capacity",
"tomcat.sessions.active.max",
"tomcat.threads.busy",
"process.start.time"
]
}
/actuator/metrics/{항목} 형태로 호출해 봤다.
다음은 jvm.memory.max 추가하여 /actuator/metrics/jvm.memory.max를 호출한 결과.
{
"name": "jvm.memory.max",
"description": "The maximum amount of memory in bytes that can be used for memory management",
"baseUnit": "bytes",
"measurements": [
{
"statistic": "VALUE",
"value": 5.447876607E9
}
],
"availableTags": [
{
"tag": "area",
"values": [
"heap",
"nonheap"
]
},
{
"tag": "id",
"values": [
"Compressed Class Space",
"PS Survivor Space",
"PS Old Gen",
"Metaspace",
"PS Eden Space",
"Code Cache"
]
}
]
}
사용자 정의용으로 MeterRegistry를 제공한다.
이전 글의 EmpController에 사용할 EmpService를 생성하고, 각 Api 호출에 따라 services.emp.post, service.emp.delete를 metrics에 제공해 본다.
맞는지는 모르겠으나, metrics조회시 동작한다.
Emp.java
package com.dbility.cloud.spring.model;
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.Data;
@Document(collection = "emp")
@Data
public class Emp {
@Id
private String id; //ObjectId
private String empno;
private String ename;
private String job;
private Long mgr;
private Date hiredate;
private double sal;
private Long deptno;
}
EmpCounterService.java
package com.dbility.cloud.spring.service;
public interface EmpCounterService {
public void CountNewEmp() throws Exception;
public void CountDeleteEmp() throws Exception;
}
EmpCounterServiceImpl.java
package com.dbility.cloud.spring.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dbility.cloud.spring.service.EmpCounterService;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
@Service("EmpCounterService")
public class EmpCounterServiceImpl implements EmpCounterService {
private final MeterRegistry registry;
@Autowired
public EmpCounterServiceImpl(MeterRegistry registry) {
this.registry=registry;
this.registry.counter("services.emp.post", Tags.empty());
this.registry.counter("services.emp.delete", Tags.empty());
}
@Override
public void CountNewEmp() throws Exception {
registry.counter("services.emp.post", Tags.empty()).increment();
}
@Override
public void CountDeleteEmp() throws Exception {
registry.counter("services.emp.delete", Tags.empty()).increment();
}
}
EmpController.java
package com.dbility.cloud.spring.controller;
import java.util.List;
import javax.annotation.Resource;
import org.bson.codecs.ObjectIdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.dbility.cloud.spring.data.EmpRepository;
import com.dbility.cloud.spring.model.Emp;
import com.dbility.cloud.spring.service.EmpCounterService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequestMapping(value = "/emp")
public class EmpController {
@Autowired
private EmpRepository repository;
@Resource(name="EmpCounterService")
private EmpCounterService empCounterService;
@GetMapping
public List<emp> findAll() throws Exception {
List<emp> emps = repository.findAll();
log.debug("GET ALL --> {}", emps);
return emps;
}
@GetMapping(value = "/{id}")
public List<emp> findById(@RequestParam String id) throws Exception {
log.debug("GET param --> {}", id);
List<emp> emps = repository.findByEmpno(id);
log.debug("GET result--> {}", emps);
return emps;
}
@PostMapping
public Emp add(@RequestBody Emp emp) throws Exception {
emp.setId(new ObjectIdGenerator().generate().toString());
repository.save(emp);
empCounterService.CountNewEmp();
log.debug("POST --> {}", emp);
return emp;
}
@DeleteMapping
public void delete(Emp emp) throws Exception {
repository.delete(emp);
empCounterService.CountDeleteEmp();
log.debug("DELETE --> {}", emp);
}
@PutMapping
public void update(@RequestBody Emp emp) throws Exception {
repository.save(emp);
log.debug("PUT --> {}", emp);
}
}
swagger-ui에서 PUT 5회, DELETE 2회 실행 후 metrics를 조회하면 다음과 같은 결과가 출력된다.
{
"name": "services.emp.post",
"description": null,
"baseUnit": null,
"measurements": [
{
"statistic": "COUNT",
"value": 5.0
}
],
"availableTags": [
]
}
{
"name": "services.emp.delete",
"description": null,
"baseUnit": null,
"measurements": [
{
"statistic": "COUNT",
"value": 2.0
}
],
"availableTags": [
]
}
'java > spring cloud' 카테고리의 다른 글
spring boot security jdbcdatasource (0) | 2019.09.21 |
---|---|
spring boot security (0) | 2019.09.18 |
Authentication is required but no CredentialsProvider has been registered (0) | 2019.09.18 |
spring boot actuator + prometheus + grafana visualization (0) | 2019.09.16 |
spring boot RESTful + swagger2 sample (0) | 2019.09.04 |