5 changed files with 181 additions and 2 deletions
@ -1,5 +1,5 @@ |
|||||
FROM python:3.10 |
FROM python:3.10 |
||||
RUN python -m pip install aiodocker aiohttp && mkdir /app |
RUN python -m pip install aiodocker==0.21.0 aiohttp==3.9.5 && mkdir /app |
||||
WORKDIR /app |
WORKDIR /app |
||||
COPY ./ ./ |
COPY ./ ./ |
||||
ENV PYTHONUNBUFFERED 1 |
ENV PYTHONUNBUFFERED 1 |
||||
|
@ -0,0 +1,29 @@ |
|||||
|
package app.controllers.other; |
||||
|
|
||||
|
import app.annotations.interfaces.CheckPermitionFlag; |
||||
|
import app.annotations.interfaces.CheckWebAccess; |
||||
|
import app.annotations.interfaces.CollectStatistic; |
||||
|
import app.services.ErrorService; |
||||
|
import jakarta.servlet.http.HttpServletRequest; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
@RestController |
||||
|
@RequestMapping("/api/error") |
||||
|
public class ErrorController { |
||||
|
|
||||
|
@Autowired |
||||
|
private ErrorService errorService; |
||||
|
|
||||
|
@GetMapping("/list") |
||||
|
@CheckWebAccess |
||||
|
@CheckPermitionFlag |
||||
|
@CollectStatistic |
||||
|
public Map getError(HttpServletRequest request, |
||||
|
@RequestParam(defaultValue = "5") Integer limit, |
||||
|
@RequestParam(defaultValue = "0") Integer offset) { |
||||
|
return errorService.listError(offset, limit); |
||||
|
} |
||||
|
} |
@ -0,0 +1,73 @@ |
|||||
|
package app.entities.db; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||
|
import jakarta.servlet.http.HttpServletRequest; |
||||
|
|
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
import java.time.Instant; |
||||
|
import java.util.Arrays; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
public class ErrorDb { |
||||
|
private final Integer id; |
||||
|
private final Long timestamp; |
||||
|
private final String message; |
||||
|
private final String trace; |
||||
|
private final String query; |
||||
|
private Throwable e; |
||||
|
|
||||
|
public ErrorDb(ResultSet rs) throws SQLException { |
||||
|
this.id = rs.getInt("id"); |
||||
|
this.timestamp = rs.getTimestamp("err_timestamp").getTime(); |
||||
|
this.message = rs.getString("err_message"); |
||||
|
this.trace = rs.getString("err_trace"); |
||||
|
this.query = rs.getString("err_query"); |
||||
|
this.e = null; |
||||
|
} |
||||
|
|
||||
|
public ErrorDb(Throwable e, String query) { |
||||
|
this.id = null; |
||||
|
this.timestamp = Instant.now().getEpochSecond(); |
||||
|
this.message = e.toString(); |
||||
|
this.trace = Arrays.stream(e.getStackTrace()) |
||||
|
.map(StackTraceElement::toString) |
||||
|
.collect(Collectors.joining("\n")); |
||||
|
this.query = query; |
||||
|
this.e = e; |
||||
|
} |
||||
|
|
||||
|
public static String Request2Query(HttpServletRequest request) { |
||||
|
if (request == null) return null; |
||||
|
|
||||
|
StringBuilder str = new StringBuilder(); |
||||
|
str.append(request.getMethod()).append(" "); |
||||
|
str.append(request.getRequestURI()).append("?").append(request.getQueryString()); |
||||
|
return str.toString(); |
||||
|
} |
||||
|
|
||||
|
public Integer getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public Long getTimestamp() { |
||||
|
return timestamp; |
||||
|
} |
||||
|
|
||||
|
public String getMessage() { |
||||
|
return message; |
||||
|
} |
||||
|
|
||||
|
public String getTrace() { |
||||
|
return trace; |
||||
|
} |
||||
|
|
||||
|
public String getQuery() { |
||||
|
return query; |
||||
|
} |
||||
|
|
||||
|
@JsonIgnore |
||||
|
public Throwable getE() { |
||||
|
return e; |
||||
|
} |
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
package app.services; |
||||
|
|
||||
|
import app.entities.db.ErrorDb; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Qualifier; |
||||
|
import org.springframework.jdbc.core.JdbcTemplate; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/* |
||||
|
create table tf2_facti13.backend_errors |
||||
|
( |
||||
|
id serial, |
||||
|
err_timestamp timestamp default current_timestamp, |
||||
|
err_message varchar, |
||||
|
err_trace varchar, |
||||
|
err_query varchar |
||||
|
); |
||||
|
|
||||
|
alter table tf2_facti13.backend_errors |
||||
|
owner to sourcemod; |
||||
|
*/ |
||||
|
@Service |
||||
|
public class ErrorService { |
||||
|
|
||||
|
@Autowired |
||||
|
@Qualifier("jt_rw") |
||||
|
private JdbcTemplate jdbcTemplate_rw; |
||||
|
|
||||
|
@Autowired |
||||
|
@Qualifier("jt_ro") |
||||
|
private JdbcTemplate jdbcTemplate_ro; |
||||
|
|
||||
|
private final Logger logger = LoggerFactory.getLogger(getClass()); |
||||
|
|
||||
|
public void insertError(ErrorDb errorDb) { |
||||
|
try { |
||||
|
jdbcTemplate_rw.update("INSERT INTO backend_errors (err_message, err_trace, err_query) VALUES (?,?,?)", |
||||
|
errorDb.getMessage(), errorDb.getTrace(), errorDb.getQuery()); |
||||
|
} catch (Exception e) { |
||||
|
logger.error("Cannot insert err into db", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Map listError(int offset, int limit) { |
||||
|
List<ErrorDb> result = jdbcTemplate_ro.query("SELECT * FROM backend_errors ORDER BY id DESC LIMIT ? OFFSET ?", |
||||
|
new Object[]{limit, offset}, (rs, n) -> new ErrorDb(rs)); |
||||
|
Long count = jdbcTemplate_ro.query("SELECT count(*) as c FROM backend_errors", (rs, n) -> rs.getLong("c")).get(0); |
||||
|
|
||||
|
return Map.of("result", result, "count", count); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
Loading…
Reference in new issue