Commit 87f37e70 authored by Ali's avatar Ali

add logger configuration

parent 1d1d41f3
FROM 172.29.3.41:5000/openjdk:17-jdk
FROM openjdk:17-jdk
WORKDIR /app
......
This diff is collapsed.
......@@ -83,6 +83,11 @@
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.4</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.3</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-observation-test</artifactId>
......
......@@ -14,6 +14,12 @@ import org.springframework.kafka.config.KafkaListenerContainerFactory;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.kafka.listener.DefaultErrorHandler;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.backoff.FixedBackOff;
import java.util.HashMap;
import java.util.Map;
......@@ -55,6 +61,13 @@ public class NotificationKafkaConsumer {
ConcurrentKafkaListenerContainerFactory<Long,CreateNotificationDto> notificationFactory
= new ConcurrentKafkaListenerContainerFactory<>();
notificationFactory.setConsumerFactory(notificationConsumerFactory);
// Set acknowledgment mode to manual
notificationFactory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL);
// Set the error handler with retry functionality
notificationFactory.setCommonErrorHandler(new DefaultErrorHandler(
new FixedBackOff(1000L, 5)));
return notificationFactory;
}
}
......@@ -4,6 +4,8 @@ import com.ali.notificationsvc.dtos.CreateNotificationDto;
import com.ali.notificationsvc.dtos.NotificationDto;
import com.ali.notificationsvc.services.INotificationService;
import com.ali.notificationsvc.status.RequestStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
......@@ -15,6 +17,8 @@ import java.util.List;
@RequestMapping("/api/notifications")
public class NotificationController {
private static final Logger LOGGER = LoggerFactory.getLogger(NotificationController.class);
@Autowired
INotificationService notificationService;
......@@ -23,43 +27,59 @@ public class NotificationController {
}
@GetMapping("getById/{id}")
public ResponseEntity<NotificationDto> getById(@PathVariable("id") int id) {
LOGGER.info(String.format("get notification details by %s id",id));
NotificationDto notificationDto = new NotificationDto();
notificationDto = notificationService.getById(id);
return ResponseEntity.ok(notificationDto);
}
@GetMapping("getAll")
public ResponseEntity<List<NotificationDto>> getAllNotifications() {
LOGGER.info(String.format("get all notification"));
List<NotificationDto> notificationDtos = notificationService.getAll();
return ResponseEntity.ok(notificationDtos);
}
@GetMapping("getAllByCompanyId/{id}")
public ResponseEntity<List<NotificationDto>> getAllByCompanyId(@PathVariable("id") int companyId) {
LOGGER.info(String.format("get all notification by company id: %s", companyId));
List<NotificationDto> notificationDtos = notificationService.getNotificationByCompanyId(companyId);
return ResponseEntity.ok(notificationDtos);
}
@GetMapping("getAllByJobseekerId/{id}")
public ResponseEntity<List<NotificationDto>> getAllByJobseekerId(@PathVariable("id") int jobseekerId) {
LOGGER.info(String.format("get all notification by jobseeker id: %s", jobseekerId));
List<NotificationDto> notificationDtos = notificationService.getNotificationByJobseekerId(jobseekerId);
return ResponseEntity.ok(notificationDtos);
}
@GetMapping("isExist/{id}")
public ResponseEntity<Boolean> isExist(@PathVariable("id") int notificationId) {
LOGGER.info(String.format("check if notification is exist where id: %s", notificationId));
boolean isExist = notificationService.existById(notificationId);
return ResponseEntity.ok(isExist);
}
@GetMapping("getUnReadNotificationNumForJobseeker/{id}")
public ResponseEntity<Integer> getUnReadNotificationNumForJobseeker(@PathVariable("id") int jobseekerId) {
LOGGER.info(String.format("get all un read notifications for jobseeker id: %s", jobseekerId));
int num = notificationService.getUnReadNotificationsNumberByJobseekerId(jobseekerId);
return ResponseEntity.ok(num);
}
@GetMapping("getUnReadNotificationNumForCompany/{id}")
public ResponseEntity<Integer> getUnReadNotificationNumForCompany(@PathVariable("id") int companyId) {
LOGGER.info(String.format("get all un read notifications for company id: %s", companyId));
int num = notificationService.getUnReadNotificationsNumberByCompanyId(companyId);
return ResponseEntity.ok(num);
}
@PostMapping("create")
public ResponseEntity<RequestStatus> createNotification(@RequestBody CreateNotificationDto createNotificationDto) {
LOGGER.info(String.format("create new notification in synchronized way"));
RequestStatus status = notificationService.create(createNotificationDto);
if (status.isStatus()) {
return ResponseEntity.status(HttpStatus.CREATED).body(status);
......@@ -69,6 +89,8 @@ public class NotificationController {
}
@PutMapping("update")
public ResponseEntity<RequestStatus> updateNotification(@RequestBody NotificationDto notificationDto) {
LOGGER.info(String.format("update notification where id is: %s", notificationDto.getId()));
RequestStatus status = notificationService.update(notificationDto);
if (status.isStatus()) {
return ResponseEntity.ok(status);
......@@ -78,6 +100,8 @@ public class NotificationController {
}
@DeleteMapping("delete/{id}")
public ResponseEntity<RequestStatus> deleteNotification(@PathVariable("id") int id) {
LOGGER.info(String.format("delete notification where id is: %s", id));
RequestStatus status = notificationService.delete(id);
if (status.isStatus()) {
return ResponseEntity.ok(status);
......
......@@ -4,13 +4,18 @@ import com.ali.notificationsvc.dtos.CreateNotificationDto;
import com.ali.notificationsvc.services.INotificationService;
import com.ali.notificationsvc.status.RequestStatus;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;
@Component
public class NotificationKafkaListener {
private static final Logger LOGGER = LoggerFactory.getLogger(NotificationKafkaListener.class);
@Autowired
private INotificationService notificationService;
......@@ -22,12 +27,23 @@ public class NotificationKafkaListener {
groupId ="${spring.kafka.consumer.group-id}",
containerFactory = "notificationFactory"
)
void listener(ConsumerRecord<Long, CreateNotificationDto> data){
void listener(ConsumerRecord<Long, CreateNotificationDto> data, Acknowledgment acknowledgment) {
CreateNotificationDto createNotificationDto = data.value();
System.out.println("Key: " + data.key());
System.out.println("Received: " + createNotificationDto.toString());
LOGGER.info("Received: " + createNotificationDto.toString()+ "Key: " + data.key());
try {
RequestStatus requestStatus = notificationService.create(createNotificationDto);
System.out.println(requestStatus.isStatus());
System.out.println(requestStatus.getDescribtion());
if (requestStatus.isStatus()) {
// Acknowledge the message if successfully processed
acknowledgment.acknowledge();
LOGGER.info("Message processed successfully. kafka acknowledge");
} else {
// If processing fails, throw an exception to trigger retry
throw new RuntimeException("Failed to process message, will retry.");
}
} catch (Exception e) {
// Log the failure and let the retry mechanism handle the retry
LOGGER.error("Error processing message: " + e.getMessage());
throw e; // Propagate the exception to trigger a retry
}
}
}
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
Timestamp: %d{yyyy-MM-dd HH:mm:ss.SSS} | Thread: [%thread] | Level: %-5level | Trace: [traceId=%X{traceId}, spanId=%X{spanId}, parentId=%X{parentId}] | Logger: %logger{36} | Message: %msg%n
</pattern>
</encoder>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/notification-service.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/notification-service.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>10</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>
Timestamp: %d{yyyy-MM-dd HH:mm:ss.SSS} | Thread: [%thread] | Level: %-5level | Trace: [traceId=%X{traceId}, spanId=%X{spanId}, parentId=%X{parentId}] | Logger: %logger{36} | Message: %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</configuration>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment