diff --git a/nladmin-system/pom.xml b/nladmin-system/pom.xml index 78d2e5638..3ef99f3fb 100644 --- a/nladmin-system/pom.xml +++ b/nladmin-system/pom.xml @@ -127,6 +127,19 @@ oshi-core 5.0.1 + + + + + com.github.loki4j + loki-logback-appender-jdk8 + 1.3.2 + + + org.apache.httpcomponents + httpclient + 4.5.13 + diff --git a/nladmin-system/src/main/java/org/nl/modules/common/annotation/RateLimiter.java b/nladmin-system/src/main/java/org/nl/modules/common/annotation/RateLimiter.java new file mode 100644 index 000000000..98cba38e9 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/common/annotation/RateLimiter.java @@ -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; +} diff --git a/nladmin-system/src/main/java/org/nl/modules/loki/rest/LokiController.java b/nladmin-system/src/main/java/org/nl/modules/loki/rest/LokiController.java new file mode 100644 index 000000000..69cd1d0fc --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/loki/rest/LokiController.java @@ -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 labels() { + return new ResponseEntity<>(lokiService.getLabels(), HttpStatus.OK); + } + + @PostMapping("/values") + @ApiOperation("根据标签获取值") + public ResponseEntity getAllValues(@RequestBody String label) { + return new ResponseEntity<>(lokiService.getValuesByLabel(label), HttpStatus.OK); + } + + @PostMapping("/logs") + @ApiOperation("获取日志") + @RateLimiter(value = 1, timeout = 300) // 限流 + public ResponseEntity getLogData(@RequestBody JSONObject json) { + return new ResponseEntity<>(lokiService.getLogData(json), HttpStatus.OK); + } +} diff --git a/nladmin-system/src/main/java/org/nl/modules/loki/service/LokiService.java b/nladmin-system/src/main/java/org/nl/modules/loki/service/LokiService.java new file mode 100644 index 000000000..dedd921eb --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/loki/service/LokiService.java @@ -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); +} diff --git a/nladmin-system/src/main/java/org/nl/modules/loki/service/impl/LokiServiceImpl.java b/nladmin-system/src/main/java/org/nl/modules/loki/service/impl/LokiServiceImpl.java new file mode 100644 index 000000000..237fc6665 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/loki/service/impl/LokiServiceImpl.java @@ -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; + } + +} diff --git a/nladmin-system/src/main/java/org/nl/modules/system/domain/User.java b/nladmin-system/src/main/java/org/nl/modules/system/domain/User.java index 54d709066..22179b1e3 100644 --- a/nladmin-system/src/main/java/org/nl/modules/system/domain/User.java +++ b/nladmin-system/src/main/java/org/nl/modules/system/domain/User.java @@ -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; diff --git a/nladmin-system/src/main/java/org/nl/modules/system/service/impl/UserServiceImpl.java b/nladmin-system/src/main/java/org/nl/modules/system/service/impl/UserServiceImpl.java index 90d5c56f0..708d108be 100644 --- a/nladmin-system/src/main/java/org/nl/modules/system/service/impl/UserServiceImpl.java +++ b/nladmin-system/src/main/java/org/nl/modules/system/service/impl/UserServiceImpl.java @@ -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 diff --git a/nladmin-system/src/main/resources/config/application-dev.yml b/nladmin-system/src/main/resources/config/application-dev.yml index f37c4f0b7..a3bbd8cde 100644 --- a/nladmin-system/src/main/resources/config/application-dev.yml +++ b/nladmin-system/src/main/resources/config/application-dev.yml @@ -150,4 +150,8 @@ sa-token: is-log: false jwt-secret-key: opsjajisdnnca0sdkksdfaaasdfwwq # token 前缀 -# token-prefix: Bearer \ No newline at end of file +# token-prefix: Bearer + +loki: + url: http://localhost:3100/loki/api/v1 + systemName: acs \ No newline at end of file diff --git a/nladmin-system/src/main/resources/logback-spring.xml b/nladmin-system/src/main/resources/logback-spring.xml index 01130dd52..183f0c8b5 100644 --- a/nladmin-system/src/main/resources/logback-spring.xml +++ b/nladmin-system/src/main/resources/logback-spring.xml @@ -14,6 +14,10 @@ https://juejin.cn/post/6844903775631572999 + + + + + + 1000 + + ${LOKI_URL}/push + + + + system=${SYSTEM_NAME},level=%level,logType=%X{log_file_type:-logType},device=%X{device_code_log:-device} + + + ${log.pattern} + + true + + + + @@ -82,6 +104,7 @@ https://juejin.cn/post/6844903775631572999 + diff --git a/nladmin-ui/package.json b/nladmin-ui/package.json index bda4ee1b8..4fcddd2fc 100644 --- a/nladmin-ui/package.json +++ b/nladmin-ui/package.json @@ -37,6 +37,7 @@ "@logicflow/extension": "^1.1.22", "@riophae/vue-treeselect": "0.4.0", "af-table-column": "^1.0.3", + "ansi_up": "^5.1.0", "axios": "0.18.1", "clipboard": "^2.0.4", "codemirror": "^5.49.2", diff --git a/nladmin-ui/src/views/loki/api/loki.js b/nladmin-ui/src/views/loki/api/loki.js new file mode 100644 index 000000000..4adb6b525 --- /dev/null +++ b/nladmin-ui/src/views/loki/api/loki.js @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +export function getAllLabels() { + return request({ + url: 'api/loki/labels', + method: 'get' + }) +} + +export function getAllValues(label) { + return request({ + url: 'api/loki/values', + method: 'post', + data: label + }) +} + +export function getLogData(param) { + return request({ + url: 'api/loki/logs', + method: 'post', + data: param + }) +} + +export default { getAllLabels, getAllValues, getLogData } diff --git a/nladmin-ui/src/views/loki/view/index.vue b/nladmin-ui/src/views/loki/view/index.vue new file mode 100644 index 000000000..c7966c5fa --- /dev/null +++ b/nladmin-ui/src/views/loki/view/index.vue @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + backward + forward + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 查询{{ runStatu }} + + {{ item.label }} + + + + + + + + + + + + + + + + + + + + + + +