日志系统
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
package org.nl.modules.common.annotation;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author: lyd
|
||||
* @Description: 限流注解,添加了 {@link AliasFor} 必须通过 {@link AnnotationUtils} 获取,才会生效
|
||||
* @Date: 2022-08-15
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RateLimiter {
|
||||
int NOT_LIMITED = 0;
|
||||
|
||||
/**
|
||||
* qps
|
||||
*/
|
||||
@AliasFor("qps") double value() default NOT_LIMITED;
|
||||
|
||||
/**
|
||||
* qps
|
||||
*/
|
||||
@AliasFor("value") double qps() default NOT_LIMITED;
|
||||
|
||||
/**
|
||||
* 超时时长
|
||||
*/
|
||||
int timeout() default 0;
|
||||
|
||||
/**
|
||||
* 超时时间单位
|
||||
*/
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.nl.modules.loki.rest;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.modules.common.annotation.RateLimiter;
|
||||
import org.nl.modules.loki.service.LokiService;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @Author: lyd
|
||||
* @Description: 日志监控
|
||||
* @Date: 2022-08-15
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "日志监控")
|
||||
@RequestMapping("/api/loki")
|
||||
@Slf4j
|
||||
public class LokiController {
|
||||
|
||||
private final LokiService lokiService;
|
||||
|
||||
@GetMapping("/labels")
|
||||
@ApiOperation("获取标签")
|
||||
public ResponseEntity<Object> labels() {
|
||||
return new ResponseEntity<>(lokiService.getLabels(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/values")
|
||||
@ApiOperation("根据标签获取值")
|
||||
public ResponseEntity<Object> getAllValues(@RequestBody String label) {
|
||||
return new ResponseEntity<>(lokiService.getValuesByLabel(label), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/logs")
|
||||
@ApiOperation("获取日志")
|
||||
@RateLimiter(value = 1, timeout = 300) // 限流
|
||||
public ResponseEntity<Object> getLogData(@RequestBody JSONObject json) {
|
||||
return new ResponseEntity<>(lokiService.getLogData(json), HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.nl.modules.loki.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* @Author: lyd
|
||||
* @Description: 服务类
|
||||
* @Date: 2022-08-15
|
||||
*/
|
||||
public interface LokiService {
|
||||
/**
|
||||
* 获取日志的所有标签
|
||||
* @return
|
||||
*/
|
||||
JSONObject getLabels();
|
||||
|
||||
/**
|
||||
* 根据label获取值
|
||||
* @param label
|
||||
* @return
|
||||
*/
|
||||
JSONObject getValuesByLabel(String label);
|
||||
|
||||
/**
|
||||
* 获取日志信息
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
JSONObject getLogData(JSONObject json);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.nl.modules.loki.service.impl;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.nl.modules.loki.service.LokiService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Author: lyd
|
||||
* @Description: 实现类
|
||||
* @Date: 2022-08-15
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LokiServiceImpl implements LokiService {
|
||||
|
||||
@Value("${loki.url}")
|
||||
private String lokiUrl;
|
||||
|
||||
@Value("${loki.systemName}")
|
||||
private String systemName;
|
||||
|
||||
@Override
|
||||
public JSONObject getLabels() {
|
||||
String result = HttpUtil.get(lokiUrl + "/labels", CharsetUtil.CHARSET_UTF_8);
|
||||
JSONObject parse = (JSONObject) JSONObject.parse(result);
|
||||
return parse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getValuesByLabel(String label) {
|
||||
String result = HttpUtil.get(lokiUrl + "/label/" + label + "/values", CharsetUtil.CHARSET_UTF_8);
|
||||
JSONObject parse = (JSONObject) JSONObject.parse(result);
|
||||
return parse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getLogData(JSONObject json) {
|
||||
String logLabel = "";
|
||||
String logLabelValue = "";
|
||||
Long start = 0L;
|
||||
Long end = 0L;
|
||||
String text = "";
|
||||
String limit = "100";
|
||||
String direction = "backward";
|
||||
if (json.get("logLabel") != null) logLabel = json.getString("logLabel");
|
||||
if (json.get("logLabelValue") != null) logLabelValue = json.getString("logLabelValue");
|
||||
if (json.get("text") != null) text = json.getString("text");
|
||||
if (json.get("start") != null) start = json.getLong("start");
|
||||
if (json.get("end") != null) end = json.getLong("end");
|
||||
if (json.get("limits") != null) limit = json.getString("limits");
|
||||
if (json.get("direction") != null) direction = json.getString("direction");
|
||||
/**
|
||||
* 组织参数
|
||||
* 纳秒数
|
||||
* 1660037391880000000
|
||||
* 1641453208415000000
|
||||
* http://localhost:3100/loki/api/v1/query_range?query={host="localhost"} |= ``&limit=1500&start=1641453208415000000&end=1660027623419419002
|
||||
*/
|
||||
JSONObject parse = null;
|
||||
String query = lokiUrl + "/query_range?query={system=\"" + systemName + "\", " + logLabel + "=\"" + logLabelValue + "\"} |= `" + text + "`";
|
||||
String result = "";
|
||||
if (start==0L) {
|
||||
result = HttpUtil.get(query + "&limit=" + limit + "&direction=" + direction, CharsetUtil.CHARSET_UTF_8);
|
||||
} else {
|
||||
result = HttpUtil.get(query + "&limit=" + limit + "&start=" + start + "&end=" + end + "&direction=" + direction, CharsetUtil.CHARSET_UTF_8);
|
||||
}
|
||||
try {
|
||||
parse = (JSONObject) JSONObject.parse(result);
|
||||
} catch (Exception e) {
|
||||
// reslut的值可能为:too many outstanding requests,无法转化成Json
|
||||
System.out.println("reslut:" + result);
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return parse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -70,11 +70,9 @@ public class User extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "用户昵称")
|
||||
private String nickName;
|
||||
|
||||
@Email
|
||||
@ApiModelProperty(value = "邮箱")
|
||||
private String email;
|
||||
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "电话号码")
|
||||
private String phone;
|
||||
|
||||
|
||||
@@ -21,11 +21,9 @@ import org.nl.modules.common.config.FileProperties;
|
||||
import org.nl.modules.common.exception.EntityExistException;
|
||||
import org.nl.modules.common.exception.EntityNotFoundException;
|
||||
import org.nl.modules.common.utils.*;
|
||||
import org.nl.modules.security.satoken.utils.FlushSessionUtil;
|
||||
import org.nl.modules.security.service.OnlineUserService;
|
||||
import org.nl.modules.system.domain.User;
|
||||
import org.nl.modules.system.repository.UserRepository;
|
||||
import org.nl.modules.system.service.RoleService;
|
||||
import org.nl.modules.system.service.UserService;
|
||||
import org.nl.modules.system.service.dto.RoleSmallDto;
|
||||
import org.nl.modules.system.service.dto.UserDto;
|
||||
@@ -60,8 +58,8 @@ public class UserServiceImpl implements UserService {
|
||||
private final FileProperties properties;
|
||||
private final RedisUtils redisUtils;
|
||||
private final OnlineUserService onlineUserService;
|
||||
private final FlushSessionUtil flushSessionUtil;
|
||||
private final RoleService roleService;
|
||||
// private final FlushSessionUtil flushSessionUtil;
|
||||
// private final RoleService roleService;
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
@@ -150,4 +150,8 @@ sa-token:
|
||||
is-log: false
|
||||
jwt-secret-key: opsjajisdnnca0sdkksdfaaasdfwwq
|
||||
# token 前缀
|
||||
# token-prefix: Bearer
|
||||
# token-prefix: Bearer
|
||||
|
||||
loki:
|
||||
url: http://localhost:3100/loki/api/v1
|
||||
systemName: acs
|
||||
@@ -14,6 +14,10 @@ https://juejin.cn/post/6844903775631572999
|
||||
<property name="log.pattern"
|
||||
value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)"/>
|
||||
<springProperty scope="context" name="logPath" source="logging.file.path" defaultValue="logs"/>
|
||||
<springProperty scope="context" name="lokiUrl" source="loki.url"/>
|
||||
<springProperty scope="context" name="systemName" source="loki.systemName"/>
|
||||
<property name="LOKI_URL" value="${lokiUrl}"/>
|
||||
<property name="SYSTEM_NAME" value="${systemName}"/>
|
||||
<property name="LOG_HOME" value="${logPath}"/>
|
||||
<!--引入默认的一些设置-->
|
||||
<!--<include resource="log/XrToMes.xml"/>
|
||||
@@ -54,10 +58,28 @@ https://juejin.cn/post/6844903775631572999
|
||||
<appender-ref ref="FILE"/>
|
||||
</appender>
|
||||
|
||||
<!--添加loki-->
|
||||
<appender name="lokiAppender" class="com.github.loki4j.logback.Loki4jAppender">
|
||||
<batchTimeoutMs>1000</batchTimeoutMs>
|
||||
<http class="com.github.loki4j.logback.ApacheHttpSender">
|
||||
<url>${LOKI_URL}/push</url>
|
||||
</http>
|
||||
<format>
|
||||
<label>
|
||||
<pattern>system=${SYSTEM_NAME},level=%level,logType=%X{log_file_type:-logType},device=%X{device_code_log:-device}</pattern>
|
||||
</label>
|
||||
<message>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</message>
|
||||
<sortByTime>true</sortByTime>
|
||||
</format>
|
||||
</appender>
|
||||
|
||||
<!--开发环境:打印控制台-->
|
||||
<springProfile name="dev">
|
||||
<root level="info">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
</root>
|
||||
|
||||
<logger name="jdbc.audit" level="ERROR" additivity="false">
|
||||
@@ -82,6 +104,7 @@ https://juejin.cn/post/6844903775631572999
|
||||
<springProfile name="prod">
|
||||
<root level="info">
|
||||
<appender-ref ref="asyncFileAppender"/>
|
||||
<appender-ref ref="lokiAppender" />
|
||||
</root>
|
||||
<logger name="jdbc.audit" level="ERROR" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
|
||||
Reference in New Issue
Block a user