๐คฆโ๏ธ Slack ์๋ฆผ ์ฐ๋ ์์
๊ธฐ์กด์ ์งํํ๋ ํ๋ก์ ํธ์ Slack ์๋ฆผ ์ฐ๋ ์์ ์ ์งํํ๋ ์ค์ด๋ค. ์น ํ์ด์ง์์ ์ค๋ฅ๊ฐ ๋๋ฉด ์ค๋ฅ ๋ฉ์์ง๋ฅผ Slack ์๋ฆผ์ ํตํด ์ค์๊ฐ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ ํ๋ ์์ ์ด๋ค. ๋ค๋ง, ์ํ์น ์๋ค. ํ์ฌ๊น์ง์ ์์ ์ ํ ๋ฒ ์ ๋ฆฌํด๋ณด๋ฉด ์ ์ ์์๊น ์ถ์ด ์ ๋ฆฌํด๋ณธ๋ค.
Spring Boot ์ค์
- build.gradle
implementation 'com.github.maricn:logback-slack-appender:1.4.0'
- application.properties
logging.slack.webhook-uri: ${SLACK_WEBHOOK_URI}
logging.slack.config: classpath:logback-slack.xml
- logback-spring.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<springProperty name="SLACK_WEBHOOK_URI" source="logging.slack.webhook-uri"/>
<appender name="SLACK" class="com.github.maricn.logback.SlackAppender">
<webhookUri>${SLACK_WEBHOOK_URI}</webhookUri>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %msg %n</pattern>
</layout>
<username>Cake-Server-log</username>
<iconEmoji>:stuck_out_tongue_winking_eye:</iconEmoji>
<colorCoding>true</colorCoding>
</appender>
<!-- Consol appender ์ค์ -->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %green(%-5level) %logger{35} %cyan(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<appender name="ASYNC_SLACK" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="SLACK"/>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<root level="INFO">
<appender-ref ref="Console" />
<appender-ref ref="ASYNC_SLACK"/>
</root>
</configuration>
์์ค์ฝ๋ ์ค์
- StatusAlarm
package com.example.thebestmeal_test.domain;
import com.example.thebestmeal_test.dto.StatusAlarmDto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Entity
public class StatusAlarm extends Timestamped{
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String content;
@Column
private String imageUrl;
public StatusAlarm(StatusAlarmDto.Request request, String imageUrl) {
this.title = request.getTitle();
this.content = request.getContent();
this.imageUrl = imageUrl;
}
}
- StatusAlarmDto
package com.example.thebestmeal_test.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;
@NoArgsConstructor
public class StatusAlarmDto {
// Slack ์ํ ๋ฉ์ธ์ง ์ ์ก์ ์ํ ๋ด๋ถ ํด๋์ค
@Getter
@Setter
public static class Request {
private String title;
private String content;
private MultipartFile image;
}
@Getter
@Setter
public static class Response {
private long id;
private String title;
private String imageUrl;
}
}
- StatusAlarmService
package com.example.thebestmeal_test.service;
import com.example.thebestmeal_test.domain.StatusAlarm;
import com.example.thebestmeal_test.dto.StatusAlarmDto;
import com.example.thebestmeal_test.repository.StatusAlarmRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.io.IOException;
import java.util.List;
@RequiredArgsConstructor
@Service
public class StatusAlarmService {
private final StatusAlarmRepository statusAlarmRepository;
private final AwsService awsService;
@Transactional
public StatusAlarm setStatusAlarm(StatusAlarmDto.Request request) throws IOException {
String url = null;
if(request.getImage() != null) url = awsService.upload(request.getImage());
StatusAlarm statusAlarm = new StatusAlarm(request, url);
statusAlarmRepository.save(statusAlarm);
return statusAlarm;
}
public StatusAlarm getStatusAlarm(Long id) {
return statusAlarmRepository.findById(id).orElseThrow(
() -> new NullPointerException("ํด๋น ์์ด๋๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.")
);
}
public List<StatusAlarm> getStatusAlarms() {
return statusAlarmRepository.findAll();
}
}
- StatusAlarmController
package com.example.thebestmeal_test.controller;
import com.example.thebestmeal_test.domain.StatusAlarm;
import com.example.thebestmeal_test.dto.StatusAlarmDto;
import com.example.thebestmeal_test.service.StatusAlarmService;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.modelmapper.TypeToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List;
@RequiredArgsConstructor
@RestController
public class StatusAlarmController {
private final StatusAlarmService statusAlarmService;
private final ModelMapper modelMapper;
@PostMapping("/statusAlarm")
public StatusAlarm setStatusAlarm(StatusAlarmDto.Request request) throws IOException {
return statusAlarmService.setStatusAlarm(request);
}
@GetMapping("/statusAlarms")
public List<StatusAlarmDto.Response> getStatusAlarms() {
int i = 1/0; // (์๋์ ์ธ ์๋ฌ ๋ฐ์์ ์ํ ์์ ์ฝ๋)
List<StatusAlarm> statusAlarms = statusAlarmService.getStatusAlarms();
List<StatusAlarmDto.Response> response = modelMapper.map(statusAlarms, new TypeToken<List<StatusAlarmDto.Response>>() {}.getType());
return response;
}
}
์์ค์ฝ๋ ์์ฒด์๋ ์ด์์ด ์์๋ค. Build ์คํ๋ ์ ๋์๊ณ , Postman์ ํตํ ํ ์คํธ ๋ด์ฉ์ ํฐ๋ฏธ๋์ ๋ก๊ทธ๋ ์ ์ฐํ๋ค. ์ค๋ ๊ณ ๋ฏผ์ ๊ฝค๋ ํ์ง๋ง ์์ธ์ ์ฐพ์ง ๋ชปํ๋ค. ์ด์ฉ๋ฉด ๋ด๊ฐ ์์ฃผ ๋ฐ๋ณด ๊ฐ์ ์ค์๋ฅผ ํ๊ณ ์์์ง๋ ๋ชจ๋ฅธ๋ค. ๊ทธ๊ฒ ์กฐ๊ธ ๋ฌด์ญ๋ค. ์ง๊ธ์ผ๋ก์๋ ์ฌ๋ api ์๋น์ค ๋ด์์ ์ด๋ ํ ์ค์ ๊ฐ์ ์๋ชปํด์ฃผ์๋๋ผ๋ ์๊ฐ์ ํ๊ณ ์๋ค. ๋ด์ผ ์ค์ผ๋ก ๋ง๋ฌด๋ฆฌํ๊ณ ์ถ๋ค.... ๋๋ฅต ใ
๐ ์ ๋ณด์ฒ๋ฆฌ๊ธฐ์ฌ ์ค๋น์ค!
์ ์ฒ๊ธฐ ์ค๋น๋ ์์ง๊น์ง๋ ์ํญ์ด๋ค. ํ๊ธฐ๊ฐ 4์ 24์ผ์ ์์ ์ธ๋ฐ, ์ฌ์ค ํ๊ธฐ๋ ๋ฌธ์ ์ํ๊ณผ ๊ฐ๊ด์์ด๋ผ ํฐ ๋ถ๋ด์ด ์๋ค. ์ง๊ธ๊น์ง ๋ชจ์๊ณ ์ฌ ํผ ๊ฒ๋ ๋ค ํฉ๊ฒฉ์ ์ด๋๊น.. ๋ฌธ์ ๋ ์ค๊ธฐ๋ค.
์ค๊ธฐ ๋ฌธ์ ๋ ์ ์ฝ๋ฉ, ์ํํธ์จ์ด ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ์ฃผ๊ด์ ๋ฌธ์ ๋ฑ ์๋นํ ๊ตฌ์ฒด์ ์ธ ๋ด์ฉ๋ค์ด ๋์์ ๋ฒ์จ๋ถํฐ ๊ฒ์ด ๋๋ค. ํนํ, C์ธ์ด ์๊ณ ๋ฆฌ์ฆ ์์ฝ๋ฉ ๋ฌธ์ ๊ฐ ๋์ค๋ฉด.. ์์ธํ ๊ฒ ๊ฐ๋ค. C์ธ์ด๋ ๋ค๋ค๋ณธ ์ ์ด ์์ผ๋๊น.. ํ๊ธฐ๋ฅผ ์ค๋นํ๋ฉด์ ๋ณธ ๋ด์ฉ๋ค์ด ์ ๋ถ๋ผ์ ์์ด ์บ์บํ๋ค. ๊ทธ๋๋ ๋ถ๋ชํ๋ด์ผ ์๊ณ , ๋ค๋ฅธ ๋ฌธ์ ๋ค์์ ๋์ ํ๋ฉด ๊ฐ๋ฅ์ฑ์ด ์์ง๋ ์์ผ๋๊น ์ผ๋จ ๋ฅ๋์ด๋ค.
์ด์ฌํ ํด์ ์ ๋ณด์ฒ๋ฆฌ๊ธฐ์ฌ ๋์ฐจ ํฉ๊ฒฉ์ ์ด๋ฃจ์.
'๋ด ์ด์ผ๊ธฐ(TMI)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TMI] ์ธํผ(SSAFY) 8๊ธฐ ์ง์ ๊ทธ๋ฆฌ๊ณ ์ต์ข ํ๋ฝ.. (1) | 2022.07.06 |
---|---|
[์ ๋ณด์ฒ๋ฆฌ๊ธฐ์ฌ] ํ๊ธฐ ํฉ๊ฒฉ.. (0) | 2022.06.06 |
[TIL] ์ฝ๋ ํจ์จ์ฑ์ ๋ํ ๊ณ ๋ฏผ(๋ฐฑ์ค ๊ณต๋ถ..) (0) | 2022.04.05 |
[TIL] ์คํฐ๋ ๋ฐ ์ ์ฒ๊ธฐ ๊ณต๋ถ (0) | 2022.03.29 |
[์ค๋์ ์๊ฐ] ๋ต๋ตํ ํ๋ฃจ (0) | 2022.03.23 |