adding missing files
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package com.release11.klaus.controller;
|
||||
|
||||
import com.release11.klaus.model.EventRequestDto;
|
||||
import com.release11.klaus.service.EtrackService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping
|
||||
@AllArgsConstructor
|
||||
public class EventController {
|
||||
|
||||
private final EtrackService etrackService;
|
||||
|
||||
@PostMapping("/eventsForm")
|
||||
@ResponseBody
|
||||
public String getLogs(@Valid EventRequestDto eventsDto, BindingResult bindingResult){
|
||||
return String.valueOf(etrackService.getEventsByDateTimeAndBusinessKeys(eventsDto));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.release11.klaus.controller;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ControllerAdvice
|
||||
public class MvcExceptionHandler {
|
||||
|
||||
@ExceptionHandler(ConstraintViolationException.class)
|
||||
public ResponseEntity<List> validationErrorHandler(ConstraintViolationException e){
|
||||
List<String> errors = new ArrayList<>(e.getConstraintViolations().size());
|
||||
|
||||
e.getConstraintViolations().forEach(constraintViolation -> {
|
||||
errors.add(constraintViolation.getPropertyPath() + " : " + constraintViolation.getMessage());
|
||||
});
|
||||
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@ExceptionHandler(BindException.class)
|
||||
public ResponseEntity<List> handleBindException(BindException ex){
|
||||
return new ResponseEntity(ex.getAllErrors(), HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
35
src/main/java/com/release11/klaus/model/Event.java
Normal file
35
src/main/java/com/release11/klaus/model/Event.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package com.release11.klaus.model;
|
||||
|
||||
import com.release11.klaus.utilis.BusinessKey;
|
||||
import lombok.*;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
@Builder
|
||||
@ToString
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Event {
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-ddTHH:mm:ss")
|
||||
private LocalDateTime dateTimeStamp;
|
||||
@Nullable
|
||||
private String[] businessKeys;
|
||||
private String thread;
|
||||
private String level;
|
||||
@Nullable
|
||||
private String message;
|
||||
}
|
||||
|
||||
//{"date" : "%d{yyyy-MM-dd}", "timestamp":"%d{HH:mm:ss}", "businessKeys": {"interfaceName": "%X{interfaceName}",
|
||||
// "clientUUID": "%X{clientUUID}", "messageId": "%X{messageId}"},"thread":"%t","level":"%-5level", "message":"%msg"}%n
|
||||
25
src/main/java/com/release11/klaus/model/EventRequestDto.java
Normal file
25
src/main/java/com/release11/klaus/model/EventRequestDto.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.release11.klaus.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class EventRequestDto {
|
||||
|
||||
private UUID clientUUID;
|
||||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
|
||||
private LocalDateTime localDateTimeFrom;
|
||||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
|
||||
private LocalDateTime localDateTimeTo;
|
||||
private int mockedResponseId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.release11.klaus.repository;
|
||||
|
||||
import com.release11.klaus.model.Event;
|
||||
import com.release11.klaus.utilis.BusinessKey;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Repository
|
||||
@Transactional
|
||||
public interface EventRepository {
|
||||
List<Event> findEvents(LocalDateTime localDateTimeFrom, LocalDateTime localDateTimeTo,
|
||||
Map<BusinessKey, String> businessKeys);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.release11.klaus.repository;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.release11.klaus.model.Event;
|
||||
import com.release11.klaus.utilis.BusinessKey;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.boot.configurationprocessor.json.JSONException;
|
||||
import org.springframework.boot.configurationprocessor.json.JSONObject;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Repository
|
||||
@AllArgsConstructor
|
||||
public class EventRepositoryImpl implements EventRepository {
|
||||
|
||||
private final String LOG_PREFIX = "logstash_";
|
||||
private final JedisPool jedisPool;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public List<Event> findEvents(LocalDateTime localDateTimeFrom, LocalDateTime localDateTimeTo,
|
||||
Map<BusinessKey, String> businessKeys) {
|
||||
List<String> eventStrings = findEventsBetweenDates(localDateTimeFrom.toLocalDate(), localDateTimeTo.toLocalDate());
|
||||
if (businessKeys.size() > 0) {
|
||||
eventStrings = businessKeysFilter(eventStrings, businessKeys);
|
||||
}
|
||||
List<Event> events = parseEvents(eventStrings);
|
||||
if (localDateTimeFrom.toLocalTime() != LocalTime.MIN) {
|
||||
events = events.stream().filter(event -> event.getDateTimeStamp().compareTo(localDateTimeFrom) >= 0)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return events.stream().filter(event -> event.getDateTimeStamp().compareTo(localDateTimeTo) <= 0)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<String> findEventsBetweenDates(LocalDate localDateFrom, LocalDate localDateTo) {
|
||||
try (Jedis jedis = jedisPool.getResource()) {
|
||||
return localDateFrom.datesUntil(localDateTo.plusDays(1)).map(day -> LOG_PREFIX + day.toString())
|
||||
.map(key -> jedis.lrange(key, 0, -1)).flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> businessKeysFilter(List<String> events, Map<BusinessKey, String> businessKeys) {
|
||||
List<String> resultList = new ArrayList<>();
|
||||
for (Map.Entry<BusinessKey, String> entry : businessKeys.entrySet()) {
|
||||
String stringPattern = "\"" + entry.getKey() + ":" + entry.getValue() + "\"";
|
||||
resultList = events.stream().filter(s -> s.contains(stringPattern)).collect(Collectors.toList());
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
private List<Event> parseEvents(List<String> eventStrings) {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (String eventString : eventStrings) {
|
||||
try {
|
||||
events.add(objectMapper.readValue(eventString, Event.class));
|
||||
} catch (JsonProcessingException e) {
|
||||
System.out.println(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return events;
|
||||
}
|
||||
}
|
||||
12
src/main/java/com/release11/klaus/service/EtrackService.java
Normal file
12
src/main/java/com/release11/klaus/service/EtrackService.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.release11.klaus.service;
|
||||
|
||||
import com.release11.klaus.model.Event;
|
||||
import com.release11.klaus.model.EventRequestDto;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public interface EtrackService {
|
||||
List<Event> getEventsByDateTimeAndBusinessKeys(EventRequestDto eventsDto);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.release11.klaus.service;
|
||||
|
||||
import com.release11.klaus.model.Event;
|
||||
import com.release11.klaus.model.EventRequestDto;
|
||||
import com.release11.klaus.repository.EventRepository;
|
||||
import com.release11.klaus.utilis.BusinessKey;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class EtrackServiceImpl implements EtrackService {
|
||||
|
||||
private final EventRepository eventRepository;
|
||||
|
||||
@Override
|
||||
public List<Event> getEventsByDateTimeAndBusinessKeys(EventRequestDto eventsDto) {
|
||||
Map<BusinessKey, String> businessKeys = new HashMap<>();
|
||||
businessKeys.put(BusinessKey.CLIENT_UUID, eventsDto.getClientUUID().toString());
|
||||
return eventRepository.findEvents(eventsDto.getLocalDateTimeFrom(), eventsDto.getLocalDateTimeTo(),
|
||||
businessKeys);
|
||||
}
|
||||
}
|
||||
224
src/main/java/com/release11/klaus/utilis/RedisAppender.java
Normal file
224
src/main/java/com/release11/klaus/utilis/RedisAppender.java
Normal file
@@ -0,0 +1,224 @@
|
||||
package com.release11.klaus.utilis;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.cwbase.logback.AdditionalField;
|
||||
import com.cwbase.logback.JSONEventLayout;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Layout;
|
||||
import ch.qos.logback.core.UnsynchronizedAppenderBase;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
public class RedisAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
|
||||
|
||||
JedisPool pool;
|
||||
|
||||
// keep this for config compatibility for now
|
||||
JSONEventLayout jsonlayout;
|
||||
|
||||
Layout<ILoggingEvent> layout;
|
||||
|
||||
// logger configurable options
|
||||
String host = "localhost";
|
||||
int port = Protocol.DEFAULT_PORT;
|
||||
String key = null;
|
||||
int timeout = Protocol.DEFAULT_TIMEOUT;
|
||||
String password = null;
|
||||
int database = Protocol.DEFAULT_DATABASE;
|
||||
|
||||
public RedisAppender() {
|
||||
jsonlayout = new JSONEventLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent event) {
|
||||
Jedis client = pool.getResource();
|
||||
try {
|
||||
String json = layout == null ? jsonlayout.doLayout(event) : layout.doLayout(event);
|
||||
key = "logstash_" + LocalDate.now();
|
||||
client.rpush(key, json);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (client != null) {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getSource() {
|
||||
return jsonlayout.getSource();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setSource(String source) {
|
||||
jsonlayout.setSource(source);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getSourceHost() {
|
||||
return jsonlayout.getSourceHost();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setSourceHost(String sourceHost) {
|
||||
jsonlayout.setSourceHost(sourceHost);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getSourcePath() {
|
||||
return jsonlayout.getSourcePath();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setSourcePath(String sourcePath) {
|
||||
jsonlayout.setSourcePath(sourcePath);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getTags() {
|
||||
if (jsonlayout.getTags() != null) {
|
||||
Iterator<String> i = jsonlayout.getTags().iterator();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (i.hasNext()) {
|
||||
sb.append(i.next());
|
||||
if (i.hasNext()) {
|
||||
sb.append(',');
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setTags(String tags) {
|
||||
if (tags != null) {
|
||||
String[] atags = tags.split(",");
|
||||
jsonlayout.setTags(Arrays.asList(atags));
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getType() {
|
||||
return jsonlayout.getType();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setType(String type) {
|
||||
jsonlayout.setType(type);
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public int getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public void setDatabase(int database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setMdc(boolean flag) {
|
||||
jsonlayout.setProperties(flag);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean getMdc() {
|
||||
return jsonlayout.getProperties();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setLocation(boolean flag) {
|
||||
jsonlayout.setLocationInfo(flag);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean getLocation() {
|
||||
return jsonlayout.getLocationInfo();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setCallerStackIndex(int index) {
|
||||
jsonlayout.setCallerStackIdx(index);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getCallerStackIndex() {
|
||||
return jsonlayout.getCallerStackIdx();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void addAdditionalField(AdditionalField p) {
|
||||
jsonlayout.addAdditionalField(p);
|
||||
}
|
||||
|
||||
public Layout<ILoggingEvent> getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
public void setLayout(Layout<ILoggingEvent> layout) {
|
||||
this.layout = layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
|
||||
config.setTestOnBorrow(true);
|
||||
pool = new JedisPool(config, host, port, timeout, password, database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
pool.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
14
src/main/resources/static/css/styles.css
Normal file
14
src/main/resources/static/css/styles.css
Normal file
@@ -0,0 +1,14 @@
|
||||
.page-section{
|
||||
padding: 2rem 0;
|
||||
}
|
||||
|
||||
.page-section .column{
|
||||
float: left;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.page-section .row:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
Reference in New Issue
Block a user