├── console ├── src │ ├── views │ │ ├── system │ │ │ └── systemManage.vue │ │ ├── trace │ │ │ └── BusinessTrace.vue │ │ ├── table │ │ │ └── ArticleView.vue │ │ ├── user │ │ │ └── index.vue │ │ └── tree │ │ │ └── index.vue │ ├── assets │ │ ├── main.jpg │ │ └── 404_images │ │ │ ├── 404.png │ │ │ └── 404_cloud.png │ ├── layout │ │ ├── components │ │ │ ├── index.js │ │ │ ├── Sidebar │ │ │ │ ├── FixiOSBug.js │ │ │ │ ├── Link.vue │ │ │ │ ├── Item.vue │ │ │ │ ├── index.vue │ │ │ │ └── Logo.vue │ │ │ └── AppMain.vue │ │ ├── mixin │ │ │ └── ResizeHandler.js │ │ └── index.vue │ ├── App.vue │ ├── api │ │ ├── mappingApi.js │ │ ├── environmentApi.js │ │ ├── errorReportedApi.js │ │ ├── subscribeApi.js │ │ ├── table.js │ │ ├── documentApi.js │ │ ├── user.js │ │ ├── cacheApi.js │ │ ├── beanApi.js │ │ ├── errorCodeApi.js │ │ ├── logApi.js │ │ ├── runtimeApi.js │ │ └── articleApi.js │ ├── icons │ │ ├── svg │ │ │ ├── link.svg │ │ │ ├── user.svg │ │ │ ├── example.svg │ │ │ ├── table.svg │ │ │ ├── password.svg │ │ │ ├── nested.svg │ │ │ ├── eye.svg │ │ │ ├── eye-open.svg │ │ │ ├── error-code.svg │ │ │ ├── tree.svg │ │ │ ├── config.svg │ │ │ └── dashboard.svg │ │ ├── index.js │ │ └── svgo.yml │ ├── utils │ │ ├── get-page-title.js │ │ ├── auth.js │ │ ├── validate.js │ │ └── highlight.js │ ├── store │ │ ├── getters.js │ │ ├── index.js │ │ └── modules │ │ │ ├── settings.js │ │ │ └── app.js │ ├── settings.js │ ├── styles │ │ ├── mixin.scss │ │ ├── variables.scss │ │ ├── element-ui.scss │ │ ├── transition.scss │ │ ├── index.scss │ │ ├── my-awesome-json-theme.scss │ │ └── custom-awesome-json-theme.scss │ ├── components │ │ ├── code │ │ │ └── CodePreview.vue │ │ ├── md │ │ │ ├── MdView.vue │ │ │ └── MdEdit.vue │ │ ├── Hamburger │ │ │ └── index.vue │ │ ├── SvgIcon │ │ │ └── index.vue │ │ ├── selects │ │ │ └── ArticleLabelSearchSelect.vue │ │ ├── GDJsonEditor │ │ │ └── index.vue │ │ └── Breadcrumb │ │ │ └── index.vue │ ├── main.js │ └── permission.js ├── .eslintignore ├── tests │ └── unit │ │ ├── .eslintrc.js │ │ ├── utils │ │ ├── param2Obj.spec.js │ │ ├── validate.spec.js │ │ ├── formatTime.spec.js │ │ └── parseTime.spec.js │ │ └── components │ │ ├── SvgIcon.spec.js │ │ └── Hamburger.spec.js ├── public │ ├── 6176c7b460524356acd2a3d7eb174df9.js │ ├── favicon.ico │ └── index.html ├── .env.production ├── .env.development ├── .travis.yml ├── .env.staging ├── jsconfig.json ├── postcss.config.js ├── .gitignore ├── .editorconfig ├── mock │ ├── utils.js │ ├── table.js │ ├── index.js │ └── user.js ├── babel.config.js ├── jest.config.js ├── LICENSE └── package.json ├── mavenDeploy.bat ├── mavenInstall.bat ├── runtime-record-core └── src │ └── main │ ├── resources │ ├── material │ │ └── README.md │ ├── runtime-log-version.properties │ ├── static │ │ └── runtimeLogo.png │ ├── notify │ │ └── feishu │ │ │ └── subscribeLog.json │ └── chart │ │ ├── MemoryChartLine.json │ │ └── ThreadChartLine.json │ └── java │ └── com │ └── aio │ └── runtime │ ├── db │ └── orm │ │ ├── package-info.java │ │ ├── annotations │ │ ├── AioField.java │ │ ├── AioId.java │ │ └── AioTable.java │ │ ├── domain │ │ ├── enums │ │ │ ├── AioDbTypeEnum.java │ │ │ └── ConditionEnum.java │ │ └── bo │ │ │ └── Condition.java │ │ └── utils │ │ └── CamelToSnakeUtils.java │ ├── jvm │ ├── package-info.java │ ├── domain │ │ ├── QueryJvmParams.java │ │ └── AioJvmBo.java │ ├── service │ │ └── AioRuntimeJvmService.java │ └── AioJvmConfig.java │ ├── log │ ├── package-info.java │ ├── domain │ │ ├── SetLogLevelParams.java │ │ ├── AioLogAppendProperties.java │ │ ├── AioLogBo.java │ │ ├── QueryLogParams.java │ │ ├── AioLogParamsBo.java │ │ └── AioLogVo.java │ ├── service │ │ ├── AioLogService.java │ │ └── AbstractAioLogService.java │ ├── AioLogAppendConfig.java │ ├── save │ │ └── LogSaveCache.java │ └── append │ │ ├── AioLogAppenderRunner.java │ │ └── AioLogLiteAppender.java │ ├── environment │ ├── package-info.java │ ├── domain │ │ ├── EnvironmentItemDictBo.java │ │ ├── QueryEnvironmentParams.java │ │ └── EnvironmentItemBo.java │ ├── service │ │ └── IAioEnvironmentService.java │ └── controller │ │ └── AioEnvironmentController.java │ ├── beans │ ├── package-info.java │ ├── domain │ │ ├── BeanMethodParameter.java │ │ ├── QueryBeanMethodInfoParams.java │ │ ├── BeanMethodInfo.java │ │ ├── QueryBeanParams.java │ │ ├── RunMethodParameter.java │ │ ├── AioBeanVo.java │ │ └── AioBeanBo.java │ ├── service │ │ └── IAioBeansService.java │ └── AioRuntimeBeansConfig.java │ ├── mappings │ ├── package-info.java │ ├── domain │ │ ├── QueryMappingParams.java │ │ ├── AioMappingBo.java │ │ └── AioMappingVo.java │ ├── service │ │ └── IAioMappingService.java │ └── controller │ │ └── AioMappingController.java │ ├── reported │ ├── mapper │ │ └── ErrorReportedMapper.java │ ├── service │ │ ├── ErrorReportedService.java │ │ └── impl │ │ │ └── AbstractErrorReportedServiceImpl.java │ ├── domain │ │ ├── ErrorReportedProperties.java │ │ ├── vo │ │ │ └── ErrorReportVo.java │ │ ├── dao │ │ │ └── ErrorReportDo.java │ │ └── params │ │ │ ├── AddErrorParams.java │ │ │ └── QueryErrorParams.java │ ├── ErrorReportedConfig.java │ └── controller │ │ └── ErrorReportedController.java │ ├── subscribe │ ├── mapper │ │ ├── SubscribeLogMapper.java │ │ └── ErrorCodeMapper.java │ ├── domain │ │ ├── properties │ │ │ ├── SubscribeFeiShuProperties.java │ │ │ └── AioSubscribeProperties.java │ │ ├── dao │ │ │ ├── ErrorCodeDo.java │ │ │ └── SubscribeLogDo.java │ │ ├── params │ │ │ ├── UpdateSubscribeLogStatusParams.java │ │ │ ├── AddErrorCodeParams.java │ │ │ ├── QueryErrorCodeParams.java │ │ │ └── QuerySubscribeLogParams.java │ │ ├── bo │ │ │ └── ErrorCodeBo.java │ │ ├── enums │ │ │ └── SubscibeHandleStatusEnum.java │ │ ├── SubscribeLogBo.java │ │ └── SubscribeLogVo.java │ ├── AioSubscribeConfig.java │ ├── service │ │ ├── SubscribeLogService.java │ │ └── ErrorCodeService.java │ ├── AioSubscribeMapperConfig.java │ ├── log │ │ ├── SubscribeAppenderRunner.java │ │ └── SubscribeMarker.java │ └── controller │ │ └── SubscribeLogController.java │ ├── security │ ├── domain │ │ ├── LoginParams.java │ │ ├── UserInfoResult.java │ │ └── RuntimeSecurityProperties.java │ └── RuntimeSecurityConfig.java │ ├── cache │ ├── domain │ │ └── AioCacheBo.java │ └── AioCacheManageConfig.java │ ├── common │ ├── info │ │ ├── AioSystemInfo.java │ │ └── SystemRuntimeInfo.java │ ├── HandleRuntimeException.java │ └── interceptor │ │ └── TraceIdInterceptor.java │ ├── domain │ ├── exception │ │ └── RuntimeSecurityUnAuthException.java │ └── event │ │ └── MappingVisitEvent.java │ └── record │ └── log │ ├── domain │ ├── RecordInfoVo.java │ ├── QueryRecordParams.java │ ├── MappingRecordVo.java │ ├── MappingRecordBo.java │ └── constants │ │ └── MappingLogFieldConstant.java │ ├── service │ ├── MappingLogService.java │ └── AbstractMappingLogService.java │ ├── AioRuntimeApplicationStartedEventListener.java │ ├── config │ ├── properties │ │ └── AioMappingLogProperties.java │ └── RuntimeLogWebViewConfig.java │ ├── AioRuntimeApplicationStartingEventListener.java │ ├── integration │ └── RuntimeRecordModuleDiscover.java │ ├── controller │ └── MappingLogController.java │ └── RuntimeRecordConfig.java ├── docs ├── cmd.md ├── imgs │ └── img.png ├── Bug.md ├── 日志订阅.md ├── jvm.buffer.total.capacity.md ├── JVM内存说明.md ├── 建表语句.md └── jvm线程相关.md ├── runtime-record-servlet └── src │ └── main │ ├── resources │ ├── db.setting │ ├── application.properties │ ├── logback-test.xml │ ├── application-pro.properties │ └── application-dev.properties │ └── java │ └── com │ └── guodun │ └── aio │ └── document │ ├── domain │ └── TestCacheConstants.java │ ├── user │ ├── config │ │ ├── UserModelConfig.java │ │ └── ServletWebInterceptorConfig.java │ ├── domain │ │ └── params │ │ │ └── LoginParams.java │ ├── EnableUserModel.java │ ├── controller │ │ ├── LoginController.java │ │ └── UserController.java │ └── TestAioUserApiImpl.java │ ├── controller │ ├── TestWechatController.java │ └── TestCacheManageController.java │ ├── GuodunDocumentApplication.java │ └── zuul │ └── UserCenterZuulFilter.java ├── runtime-record-spring-boot-starter └── src │ └── main │ └── resources │ └── META-INF │ ├── spring.factories │ └── additional-spring-configuration-metadata.json ├── Dockerfile └── .gitignore /console/src/views/system/systemManage.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mavenDeploy.bat: -------------------------------------------------------------------------------- 1 | mvn clean deploy -DskipTests 2 | -------------------------------------------------------------------------------- /mavenInstall.bat: -------------------------------------------------------------------------------- 1 | mvn clean install -DskipTests 2 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/resources/material/README.md: -------------------------------------------------------------------------------- 1 | # 材料 2 | -------------------------------------------------------------------------------- /console/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | src/assets 3 | public 4 | dist 5 | -------------------------------------------------------------------------------- /docs/cmd.md: -------------------------------------------------------------------------------- 1 | # 上传中央仓库命令 2 | 3 | ```shell 4 | mvn clean install deploy -P release 5 | ``` 6 | -------------------------------------------------------------------------------- /docs/imgs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeisangel/aio-runtime/HEAD/docs/imgs/img.png -------------------------------------------------------------------------------- /console/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/resources/runtime-log-version.properties: -------------------------------------------------------------------------------- 1 | runtime.version=${revision} 2 | -------------------------------------------------------------------------------- /console/public/6176c7b460524356acd2a3d7eb174df9.js: -------------------------------------------------------------------------------- 1 | window.aioSecretKey = '6176c7b460524356acd2a3d7eb174df9'; 2 | -------------------------------------------------------------------------------- /console/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeisangel/aio-runtime/HEAD/console/public/favicon.ico -------------------------------------------------------------------------------- /console/src/assets/main.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeisangel/aio-runtime/HEAD/console/src/assets/main.jpg -------------------------------------------------------------------------------- /docs/Bug.md: -------------------------------------------------------------------------------- 1 | # 待解决的bug 2 | 3 | 1. 运行时业务接口提供更安全的双因子身份验证,或者三因子身份验证 4 | 2. 将安全拦截器接口日志级别降低为debug 5 | 3. 默认启动 6 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/db/orm/package-info.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.db.orm; 2 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/resources/db.setting: -------------------------------------------------------------------------------- 1 | showSql = true 2 | formatSql = true 3 | sqlLevel = debug 4 | -------------------------------------------------------------------------------- /console/.env.production: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'production' 3 | 4 | # base api 5 | VUE_APP_BASE_API = '' 6 | 7 | -------------------------------------------------------------------------------- /console/.env.development: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'development' 3 | 4 | # base api 5 | VUE_APP_BASE_API = '/dev-api' 6 | -------------------------------------------------------------------------------- /console/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 10 3 | script: npm run test 4 | notifications: 5 | email: false 6 | -------------------------------------------------------------------------------- /console/src/assets/404_images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeisangel/aio-runtime/HEAD/console/src/assets/404_images/404.png -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/jvm/package-info.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.jvm; 2 | /** 3 | * JVM 数据 4 | */ 5 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/package-info.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log; 2 | /** 3 | * 日志 4 | * 5 | */ 6 | -------------------------------------------------------------------------------- /console/src/assets/404_images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeisangel/aio-runtime/HEAD/console/src/assets/404_images/404_cloud.png -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/environment/package-info.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.environment; 2 | /** 3 | * 运行环境 4 | */ 5 | -------------------------------------------------------------------------------- /console/.env.staging: -------------------------------------------------------------------------------- 1 | NODE_ENV = production 2 | 3 | # just a flag 4 | ENV = 'staging' 5 | 6 | # base api 7 | VUE_APP_BASE_API = '/stage-api' 8 | 9 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/package-info.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans; 2 | /** 3 | * Beans 模块集成 4 | * 5 | */ 6 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/mappings/package-info.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.mappings; 2 | /** 3 | * 4 | * 请求地址 5 | * 6 | * 7 | * 8 | */ 9 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/resources/static/runtimeLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeisangel/aio-runtime/HEAD/runtime-record-core/src/main/resources/static/runtimeLogo.png -------------------------------------------------------------------------------- /console/src/layout/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Navbar } from './Navbar' 2 | export { default as Sidebar } from './Sidebar' 3 | export { default as AppMain } from './AppMain' 4 | -------------------------------------------------------------------------------- /console/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /console/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "exclude": ["node_modules", "dist"] 9 | } 10 | -------------------------------------------------------------------------------- /console/src/views/trace/BusinessTrace.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | 18 | -------------------------------------------------------------------------------- /console/postcss.config.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | 'plugins': { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | 'autoprefixer': {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /console/src/api/mappingApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getMappingPageApi(data) { 4 | return request({ 5 | url: '/runtime/aio/mapping/page', 6 | method: 'get', 7 | params:data 8 | }) 9 | } 10 | 11 | -------------------------------------------------------------------------------- /console/src/api/environmentApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getEnvironmentPageApi(data) { 4 | return request({ 5 | url: '/runtime/aio/environment/page', 6 | method: 'get', 7 | params:data 8 | }) 9 | } 10 | 11 | -------------------------------------------------------------------------------- /console/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | package-lock.json 8 | tests/**/coverage/ 9 | 10 | # Editor directories and files 11 | .idea 12 | .vscode 13 | *.suo 14 | *.ntvs* 15 | *.njsproj 16 | *.sln 17 | -------------------------------------------------------------------------------- /console/src/api/errorReportedApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getErrorReportedPageApi(data,params) { 4 | return request({ 5 | url: '/runtime/aio/error/reported/page', 6 | method: 'post', 7 | params:params, 8 | data:data 9 | }) 10 | } 11 | 12 | -------------------------------------------------------------------------------- /console/src/icons/svg/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime-record-spring-boot-starter/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.aio.runtime.record.log.RuntimeRecordConfig 2 | org.springframework.context.ApplicationListener=com.aio.runtime.record.log.AioRuntimeApplicationStartingEventListener 3 | -------------------------------------------------------------------------------- /console/src/utils/get-page-title.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from '@/settings' 2 | 3 | const title = defaultSettings.title || 'Vue Admin Template' 4 | 5 | export default function getPageTitle(pageTitle) { 6 | if (pageTitle) { 7 | return `${pageTitle} - ${title}` 8 | } 9 | return `${title}` 10 | } 11 | -------------------------------------------------------------------------------- /console/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /console/src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | sidebar: state => state.app.sidebar, 3 | device: state => state.app.device, 4 | token: state => state.user.token, 5 | avatar: state => state.user.avatar, 6 | name: state => state.user.name, 7 | roles: state => state.user.roles 8 | } 9 | export default getters 10 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/domain/TestCacheConstants.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.domain; 2 | 3 | /** 4 | * @author lzm 5 | * @desc 6 | * @date 2024/08/10 7 | */ 8 | public class TestCacheConstants { 9 | public static final String FORM_FIELD_MAP = "form_field_map"; 10 | } 11 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/jvm/domain/QueryJvmParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.jvm.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc JVMService 8 | * @date 2024/08/20 9 | */ 10 | @Data 11 | public class QueryJvmParams { 12 | private Long[] createTimeRange; 13 | } 14 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/mapper/ErrorReportedMapper.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.mapper; 2 | 3 | import com.aio.runtime.reported.domain.dao.ErrorReportDo; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | public interface ErrorReportedMapper extends BaseMapper { 7 | } 8 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/mapper/SubscribeLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.mapper; 2 | 3 | import com.aio.runtime.subscribe.domain.dao.SubscribeLogDo; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | public interface SubscribeLogMapper extends BaseMapper { 7 | } 8 | -------------------------------------------------------------------------------- /console/src/icons/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '@/components/SvgIcon'// svg component 3 | 4 | // register globally 5 | Vue.component('svg-icon', SvgIcon) 6 | 7 | const req = require.context('./svg', false, /\.svg$/) 8 | const requireAll = requireContext => requireContext.keys().map(requireContext) 9 | requireAll(req) 10 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/domain/BeanMethodParameter.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc Bean方法参数 8 | * @date 2024/08/20 9 | */ 10 | @Data 11 | public class BeanMethodParameter { 12 | private String type; 13 | private Object value; 14 | } 15 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/security/domain/LoginParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.security.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lizhenming 7 | * @desc: 8 | * @date 2022/12/9 22:51 9 | */ 10 | @Data 11 | public class LoginParams { 12 | private String password; 13 | private String username; 14 | } 15 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/user/config/UserModelConfig.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.user.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | 5 | /** 6 | * @author lizhenming 7 | * @desc: 8 | * @date 2022/12/9 22:48 9 | */ 10 | @Configuration 11 | public class UserModelConfig { 12 | } 13 | -------------------------------------------------------------------------------- /console/src/icons/svgo.yml: -------------------------------------------------------------------------------- 1 | # replace default config 2 | 3 | # multipass: true 4 | # full: true 5 | 6 | plugins: 7 | 8 | # - name 9 | # 10 | # or: 11 | # - name: false 12 | # - name: true 13 | # 14 | # or: 15 | # - name: 16 | # param1: 1 17 | # param2: 2 18 | 19 | - removeAttrs: 20 | attrs: 21 | - 'fill' 22 | - 'fill-rule' 23 | -------------------------------------------------------------------------------- /console/src/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 3 | title: 'Vue Admin Template', 4 | 5 | /** 6 | * @type {boolean} true | false 7 | * @description Whether fix the header 8 | */ 9 | fixedHeader: false, 10 | 11 | /** 12 | * @type {boolean} true | false 13 | * @description Whether show the logo in sidebar 14 | */ 15 | sidebarLogo: true 16 | } 17 | -------------------------------------------------------------------------------- /console/src/utils/auth.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const TokenKey = 'vue_admin_template_token' 4 | 5 | export function getToken() { 6 | return Cookies.get(TokenKey) 7 | } 8 | 9 | export function setToken(token) { 10 | return Cookies.set(TokenKey, token) 11 | } 12 | 13 | export function removeToken() { 14 | return Cookies.remove(TokenKey) 15 | } 16 | -------------------------------------------------------------------------------- /docs/日志订阅.md: -------------------------------------------------------------------------------- 1 | # 日志订阅 2 | 3 | ## 日志飞书推送 4 | 5 | ```properties 6 | aio.runtime.log.subscribe.markers=test,test1,test2 7 | aio.runtime.log.subscribe.feishu.webhook=https://open.feishu.cn/open-apis/bot/v2/hook/c91f856d-5f0f-468b-a16d-efc899dce88a 8 | ``` 9 | 10 | > `aio.runtime.log.subscribe.markers` 表示需要推送的订阅标记 11 | > `aio.runtime.log.subscribe.feishu.webhook` 表示飞书机器人的webhook地址 12 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/user/domain/params/LoginParams.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.user.domain.params; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lizhenming 7 | * @desc: 8 | * @date 2022/12/9 22:51 9 | */ 10 | @Data 11 | public class LoginParams { 12 | private String password; 13 | private String username; 14 | } -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/domain/QueryBeanMethodInfoParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 查询bean接口 8 | * @date 2024/08/06 9 | */ 10 | @Data 11 | public class QueryBeanMethodInfoParams { 12 | private String className; 13 | private String method; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/cache/domain/AioCacheBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.cache.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 缓存信息 8 | * @date 2024/08/10 9 | */ 10 | @Data 11 | public class AioCacheBo { 12 | private String cacheManagerName; 13 | private String cacheName; 14 | private String target; 15 | } 16 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/common/info/AioSystemInfo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.common.info; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 系统信息 8 | * @date 2024/08/16 9 | */ 10 | @Data 11 | public class AioSystemInfo { 12 | private String maxMemory; 13 | private String freeMemory; 14 | private String totalMemory; 15 | } 16 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/domain/SetLogLevelParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 设置日志级别参数 8 | * @date 2024/08/25 9 | */ 10 | @Data 11 | public class SetLogLevelParams { 12 | private String name; 13 | private String configuredLevel; 14 | private String effectiveLevel; 15 | } 16 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/properties/SubscribeFeiShuProperties.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.properties; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 订阅飞书属性 8 | * @date 2024/10/08 9 | */ 10 | @Data 11 | public class SubscribeFeiShuProperties { 12 | private String webhook; 13 | private String secret; 14 | } 15 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/mapper/ErrorCodeMapper.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.mapper; 2 | 3 | import com.aio.runtime.subscribe.domain.dao.ErrorCodeDo; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | /** 7 | * @author lzm 8 | * @desc 错误码Mapper 9 | * @date 2025/04/08 10 | */ 11 | public interface ErrorCodeMapper extends BaseMapper { 12 | } 13 | -------------------------------------------------------------------------------- /console/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import getters from './getters' 4 | import app from './modules/app' 5 | import settings from './modules/settings' 6 | import user from './modules/user' 7 | 8 | Vue.use(Vuex) 9 | 10 | const store = new Vuex.Store({ 11 | modules: { 12 | app, 13 | settings, 14 | user 15 | }, 16 | getters 17 | }) 18 | 19 | export default store 20 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/db/orm/annotations/AioField.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.db.orm.annotations; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 7 | */ 8 | @Target({ElementType.FIELD}) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Documented 11 | public @interface AioField { 12 | String value() ; 13 | String type() default ""; 14 | String remark() default ""; 15 | } 16 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/db/orm/domain/enums/AioDbTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.db.orm.domain.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @AllArgsConstructor 7 | @Getter 8 | public enum AioDbTypeEnum { 9 | MYSQL("mysql","mysql"), 10 | SQL_LITE("sqlLite","sqlLite"); 11 | private final String type; 12 | private final String desc; 13 | } 14 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/db/orm/annotations/AioId.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.db.orm.annotations; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 7 | */ 8 | @Target({ElementType.FIELD}) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Documented 11 | public @interface AioId { 12 | String value() default "id"; 13 | String type() default ""; 14 | String remark() default ""; 15 | } 16 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/environment/domain/EnvironmentItemDictBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.environment.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 环境项字典名称 8 | * @date 2024/07/28 9 | */ 10 | @Data 11 | public class EnvironmentItemDictBo { 12 | private String group; 13 | private String key; 14 | private String name; 15 | private String keywords; 16 | } 17 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/dao/ErrorCodeDo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.dao; 2 | 3 | import com.aio.runtime.subscribe.domain.bo.ErrorCodeBo; 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | 6 | /** 7 | * @author lzm 8 | * @desc 错误码维护 9 | * @date 2025/04/07 10 | */ 11 | @TableName("runtime_error_code") 12 | public class ErrorCodeDo extends ErrorCodeBo { 13 | } 14 | -------------------------------------------------------------------------------- /console/src/api/subscribeApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getSubscribeLogPageApi(data) { 4 | return request({ 5 | url: '/runtime/aio/log/subscribe/page', 6 | method: 'get', 7 | params:data 8 | }) 9 | } 10 | export function updateSubscribeStatusApi(data) { 11 | return request({ 12 | url: '/runtime/aio/log/subscribe/handled', 13 | method: 'post', 14 | data 15 | }) 16 | } 17 | 18 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/dao/SubscribeLogDo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.dao; 2 | 3 | import com.aio.runtime.subscribe.domain.SubscribeLogBo; 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | 6 | /** 7 | * @author lzm 8 | * @desc 订阅日志 9 | * @date 2025/04/07 10 | */ 11 | @TableName("runtime_subscribe_log") 12 | public class SubscribeLogDo extends SubscribeLogBo { 13 | } 14 | -------------------------------------------------------------------------------- /console/src/api/table.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getLogPageApi(data) { 4 | return request({ 5 | url: '/runtime/aio/log/mapping/record/page', 6 | method: 'get', 7 | params:data 8 | }) 9 | } 10 | 11 | export function getColumnListApi(tableId) { 12 | return request({ 13 | url: '/runtime/aio/log/mapping/record/page', 14 | method: 'get', 15 | params:{tableId:tableId} 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /console/src/icons/svg/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/service/AioLogService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.service; 2 | 3 | import com.aio.runtime.log.domain.AioLogBo; 4 | import com.aio.runtime.log.domain.QueryLogParams; 5 | import cn.aio1024.framework.basic.domain.page.KgoPage; 6 | import cn.aio1024.framework.basic.domain.page.PageResult; 7 | 8 | public interface AioLogService { 9 | PageResult getPage(QueryLogParams params, KgoPage page); 10 | } 11 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/params/UpdateSubscribeLogStatusParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.params; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotBlank; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 查询订阅日志参数 10 | * @date 2024/07/25 11 | */ 12 | @Data 13 | public class UpdateSubscribeLogStatusParams { 14 | @NotBlank(message = "日志ID不能为空") 15 | private String id; 16 | } 17 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=9985 2 | spring.freemarker.suffix=.html 3 | spring.freemarker.cache=false 4 | spring.freemarker.charset=UTF-8 5 | spring.profiles.active=dev 6 | #server.servlet.context-path=/test 7 | 8 | #logging.level.com.aio.runtime.log.service.lucene.LuceneLogServiceImpl=debug 9 | logging.level.com.guodun.aio.document.controller.TestLogController=debug 10 | zuul.routes.user.path=/security22233322/** 11 | -------------------------------------------------------------------------------- /console/src/api/documentApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function searchDocumentApi(data) { 4 | return request({ 5 | url: '/document/data/manage/table/list', 6 | method: 'get', 7 | data:data 8 | }) 9 | } 10 | 11 | export function releaseMenuRelationshipApi(documentId) { 12 | return request({ 13 | url: '/document/release/menu/relationship', 14 | method: 'put', 15 | params:{id:documentId} 16 | }) 17 | } 18 | 19 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/domain/BeanMethodInfo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc bean方法信息 8 | * @date 2024/10/09 9 | */ 10 | @Data 11 | public class BeanMethodInfo { 12 | private String className; 13 | private String beanName; 14 | private String methodName; 15 | private String methodDesc; 16 | private Class[] parameterTypes; 17 | } 18 | -------------------------------------------------------------------------------- /console/src/utils/validate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PanJiaChen on 16/11/18. 3 | */ 4 | 5 | /** 6 | * @param {string} path 7 | * @returns {Boolean} 8 | */ 9 | export function isExternal(path) { 10 | return /^(https?:|mailto:|tel:)/.test(path) 11 | } 12 | 13 | /** 14 | * @param {string} str 15 | * @returns {Boolean} 16 | */ 17 | export function validUsername(str) { 18 | const valid_map = ['admin', 'editor'] 19 | return valid_map.indexOf(str.trim()) >= 0 20 | } 21 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/user/EnableUserModel.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.user; 2 | 3 | 4 | import com.guodun.aio.document.user.config.UserModelConfig; 5 | import org.springframework.context.annotation.Import; 6 | 7 | import java.lang.annotation.*; 8 | 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Target({ElementType.TYPE}) 11 | @Documented 12 | @Import({UserModelConfig.class}) 13 | public @interface EnableUserModel { 14 | } 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | # 作者 3 | MAINTAINER zhaokejin 4 | 5 | ENV EXTERNAL_CONFIG="" 6 | ENV TZ Asia/Shanghai 7 | ENV BOOT_OPTIONS="" 8 | ENV BOOT_PROFILES = "" 9 | 10 | VOLUME /config 11 | 12 | ADD target/guodun-document-*.jar guodun-document.jar 13 | # 解决时间差 14 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime 15 | RUN echo $TZ > /etc/timezone 16 | 17 | ENTRYPOINT ["sh","-c","java -jar /guodun-document.jar ${BOOT_OPTIONS} ${BOOT_PROFILES} ${EXTERNAL_CONFIG}"] 18 | -------------------------------------------------------------------------------- /console/tests/unit/utils/param2Obj.spec.js: -------------------------------------------------------------------------------- 1 | import { param2Obj } from '@/utils/index.js' 2 | describe('Utils:param2Obj', () => { 3 | const url = 'https://github.com/PanJiaChen/vue-element-admin?name=bill&age=29&sex=1&field=dGVzdA==&key=%E6%B5%8B%E8%AF%95' 4 | 5 | it('param2Obj test', () => { 6 | expect(param2Obj(url)).toEqual({ 7 | name: 'bill', 8 | age: '29', 9 | sex: '1', 10 | field: window.btoa('test'), 11 | key: '测试' 12 | }) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/db/orm/annotations/AioTable.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.db.orm.annotations; 2 | 3 | import com.aio.runtime.db.orm.domain.enums.AioDbTypeEnum; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 9 | */ 10 | @Target({ElementType.TYPE}) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Documented 13 | public @interface AioTable { 14 | String value() ; 15 | AioDbTypeEnum type(); 16 | String remark() default ""; 17 | } 18 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/domain/exception/RuntimeSecurityUnAuthException.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.domain.exception; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 运行时安全未授权异常 8 | * @date 2024/09/02 9 | */ 10 | @Getter 11 | public class RuntimeSecurityUnAuthException extends RuntimeException{ 12 | private Integer code = 50014; 13 | public RuntimeSecurityUnAuthException(){ 14 | super("运行时接口授权失败"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/environment/domain/QueryEnvironmentParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.environment.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 查询环境条件 8 | * @date 2024/07/26 9 | */ 10 | @Data 11 | public class QueryEnvironmentParams { 12 | private String environmentGroup; 13 | private String propertyKey; 14 | private String propertyValue; 15 | private String propertyDesc; 16 | private String propertyType; 17 | } 18 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/service/IAioBeansService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans.service; 2 | 3 | import com.aio.runtime.beans.domain.AioBeanVo; 4 | import com.aio.runtime.beans.domain.QueryBeanParams; 5 | import cn.aio1024.framework.basic.domain.page.KgoPage; 6 | import cn.aio1024.framework.basic.domain.page.PageResult; 7 | 8 | public interface IAioBeansService { 9 | PageResult getPage(QueryBeanParams params, KgoPage page); 10 | void readBeans(); 11 | } 12 | -------------------------------------------------------------------------------- /console/src/icons/svg/example.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/mappings/domain/QueryMappingParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.mappings.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 接口信息实体类 8 | * @date 2024/07/27 9 | */ 10 | @Data 11 | public class QueryMappingParams { 12 | private String className; 13 | private String methodName; 14 | private String url; 15 | private String httpMethod; 16 | /** 17 | * 是否弃用 18 | */ 19 | private Boolean deprecated; 20 | } 21 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/db/orm/domain/bo/Condition.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.db.orm.domain.bo; 2 | 3 | import com.aio.runtime.db.orm.domain.enums.ConditionEnum; 4 | import lombok.Data; 5 | import lombok.experimental.Accessors; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 条件 10 | * @date 2024/08/06 11 | */ 12 | @Data 13 | @Accessors(chain = true) 14 | public class Condition { 15 | private String fieldName; 16 | private ConditionEnum condition; 17 | private Object value; 18 | } 19 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/jvm/service/AioRuntimeJvmService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.jvm.service; 2 | 3 | import com.aio.runtime.jvm.domain.AioJvmBo; 4 | import com.aio.runtime.jvm.domain.QueryJvmParams; 5 | import cn.aio1024.framework.basic.domain.page.KgoPage; 6 | import cn.aio1024.framework.basic.domain.page.PageResult; 7 | 8 | public interface AioRuntimeJvmService { 9 | PageResult getPage(QueryJvmParams params, KgoPage page); 10 | void clearStatisticsData(); 11 | } 12 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/domain/QueryBeanParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 查询bean接口 8 | * @date 2024/08/06 9 | */ 10 | @Data 11 | public class QueryBeanParams { 12 | private String beanName; 13 | private String className; 14 | private String dependencies; 15 | private String scope; 16 | private String aliases; 17 | private String interfaceName; 18 | private String superclass; 19 | } 20 | -------------------------------------------------------------------------------- /console/src/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | 9 | @mixin scrollBar { 10 | &::-webkit-scrollbar-track-piece { 11 | background: #d3dce6; 12 | } 13 | 14 | &::-webkit-scrollbar { 15 | width: 6px; 16 | } 17 | 18 | &::-webkit-scrollbar-thumb { 19 | background: #99a9bf; 20 | border-radius: 20px; 21 | } 22 | } 23 | 24 | @mixin relative { 25 | position: relative; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/security/domain/UserInfoResult.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.security.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author lizhenming 9 | * @desc: 10 | * @date 2022/12/9 23:20 11 | */ 12 | @Data 13 | public class UserInfoResult { 14 | private String introduction; 15 | private String avatar = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"; 16 | private String name; 17 | private List roles; 18 | } 19 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/db/orm/domain/enums/ConditionEnum.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.db.orm.domain.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public enum ConditionEnum { 9 | EQ("eq","等于"), 10 | LIKE("like","模糊查询"), 11 | BETWEEN("between","在两者之间"), 12 | LIKE_LEFT("likeLeft","模糊查询"), 13 | GT("gt","大于"), 14 | LT("lt","小于"), 15 | NE("ne","不等于"); 16 | private final String condition; 17 | private final String desc; 18 | } 19 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/service/ErrorReportedService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.service; 2 | 3 | import cn.aio1024.framework.basic.domain.page.KgoPage; 4 | import cn.aio1024.framework.basic.domain.page.PageResult; 5 | import com.aio.runtime.reported.domain.params.AddErrorParams; 6 | import com.aio.runtime.reported.domain.params.QueryErrorParams; 7 | 8 | public interface ErrorReportedService { 9 | void addError(AddErrorParams params); 10 | PageResult getPage(QueryErrorParams params, KgoPage page); 11 | } 12 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/environment/service/IAioEnvironmentService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.environment.service; 2 | 3 | import com.aio.runtime.environment.domain.EnvironmentItemBo; 4 | import com.aio.runtime.environment.domain.QueryEnvironmentParams; 5 | import cn.aio1024.framework.basic.domain.page.KgoPage; 6 | import cn.aio1024.framework.basic.domain.page.PageResult; 7 | 8 | public interface IAioEnvironmentService { 9 | PageResult getPage(QueryEnvironmentParams params, KgoPage page); 10 | void readEnvironments(); 11 | } 12 | -------------------------------------------------------------------------------- /console/src/api/user.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function login(data) { 4 | return request({ 5 | url: '/runtime/aio/security/person/login', 6 | method: 'post', 7 | data 8 | }) 9 | } 10 | 11 | export function getInfo(token) { 12 | return request({ 13 | //url: '/kgo/user', 14 | url: '/runtime/aio/security/user/login/info', 15 | method: 'get', 16 | params: { token } 17 | }) 18 | } 19 | 20 | export function logout() { 21 | return request({ 22 | url: '/runtime/aio/security/logout', 23 | method: 'post' 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/domain/RunMethodParameter.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * @author lzm 10 | * @desc Bean方法参数 11 | * @date 2024/08/20 12 | */ 13 | @Data 14 | public class RunMethodParameter extends BeanMethodInfo{ 15 | 16 | private Map parameters = new HashMap<>(); 17 | public void addParameter(String key,BeanMethodParameter parameter){ 18 | parameters.put(key,parameter); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/security/domain/RuntimeSecurityProperties.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.security.domain; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * @author lzm 8 | * @desc 运行时安全配置属性 9 | * @date 2024/08/10 10 | */ 11 | @Data 12 | @ConfigurationProperties(prefix = "aio.runtime.security") 13 | public class RuntimeSecurityProperties { 14 | private String username = "admin"; 15 | private String password = "admin@1024"; 16 | private Boolean enable = false; 17 | } 18 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/environment/domain/EnvironmentItemBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.environment.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 环境信息 8 | * @date 2024/07/26 9 | */ 10 | @Data 11 | public class EnvironmentItemBo { 12 | private String id; 13 | private String environmentGroup; 14 | private String propertyKey; 15 | private String propertyValue; 16 | private Boolean isEfficient; 17 | private String efficientValue; 18 | private String propertyDesc; 19 | private String propertyType; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /console/src/icons/svg/table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/jvm.buffer.total.capacity.md: -------------------------------------------------------------------------------- 1 | `jvm.buffer.total.capacity` 是一个 JVM 指标,用于表示 Java 应用中所有直接和堆缓冲区的总容量。它提供了关于 JVM 缓冲区(例如 NIO 缓冲区)当前最大可用容量的信息。 2 | 3 | ### 详细解释 4 | 5 | - **定义**:表示 JVM 中所有缓冲区的总分配容量,包括直接缓冲区和堆缓冲区。 6 | - **单位**:通常以字节为单位表示。 7 | 8 | ### 使用场景 9 | 10 | 1. **性能监控**:可以帮助你了解应用在输入/输出(I/O)操作时的缓存使用情况,尤其是在处理大量数据或高并发的环境中。 11 | 2. **资源管理**:通过监控这个指标,开发者能够注意到是否需要增加内存资源,或者优化内存使用,以防止内存溢出和性能下降。 12 | 13 | ### 结合其他指标 14 | 15 | - **`jvm.buffer.count`**:表示当前存在的缓冲区数量。 16 | - **`jvm.buffer.used`**:表示当前已使用的缓冲区字节数。 17 | 18 | 通过结合这些指标,你可以全面了解应用的缓冲区使用情况,从而进行更有效的资源管理。📈✨ 19 | 20 | 如果你有其他问题,或者想进一步探讨这个指标的实际应用,记得告诉我哦! 21 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/domain/RecordInfoVo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.text.DecimalFormat; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 记录的详细信息 10 | * @date 2024/06/06 11 | */ 12 | @Data 13 | public class RecordInfoVo { 14 | private String size; 15 | public void setSize(long sizeNum){ 16 | DecimalFormat df = new DecimalFormat("#.000"); 17 | String formattedNumber = df.format((double)sizeNum/1024); 18 | this.size = String.format("%s MB",formattedNumber); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/params/AddErrorCodeParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.params; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 查询订阅日志参数 8 | * @date 2024/07/25 9 | */ 10 | @Data 11 | public class AddErrorCodeParams { 12 | /** 13 | * 错误码 14 | */ 15 | private String id; 16 | /** 17 | * 错误码内容 18 | */ 19 | private String content; 20 | /** 21 | * 所属模块 22 | */ 23 | private String module; 24 | /** 25 | * 解决方案 26 | */ 27 | private String solution; 28 | } 29 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/jvm/AioJvmConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.jvm; 2 | 3 | import org.springframework.boot.actuate.metrics.MetricsEndpoint; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * @author lzm 10 | * @desc jvm配置 11 | * @date 2024/08/16 12 | */ 13 | @Configuration 14 | @ComponentScan({"com.aio.runtime.jvm"}) 15 | @ConditionalOnClass(MetricsEndpoint.class) 16 | public class AioJvmConfig { 17 | } 18 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/params/QueryErrorCodeParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.params; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 查询订阅日志参数 8 | * @date 2024/07/25 9 | */ 10 | @Data 11 | public class QueryErrorCodeParams { 12 | /** 13 | * 错误码 14 | */ 15 | private String id; 16 | /** 17 | * 错误码内容 18 | */ 19 | private String content; 20 | /** 21 | * 所属模块 22 | */ 23 | private String module; 24 | /** 25 | * 解决方案 26 | */ 27 | private String solution; 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | runtime-record-core/src/main/resources/templates/runtime/console/ 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | 17 | ### IntelliJ IDEA ### 18 | .idea 19 | *.iws 20 | *.iml 21 | *.ipr 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | !**/src/main/**/build/ 31 | !**/src/test/**/build/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /console/mock/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} url 3 | * @returns {Object} 4 | */ 5 | function param2Obj(url) { 6 | const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') 7 | if (!search) { 8 | return {} 9 | } 10 | const obj = {} 11 | const searchArr = search.split('&') 12 | searchArr.forEach(v => { 13 | const index = v.indexOf('=') 14 | if (index !== -1) { 15 | const name = v.substring(0, index) 16 | const val = v.substring(index + 1, v.length) 17 | obj[name] = val 18 | } 19 | }) 20 | return obj 21 | } 22 | 23 | module.exports = { 24 | param2Obj 25 | } 26 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/domain/event/MappingVisitEvent.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.domain.event; 2 | 3 | import com.aio.runtime.mappings.domain.AioMappingBo; 4 | import lombok.Getter; 5 | import org.springframework.context.ApplicationEvent; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 接口访问事件 10 | * @date 2024/07/29 11 | */ 12 | @Getter 13 | public class MappingVisitEvent extends ApplicationEvent { 14 | private AioMappingBo mappingBo; 15 | public MappingVisitEvent(Object source,AioMappingBo mappingBo) { 16 | super(source); 17 | this.mappingBo = mappingBo; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/domain/ErrorReportedProperties.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.domain; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * @author lzm 8 | * @desc 错误上报配置 9 | * @since 1.0.0 10 | * @date 2024/08/10 11 | */ 12 | @Data 13 | @ConfigurationProperties(prefix = ErrorReportedProperties.PREFIX) 14 | public class ErrorReportedProperties { 15 | public static final String PREFIX = "aio.runtime.error.reported"; 16 | private Boolean enable = true; 17 | private String scheme; 18 | } 19 | -------------------------------------------------------------------------------- /console/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app 4 | '@vue/cli-plugin-babel/preset' 5 | ], 6 | 'env': { 7 | 'development': { 8 | // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). 9 | // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. 10 | // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html 11 | 'plugins': ['dynamic-import-node'] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/domain/AioBeanVo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author lzm 9 | * @desc Bean视图对象 10 | * @date 2024/08/06 11 | */ 12 | @Data 13 | public class AioBeanVo { 14 | private String id; 15 | private String beanName; 16 | private String className; 17 | private List dependencies; 18 | private String scope; 19 | private List aliases; 20 | private List interfaces; 21 | private String superclass; 22 | private String resource; 23 | } 24 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | [ %d{HH:mm:ss.SSS} ] %cyan([%thread]) %yellow(%-5level)| %logger{120} :: %method | - %blue(%msg) %n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /console/src/icons/svg/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/db/orm/utils/CamelToSnakeUtils.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.db.orm.utils; 2 | 3 | /** 4 | * @author lzm 5 | * @desc 驼峰转桥接工具类 6 | * @date 2024/08/06 7 | */ 8 | public class CamelToSnakeUtils { 9 | public static String convertCamelToSnake(String camelCase) { 10 | if (camelCase == null || camelCase.isEmpty()) { 11 | return camelCase; // 处理空字符串或 null 12 | } 13 | // 使用正则表达式替换大写字母,并在前面添加下划线 14 | String result = camelCase.replaceAll("([a-z])([A-Z])", "$1_$2"); 15 | return result.toLowerCase(); // 转换为小写 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/AioRuntimeBeansConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans; 2 | 3 | import org.springframework.boot.actuate.beans.BeansEndpoint; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * @author lzm 10 | * @desc 订阅配置 11 | * @date 2024/07/28 12 | */ 13 | @Configuration 14 | @ConditionalOnClass(BeansEndpoint.class) 15 | @ComponentScan({"com.aio.runtime.beans"}) 16 | public class AioRuntimeBeansConfig { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /console/src/components/code/CodePreview.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 30 | 31 | 34 | 35 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/domain/AioLogAppendProperties.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.domain; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * @author lzm 8 | * @desc 日志属性配置 9 | * @date 2024/08/10 10 | */ 11 | @Data 12 | @ConfigurationProperties(prefix = "aio.runtime.log") 13 | public class AioLogAppendProperties { 14 | private Boolean enable = true; 15 | /** 16 | * 日志保存时间 单位天 17 | */ 18 | private Integer pastDay = 90; 19 | /** 20 | * 索引周期 默认小时 hour , 可选 day 21 | */ 22 | private String indexPeriod = "hour"; 23 | } 24 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/params/QuerySubscribeLogParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.params; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 查询订阅日志参数 8 | * @date 2024/07/25 9 | */ 10 | @Data 11 | public class QuerySubscribeLogParams { 12 | private String id; 13 | private String message; 14 | private String subscribeName; 15 | private String className; 16 | private String methodName; 17 | private String userId; 18 | private String companyId; 19 | private Integer handleStatus; 20 | private Long createFromTime; 21 | private Long createToTime; 22 | } 23 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/domain/vo/ErrorReportVo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.domain.vo; 2 | 3 | import com.aio.runtime.reported.domain.params.AddErrorParams; 4 | import com.fasterxml.jackson.annotation.JsonFormat; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | import java.util.Date; 9 | 10 | /** 11 | * @author lzm 12 | * @desc 错误上报视图层 13 | * @date 2024/10/26 14 | */ 15 | @EqualsAndHashCode(callSuper = true) 16 | @Data 17 | public class ErrorReportVo extends AddErrorParams { 18 | private String id; 19 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 20 | private Date createTime; 21 | } 22 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/AioSubscribeConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe; 2 | 3 | import com.aio.runtime.subscribe.domain.properties.AioSubscribeProperties; 4 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * @author lzm 10 | * @desc 订阅配置 11 | * @date 2024/07/28 12 | */ 13 | @Configuration 14 | @ComponentScan({"com.aio.runtime.subscribe"}) 15 | @EnableConfigurationProperties(AioSubscribeProperties.class) 16 | public class AioSubscribeConfig { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /console/mock/table.js: -------------------------------------------------------------------------------- 1 | const Mock = require('mockjs') 2 | 3 | const data = Mock.mock({ 4 | 'items|30': [{ 5 | id: '@id', 6 | title: '@sentence(10, 20)', 7 | 'status|1': ['published', 'draft', 'deleted'], 8 | author: 'name', 9 | display_time: '@datetime', 10 | pageviews: '@integer(300, 5000)' 11 | }] 12 | }) 13 | 14 | module.exports = [ 15 | { 16 | url: '/vue-admin-template/table/list', 17 | type: 'get', 18 | response: config => { 19 | const items = data.items 20 | return { 21 | code: 20000, 22 | data: { 23 | total: items.length, 24 | items: items 25 | } 26 | } 27 | } 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/cache/AioCacheManageConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.cache; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.actuate.cache.CachesEndpoint; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 6 | import org.springframework.context.annotation.ComponentScan; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * @author lzm 11 | * @desc 缓存统一配置 12 | * @date 2024/08/10 13 | */ 14 | @Configuration 15 | @ConditionalOnClass(CachesEndpoint.class) 16 | @Slf4j 17 | @ComponentScan({"com.aio.runtime.cache"}) 18 | public class AioCacheManageConfig { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/mappings/service/IAioMappingService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.mappings.service; 2 | 3 | import com.aio.runtime.mappings.domain.AioMappingBo; 4 | import com.aio.runtime.mappings.domain.AioMappingVo; 5 | import com.aio.runtime.mappings.domain.QueryMappingParams; 6 | import cn.aio1024.framework.basic.domain.page.KgoPage; 7 | import cn.aio1024.framework.basic.domain.page.PageResult; 8 | 9 | public interface IAioMappingService { 10 | PageResult getPage(QueryMappingParams params, KgoPage page); 11 | AioMappingBo getMapping(String className,String methodName); 12 | boolean updateMappingById(AioMappingBo mappingBo); 13 | } 14 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/mappings/domain/AioMappingBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.mappings.domain; 2 | 3 | import lombok.Data; 4 | import lombok.experimental.Accessors; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author lzm 10 | * @desc 接口信息实体类 11 | * @date 2024/07/27 12 | */ 13 | @Data 14 | @Accessors(chain = true) 15 | public class AioMappingBo { 16 | private String id; 17 | private String className; 18 | private String methodName; 19 | private String url; 20 | private String httpMethod; 21 | /** 22 | * 是否弃用 23 | */ 24 | private Boolean deprecated; 25 | private Date activeTime; 26 | private Long visitCounter; 27 | } 28 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/service/SubscribeLogService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.service; 2 | 3 | import com.aio.runtime.subscribe.domain.SubscribeLogVo; 4 | import com.aio.runtime.subscribe.domain.params.QuerySubscribeLogParams; 5 | import com.aio.runtime.subscribe.domain.params.UpdateSubscribeLogStatusParams; 6 | import cn.aio1024.framework.basic.domain.page.KgoPage; 7 | import cn.aio1024.framework.basic.domain.page.PageResult; 8 | 9 | public interface SubscribeLogService { 10 | PageResult getPage(QuerySubscribeLogParams params , KgoPage page); 11 | void updateSubscribeLogStatusToHandled(UpdateSubscribeLogStatusParams params); 12 | } 13 | -------------------------------------------------------------------------------- /docs/JVM内存说明.md: -------------------------------------------------------------------------------- 1 | `jvm.memory.used` 和 `jvm.memory.committed` 是两个不同的 JVM 内存指标,表示不同的内存状态。以下是它们的主要区别: 2 | 3 | ### 1. `jvm.memory.used` 4 | - **定义**:表示 JVM 当前已使用的内存量,即正在被应用程序使用的实际内存。 5 | - **作用**:提供关于应用程序当前内存消耗情况的信息,可以用来监控内存泄漏和优化性能。 6 | - **单位**:通常以字节为单位显示。 7 | 8 | ### 2. `jvm.memory.committed` 9 | - **定义**:表示 JVM 已经分配的内存量,即为 JVM 保留的内存,而不一定是正在使用的内存。 10 | - **作用**:显示了 JVM 预留的内存空间,用于内存管理和垃圾回收等操作。 11 | - **单位**:通常以字节为单位显示。 12 | 13 | ### 总结 14 | 15 | - **使用**: `jvm.memory.used` 反映应用程序真实的内存使用情况,而 `jvm.memory.committed` 显示 JVM 为应用程序保留的内存量。 16 | - **对比**: 如果 `jvm.memory.used` 的值接近 `jvm.memory.committed`,意味着内存使用得比较紧张。如果 `committed` 大于 `used`,则表示有可用的内存空间。 17 | 18 | 这两个指标结合在一起,可以帮助你更好地监控和优化 Java 应用程序的内存使用。💡📊 如果还有其他问题,随时告诉我! 19 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/domain/AioLogBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 日志对象 10 | * @date 2024/08/08 11 | */ 12 | @Data 13 | public class AioLogBo { 14 | private String className; 15 | private String methodName; 16 | private String threadName; 17 | private String level; 18 | private String id; 19 | /** 20 | * 错误码 21 | */ 22 | private String traceId; 23 | /** 24 | * 错误信息 25 | */ 26 | private String message; 27 | private Long createTime; 28 | private String marker; 29 | private Map mdc; 30 | } 31 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/service/MappingLogService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.service; 2 | 3 | import com.aio.runtime.record.log.domain.MappingRecordBo; 4 | import com.aio.runtime.record.log.domain.QueryRecordParams; 5 | import cn.aio1024.framework.basic.domain.page.KgoPage; 6 | import cn.aio1024.framework.basic.domain.page.PageResult; 7 | 8 | import java.util.List; 9 | 10 | public interface MappingLogService { 11 | void temporaryStorage(MappingRecordBo mappingRecord); 12 | List drainTo(); 13 | void batchSave(List recordList); 14 | PageResult searchRecords(QueryRecordParams params, KgoPage page); 15 | Object getRecordInfo(); 16 | } 17 | -------------------------------------------------------------------------------- /console/src/store/modules/settings.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from '@/settings' 2 | 3 | const { showSettings, fixedHeader, sidebarLogo } = defaultSettings 4 | 5 | const state = { 6 | showSettings: showSettings, 7 | fixedHeader: fixedHeader, 8 | sidebarLogo: sidebarLogo 9 | } 10 | 11 | const mutations = { 12 | CHANGE_SETTING: (state, { key, value }) => { 13 | // eslint-disable-next-line no-prototype-builtins 14 | if (state.hasOwnProperty(key)) { 15 | state[key] = value 16 | } 17 | } 18 | } 19 | 20 | const actions = { 21 | changeSetting({ commit }, data) { 22 | commit('CHANGE_SETTING', data) 23 | } 24 | } 25 | 26 | export default { 27 | namespaced: true, 28 | state, 29 | mutations, 30 | actions 31 | } 32 | 33 | -------------------------------------------------------------------------------- /console/src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | // sidebar 2 | $menuText:#bfcbd9; 3 | $menuActiveText:#409EFF; 4 | $subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951 5 | 6 | $menuBg:#304156; 7 | $menuHover:#263445; 8 | 9 | $subMenuBg:#1f2d3d; 10 | $subMenuHover:#001528; 11 | 12 | $sideBarWidth: 210px; 13 | 14 | // the :export directive is the magic sauce for webpack 15 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 16 | :export { 17 | menuText: $menuText; 18 | menuActiveText: $menuActiveText; 19 | subMenuActiveText: $subMenuActiveText; 20 | menuBg: $menuBg; 21 | menuHover: $menuHover; 22 | subMenuBg: $subMenuBg; 23 | subMenuHover: $subMenuHover; 24 | sideBarWidth: $sideBarWidth; 25 | } 26 | -------------------------------------------------------------------------------- /console/tests/unit/components/SvgIcon.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import SvgIcon from '@/components/SvgIcon/index.vue' 3 | describe('SvgIcon.vue', () => { 4 | it('iconClass', () => { 5 | const wrapper = shallowMount(SvgIcon, { 6 | propsData: { 7 | iconClass: 'test' 8 | } 9 | }) 10 | expect(wrapper.find('use').attributes().href).toBe('#icon-test') 11 | }) 12 | it('className', () => { 13 | const wrapper = shallowMount(SvgIcon, { 14 | propsData: { 15 | iconClass: 'test' 16 | } 17 | }) 18 | expect(wrapper.classes().length).toBe(1) 19 | wrapper.setProps({ className: 'test' }) 20 | expect(wrapper.classes().includes('test')).toBe(true) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /console/src/api/cacheApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getAllCacheApi() { 4 | return request({ 5 | url: '/runtime/aio/cache/all', 6 | method: 'get', 7 | }) 8 | } 9 | 10 | export function getCacheContentApi(data) { 11 | return request({ 12 | url: '/runtime/aio/cache/content', 13 | method: 'get', 14 | params: data 15 | }) 16 | } 17 | 18 | export function deleteCacheContentApi(data) { 19 | return request({ 20 | url: '/runtime/aio/cache/content', 21 | method: 'delete', 22 | params: data 23 | }) 24 | } 25 | export function clearCacheContentApi(data) { 26 | return request({ 27 | url: '/runtime/aio/cache/clear', 28 | method: 'delete', 29 | params: data 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /console/tests/unit/components/Hamburger.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import Hamburger from '@/components/Hamburger/index.vue' 3 | describe('Hamburger.vue', () => { 4 | it('toggle click', () => { 5 | const wrapper = shallowMount(Hamburger) 6 | const mockFn = jest.fn() 7 | wrapper.vm.$on('toggleClick', mockFn) 8 | wrapper.find('.hamburger').trigger('click') 9 | expect(mockFn).toBeCalled() 10 | }) 11 | it('prop isActive', () => { 12 | const wrapper = shallowMount(Hamburger) 13 | wrapper.setProps({ isActive: true }) 14 | expect(wrapper.contains('.is-active')).toBe(true) 15 | wrapper.setProps({ isActive: false }) 16 | expect(wrapper.contains('.is-active')).toBe(false) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/mappings/domain/AioMappingVo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.mappings.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import lombok.Data; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author lzm 10 | * @desc 接口信息实体类 11 | * @date 2024/07/27 12 | */ 13 | @Data 14 | public class AioMappingVo { 15 | private String id; 16 | private String className; 17 | private String methodName; 18 | private String url; 19 | private String httpMethod; 20 | /** 21 | * 是否弃用 22 | */ 23 | private Boolean deprecated; 24 | 25 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 26 | private Date activeTime; 27 | private Long visitCounter; 28 | } 29 | -------------------------------------------------------------------------------- /console/src/api/beanApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getBeanPageApi(data) { 4 | return request({ 5 | url: '/runtime/aio/bean/page', 6 | method: 'get', 7 | params:data 8 | }) 9 | } 10 | export function getMethodListApi(data) { 11 | return request({ 12 | url: '/runtime/aio/bean/method/list', 13 | method: 'get', 14 | params:data 15 | }) 16 | } 17 | 18 | export function getMethodParametersApi(data) { 19 | return request({ 20 | url: '/runtime/aio/bean/method/parameters', 21 | method: 'post', 22 | data 23 | }) 24 | } 25 | 26 | export function runMethodApi(data) { 27 | return request({ 28 | url: '/runtime/aio/bean/method/run', 29 | method: 'post', 30 | data 31 | }) 32 | } 33 | 34 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/bo/ErrorCodeBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.bo; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 错误码维护 10 | * @date 2025/04/08 11 | */ 12 | @Data 13 | public class ErrorCodeBo { 14 | /** 15 | * 错误码 16 | */ 17 | private String id; 18 | /** 19 | * 错误码内容 20 | */ 21 | private String content; 22 | /** 23 | * 所属模块 24 | */ 25 | private String module; 26 | /** 27 | * 解决方案 28 | */ 29 | private String solution; 30 | /** 31 | * 创建时间 32 | */ 33 | private Date createTime; 34 | /** 35 | * 更新时间 36 | */ 37 | private Date updateTime; 38 | } 39 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/service/ErrorCodeService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.service; 2 | 3 | import cn.aio1024.framework.basic.domain.page.KgoPage; 4 | import cn.aio1024.framework.basic.domain.page.PageResult; 5 | import com.aio.runtime.subscribe.domain.bo.ErrorCodeBo; 6 | import com.aio.runtime.subscribe.domain.params.AddErrorCodeParams; 7 | import com.aio.runtime.subscribe.domain.params.QueryErrorCodeParams; 8 | 9 | /** 10 | * 错误码 11 | */ 12 | public interface ErrorCodeService { 13 | PageResult getPage(QueryErrorCodeParams params , KgoPage page); 14 | 15 | void addErrorCode(AddErrorCodeParams params); 16 | void updateErrorCode(ErrorCodeBo params); 17 | 18 | void deleteErrorCode(String id); 19 | } 20 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/domain/dao/ErrorReportDo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.domain.dao; 2 | 3 | import com.aio.runtime.reported.domain.params.AddErrorParams; 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | import com.fasterxml.jackson.annotation.JsonFormat; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | 9 | import java.util.Date; 10 | 11 | /** 12 | * @author lzm 13 | * @desc 错误上报数据库对象 14 | * @date 2024/10/26 15 | */ 16 | @EqualsAndHashCode(callSuper = true) 17 | @Data 18 | @TableName("error_feedback_record") 19 | public class ErrorReportDo extends AddErrorParams { 20 | private String id; 21 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 22 | private Date createTime; 23 | } 24 | -------------------------------------------------------------------------------- /console/src/layout/components/Sidebar/FixiOSBug.js: -------------------------------------------------------------------------------- 1 | export default { 2 | computed: { 3 | device() { 4 | return this.$store.state.app.device 5 | } 6 | }, 7 | mounted() { 8 | // In order to fix the click on menu on the ios device will trigger the mouseleave bug 9 | // https://github.com/PanJiaChen/vue-element-admin/issues/1135 10 | this.fixBugIniOS() 11 | }, 12 | methods: { 13 | fixBugIniOS() { 14 | const $subMenu = this.$refs.subMenu 15 | if ($subMenu) { 16 | const handleMouseleave = $subMenu.handleMouseleave 17 | $subMenu.handleMouseleave = (e) => { 18 | if (this.device === 'mobile') { 19 | return 20 | } 21 | handleMouseleave(e) 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /console/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <%= webpackConfig.name %> 10 | 11 | 12 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /console/tests/unit/utils/validate.spec.js: -------------------------------------------------------------------------------- 1 | import { validUsername, isExternal } from '@/utils/validate.js' 2 | 3 | describe('Utils:validate', () => { 4 | it('validUsername', () => { 5 | expect(validUsername('admin')).toBe(true) 6 | expect(validUsername('editor')).toBe(true) 7 | expect(validUsername('xxxx')).toBe(false) 8 | }) 9 | it('isExternal', () => { 10 | expect(isExternal('https://github.com/PanJiaChen/vue-element-admin')).toBe(true) 11 | expect(isExternal('http://github.com/PanJiaChen/vue-element-admin')).toBe(true) 12 | expect(isExternal('github.com/PanJiaChen/vue-element-admin')).toBe(false) 13 | expect(isExternal('/dashboard')).toBe(false) 14 | expect(isExternal('./dashboard')).toBe(false) 15 | expect(isExternal('dashboard')).toBe(false) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/domain/QueryLogParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * @author lzm 10 | * @desc 查询日志参数 11 | * @date 2024/08/08 12 | */ 13 | @Data 14 | public class QueryLogParams { 15 | private String className; 16 | private String methodName; 17 | private String threadName; 18 | private String level; 19 | /** 20 | * 错误码 21 | */ 22 | private String traceId; 23 | /** 24 | * 错误信息 25 | */ 26 | private String message; 27 | private Long createToTime; 28 | private Long createFromTime; 29 | private List keywords; 30 | private String marker; 31 | private Map mdc; 32 | } 33 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/properties/AioSubscribeProperties.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.properties; 2 | 3 | import lombok.Data; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author lzm 12 | * @desc 日志订阅配置 13 | * @date 2024/10/08 14 | */ 15 | @Data 16 | @Slf4j 17 | @ConfigurationProperties(prefix = AioSubscribeProperties.PREFIX) 18 | public class AioSubscribeProperties { 19 | public static final String PREFIX = "aio.runtime.log.subscribe"; 20 | private SubscribeFeiShuProperties feishu; 21 | private String detailAddress; 22 | private List markers = new ArrayList<>(); 23 | } 24 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/AioRuntimeApplicationStartedEventListener.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log; 2 | 3 | import com.aio.runtime.common.info.SystemRuntimeInfo; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.boot.context.event.ApplicationStartedEvent; 6 | import org.springframework.context.ApplicationListener; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author lzm 11 | * @desc 系统启动事件 12 | * @date 2024/08/13 13 | */ 14 | @Component 15 | @Slf4j 16 | public class AioRuntimeApplicationStartedEventListener implements ApplicationListener { 17 | 18 | @Override 19 | public void onApplicationEvent(ApplicationStartedEvent event) { 20 | SystemRuntimeInfo.systemStarted(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /console/src/icons/svg/nested.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/AioLogAppendConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log; 2 | 3 | import com.aio.runtime.log.domain.AioLogAppendProperties; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 5 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 6 | import org.springframework.context.annotation.ComponentScan; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * @author lzm 11 | * @desc 订阅配置 12 | * @date 2024/07/28 13 | */ 14 | @Configuration 15 | @ConditionalOnProperty(prefix = "aio.runtime.log",name = "enable",havingValue = "true",matchIfMissing = true) 16 | @ComponentScan({"com.aio.runtime.log"}) 17 | @EnableConfigurationProperties(AioLogAppendProperties.class) 18 | public class AioLogAppendConfig { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /console/src/layout/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 | 32 | 33 | 41 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/resources/notify/feishu/subscribeLog.json: -------------------------------------------------------------------------------- 1 | { 2 | "post": { 3 | "zh_cn": { 4 | "title": "订阅日志", 5 | "content": [ 6 | [ 7 | { 8 | "tag": "text", 9 | "text": "" 10 | } 11 | ], 12 | [ 13 | { 14 | "tag": "text", 15 | "text": "" 16 | } 17 | ], 18 | [ 19 | { 20 | "tag": "text", 21 | "text": "" 22 | } 23 | ], 24 | [ 25 | { 26 | "tag": "text", 27 | "text": "" 28 | } 29 | ] 30 | ,[ 31 | { 32 | "tag": "a", 33 | "text": "详情", 34 | "href": "http://www.example.com/" 35 | } 36 | ] 37 | ] 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/domain/AioLogParamsBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.domain; 2 | 3 | import com.aio.runtime.db.orm.annotations.AioField; 4 | import com.aio.runtime.db.orm.annotations.AioId; 5 | import com.aio.runtime.db.orm.annotations.AioTable; 6 | import com.aio.runtime.db.orm.domain.enums.AioDbTypeEnum; 7 | import lombok.Data; 8 | 9 | import java.util.Date; 10 | 11 | /** 12 | * @author lzm 13 | * @desc 日志参数 14 | * @date 2024/08/09 15 | */ 16 | @Data 17 | @AioTable(value = "aio_log_scheme",type = AioDbTypeEnum.SQL_LITE) 18 | public class AioLogParamsBo { 19 | @AioId() 20 | private String id; 21 | @AioField("scheme_name") 22 | private String schemeName; 23 | @AioField("scheme_content") 24 | private String schemeContent; 25 | @AioField("update_time") 26 | private Date updateTime; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/user/config/ServletWebInterceptorConfig.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.user.config; 2 | 3 | import com.aio.runtime.common.interceptor.TraceIdInterceptor; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | /** 10 | * @author lzm 11 | * @desc 服务器Web集成配置 12 | * @date 2024/02/02 13 | */ 14 | @Slf4j 15 | @Configuration 16 | public class ServletWebInterceptorConfig implements WebMvcConfigurer { 17 | 18 | @Override 19 | public void addInterceptors(InterceptorRegistry registry) { 20 | registry.addInterceptor(new TraceIdInterceptor()).addPathPatterns("/**"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /console/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], 3 | transform: { 4 | '^.+\\.vue$': 'vue-jest', 5 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 6 | 'jest-transform-stub', 7 | '^.+\\.jsx?$': 'babel-jest' 8 | }, 9 | moduleNameMapper: { 10 | '^@/(.*)$': '/src/$1' 11 | }, 12 | snapshotSerializers: ['jest-serializer-vue'], 13 | testMatch: [ 14 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 15 | ], 16 | collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], 17 | coverageDirectory: '/tests/unit/coverage', 18 | // 'collectCoverage': true, 19 | 'coverageReporters': [ 20 | 'lcov', 21 | 'text-summary' 22 | ], 23 | testURL: 'http://localhost/' 24 | } 25 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/AioSubscribeMapperConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe; 2 | 3 | import com.aio.runtime.subscribe.domain.properties.AioSubscribeProperties; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.mybatis.spring.annotation.MapperScan; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * @author lzm 11 | * @desc 订阅配置 12 | * @date 2024/07/28 13 | */ 14 | @Slf4j 15 | @Configuration 16 | @MapperScan({"com.aio.runtime.subscribe.mapper"}) 17 | @ConditionalOnProperty(prefix = AioSubscribeProperties.PREFIX,name = "scheme",havingValue = "mysql",matchIfMissing = true) 18 | public class AioSubscribeMapperConfig { 19 | public AioSubscribeMapperConfig() { 20 | log.info("日志订阅启动mysql数据治理方案"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/enums/SubscibeHandleStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain.enums; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * 订阅记录处理状态 8 | */ 9 | @Getter 10 | @AllArgsConstructor 11 | public enum SubscibeHandleStatusEnum { 12 | HANDLED(1,"已处理"), 13 | UN_HANDLED(0,"未处理"); 14 | private final Integer status; 15 | private final String desc; 16 | 17 | public boolean eq(Integer statusInt){ 18 | return this.status.equals(statusInt); 19 | } 20 | public static String getDesc(Integer status){ 21 | for (SubscibeHandleStatusEnum statusEnum : SubscibeHandleStatusEnum.values()) { 22 | if (statusEnum.eq(status)){ 23 | return statusEnum.getDesc(); 24 | } 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /console/src/layout/components/Sidebar/Link.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 44 | -------------------------------------------------------------------------------- /console/src/utils/highlight.js: -------------------------------------------------------------------------------- 1 | import Hljs from 'highlight.js'; 2 | import 'highlight.js/styles/atom-one-dark.css'; 3 | 4 | let Highlight = {}; 5 | Highlight.install = function (Vue, options) { 6 | // 先有数据再绑定,调用highlightA 7 | Vue.directive('highlightA', { 8 | inserted: function(el) { 9 | let blocks = el.querySelectorAll('pre code'); 10 | for (let i = 0; i < blocks.length; i++) { 11 | const item = blocks[i]; 12 | Hljs.highlightBlock(item); 13 | }; 14 | } 15 | }); 16 | 17 | // 先绑定,后面会有数据更新,调用highlightB 18 | Vue.directive('highlightB', { 19 | componentUpdated: function(el) { 20 | let blocks = el.querySelectorAll('pre code'); 21 | for (let i = 0; i < blocks.length; i++) { 22 | const item = blocks[i]; 23 | Hljs.highlightBlock(item); 24 | }; 25 | } 26 | }); 27 | 28 | }; 29 | 30 | export default Highlight; 31 | -------------------------------------------------------------------------------- /console/src/layout/components/Sidebar/Item.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 42 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/domain/AioLogVo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import lombok.Data; 5 | 6 | import java.util.Date; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author lzm 11 | * @desc 日志对象 12 | * @date 2024/08/08 13 | */ 14 | @Data 15 | public class AioLogVo { 16 | private String className; 17 | private String methodName; 18 | private String threadName; 19 | private String level; 20 | private String id; 21 | /** 22 | * 错误码 23 | */ 24 | private String traceId; 25 | /** 26 | * 错误信息 27 | */ 28 | private String message; 29 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 30 | private Date createTime; 31 | private Long createTimestamp; 32 | private String marker; 33 | private Map mdc; 34 | } 35 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/config/properties/AioMappingLogProperties.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.config.properties; 2 | 3 | import lombok.Data; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author lzm 12 | * @desc 日志属性配置 13 | * @date 2024/08/10 14 | */ 15 | @Data 16 | @ConfigurationProperties(prefix = "aio.runtime.mapping.log") 17 | public class AioMappingLogProperties { 18 | private Boolean enable = true; 19 | /** 20 | * 请求地址黑名单 21 | */ 22 | private List blackList = new ArrayList<>(); 23 | 24 | public void addBlackUrl(String url){ 25 | if (StringUtils.isBlank(url)){ 26 | return; 27 | } 28 | blackList.add(url); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /console/src/api/errorCodeApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getErrorCodePageApi(data) { 4 | return request({ 5 | url: '/runtime/aio/error/code/page', 6 | method: 'get', 7 | params:data 8 | }) 9 | } 10 | 11 | export function addErrorCodeApi(data) { 12 | return request({ 13 | url: '/runtime/aio/error/code', 14 | method: 'post', 15 | data 16 | }) 17 | } 18 | 19 | export function updateErrorCodeApi(data) { 20 | return request({ 21 | url: '/runtime/aio/error/code', 22 | method: 'put', 23 | data 24 | }) 25 | } 26 | export function deleteErrorCodeApi(data) { 27 | return request({ 28 | url: '/runtime/aio/error/code', 29 | method: 'delete', 30 | data 31 | }) 32 | } 33 | export function exportErrorCodeApi(params) { 34 | return request({ 35 | url: '/runtime/aio/error/code/export', 36 | method: 'get', 37 | params 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/domain/QueryRecordParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 查询记录参数 8 | * @date 2024/05/13 9 | */ 10 | @Data 11 | public class QueryRecordParams { 12 | private Long createFromTime; 13 | private Long createToTime; 14 | private String userName; 15 | private String httpMethod; 16 | private String url; 17 | private String userId; 18 | private String companyId; 19 | private String companyName; 20 | 21 | 22 | private String mappingClass; 23 | private String mappingMethod; 24 | private String params; 25 | private String result; 26 | private String traceId; 27 | private String stackTrace; 28 | private String throwable; 29 | private String exceptionMsg; 30 | private String success; 31 | private String deprecated; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /console/src/styles/element-ui.scss: -------------------------------------------------------------------------------- 1 | // cover some element-ui styles 2 | 3 | .el-breadcrumb__inner, 4 | .el-breadcrumb__inner a { 5 | font-weight: 400 !important; 6 | } 7 | 8 | .el-upload { 9 | input[type="file"] { 10 | display: none !important; 11 | } 12 | } 13 | 14 | .el-upload__input { 15 | display: none; 16 | } 17 | 18 | 19 | // to fixed https://github.com/ElemeFE/element/issues/2461 20 | .el-dialog { 21 | transform: none; 22 | left: 0; 23 | position: relative; 24 | margin: 0 auto; 25 | } 26 | 27 | // refine element ui upload 28 | .upload-container { 29 | .el-upload { 30 | width: 100%; 31 | 32 | .el-upload-dragger { 33 | width: 100%; 34 | height: 200px; 35 | } 36 | } 37 | } 38 | 39 | // dropdown 40 | .el-dropdown-menu { 41 | a { 42 | display: block 43 | } 44 | } 45 | 46 | // to fix el-date-picker css style 47 | .el-range-separator { 48 | box-sizing: content-box; 49 | } 50 | -------------------------------------------------------------------------------- /console/src/icons/svg/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /console/src/styles/transition.scss: -------------------------------------------------------------------------------- 1 | // global transition css 2 | 3 | /* fade */ 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | /* fade-transform */ 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all .5s; 18 | } 19 | 20 | .fade-transform-enter { 21 | opacity: 0; 22 | transform: translateX(-30px); 23 | } 24 | 25 | .fade-transform-leave-to { 26 | opacity: 0; 27 | transform: translateX(30px); 28 | } 29 | 30 | /* breadcrumb transition */ 31 | .breadcrumb-enter-active, 32 | .breadcrumb-leave-active { 33 | transition: all .5s; 34 | } 35 | 36 | .breadcrumb-enter, 37 | .breadcrumb-leave-active { 38 | opacity: 0; 39 | transform: translateX(20px); 40 | } 41 | 42 | .breadcrumb-move { 43 | transition: all .5s; 44 | } 45 | 46 | .breadcrumb-leave-active { 47 | position: absolute; 48 | } 49 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/save/LogSaveCache.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.save; 2 | 3 | import cn.hutool.core.util.ObjectUtil; 4 | import com.aio.runtime.log.domain.AioLogBo; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.concurrent.BlockingQueue; 9 | import java.util.concurrent.LinkedBlockingQueue; 10 | 11 | /** 12 | * @author lzm 13 | * @desc 日志保存缓存 14 | * @date 2024/08/08 15 | */ 16 | public class LogSaveCache { 17 | public static BlockingQueue AIO_LOG_QUEUE = new LinkedBlockingQueue<>(10000); 18 | 19 | public static void addLog(AioLogBo logBo){ 20 | if (ObjectUtil.isNull(logBo)){ 21 | return; 22 | } 23 | AIO_LOG_QUEUE.add(logBo); 24 | } 25 | 26 | public static List drainTo() { 27 | List records = new ArrayList<>(); 28 | AIO_LOG_QUEUE.drainTo(records); 29 | return records; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/common/HandleRuntimeException.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.common; 2 | 3 | import cn.aio1024.framework.basic.domain.amis.AmisResult; 4 | import com.aio.runtime.domain.exception.RuntimeSecurityUnAuthException; 5 | import org.springframework.web.bind.annotation.ControllerAdvice; 6 | import org.springframework.web.bind.annotation.ExceptionHandler; 7 | import org.springframework.web.bind.annotation.ResponseBody; 8 | 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | /** 12 | * @author lzm 13 | * @desc 处理运行时异常 14 | * @date 2024/09/02 15 | */ 16 | @ControllerAdvice 17 | public class HandleRuntimeException { 18 | @ExceptionHandler(RuntimeSecurityUnAuthException.class) 19 | @ResponseBody 20 | public AmisResult handleExceptions(RuntimeSecurityUnAuthException ex, HttpServletResponse response){ 21 | // 创建 JSON 响应体 22 | return AmisResult.fail(ex.getCode(), ex.getMessage()); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/controller/TestWechatController.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestParam; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.servlet.view.RedirectView; 9 | 10 | /** 11 | * @author lzm 12 | * @desc 测试微信登录 13 | * @date 2024/09/19 14 | */ 15 | @RestController 16 | @Slf4j 17 | @RequestMapping("/test/wechat") 18 | public class TestWechatController { 19 | @RequestMapping("/login") 20 | public RedirectView login(@RequestParam String code, @RequestParam String state){ 21 | String url = StrUtil.format("http://192.168.2.21:9001/security/authorize/wechat/official/login/callback?code={}&state={}", code,state); 22 | return new RedirectView(url); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/domain/MappingRecordVo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 请求日志记录 10 | * @date 2024/05/13 11 | */ 12 | @Data 13 | public class MappingRecordVo { 14 | private String id; 15 | private String createTime; 16 | private String httpMethod; 17 | private String url; 18 | 19 | private String userId; 20 | private String userName; 21 | private String companyId; 22 | private String companyName; 23 | 24 | private String mappingClass; 25 | private String mappingMethod; 26 | private List paramsClass; 27 | private String params; 28 | private String result; 29 | private String success; 30 | private String deprecated; 31 | private String traceId; 32 | 33 | 34 | private Object stackTrace; 35 | private String throwable; 36 | private String exceptionMsg; 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/GuodunDocumentApplication.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document; 2 | 3 | 4 | import com.guodun.aio.document.user.EnableUserModel; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.cache.annotation.EnableCaching; 8 | import org.springframework.context.annotation.EnableAspectJAutoProxy; 9 | import org.springframework.scheduling.annotation.EnableAsync; 10 | import org.springframework.scheduling.annotation.EnableScheduling; 11 | 12 | @SpringBootApplication 13 | //@EnableCodeGenerate 14 | @EnableUserModel 15 | @EnableAsync 16 | @EnableAspectJAutoProxy 17 | //@EnableSecurityClient4Http 18 | //@EnableZuulProxy 19 | @EnableCaching 20 | @EnableScheduling 21 | public class GuodunDocumentApplication { 22 | public static void main(String[] args) { 23 | 24 | SpringApplication.run(GuodunDocumentApplication.class, args); 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/resources/application-pro.properties: -------------------------------------------------------------------------------- 1 | server.port=9986 2 | spring.freemarker.suffix=.html 3 | spring.freemarker.cache=false 4 | spring.freemarker.charset=UTF-8 5 | spring.datasource.url=jdbc:mysql://192.168.1.24:8306/guodun_book?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8 6 | spring.datasource.username=root 7 | spring.datasource.password=sdgd@2019 8 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 9 | spring.datasource.hikari.minimum-idle=10 10 | spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver 11 | spring.datasource.hikari.maximum-pool-size=100 12 | spring.datasource.hikari.max-lifetime=300000 13 | spring.datasource.hikari.connection-test-query=SELECT 1 14 | # mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl 15 | 16 | spring.data.solr.host=http://192.168.2.154:8983/solr 17 | document.path.target=D:/home/document 18 | #document.path.markdown=D:/document/documentTest 19 | document.path.markdown=D:/document/technicalManual 20 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/SubscribeLogBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 订阅日志对象 10 | * @date 2024/07/24 11 | */ 12 | @Data 13 | public class SubscribeLogBo { 14 | /** 15 | * 16 | */ 17 | private String id; 18 | /** 19 | * 用户ID 20 | */ 21 | private String userId; 22 | private String subscribeName; 23 | /** 24 | * 企业ID 25 | */ 26 | private String companyId; 27 | /** 28 | * 错误码 29 | */ 30 | private String traceId; 31 | /** 32 | * 类名 33 | */ 34 | private String className; 35 | /** 36 | * 方法名 37 | */ 38 | private String methodName; 39 | /** 40 | * 错误信息 41 | */ 42 | private String message; 43 | private Integer handleStatus; 44 | /** 45 | * 创建时间 46 | */ 47 | private Date createTime; 48 | /** 49 | * 处理时间 50 | */ 51 | private Date handleTime; 52 | } 53 | -------------------------------------------------------------------------------- /console/src/components/md/MdView.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 42 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/AioRuntimeApplicationStartingEventListener.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log; 2 | 3 | import cn.hutool.core.date.DateUtil; 4 | import cn.hutool.core.lang.Console; 5 | import com.aio.runtime.common.info.SystemRuntimeInfo; 6 | import cn.aio1024.framework.basic.domain.trace.TraceId; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.boot.context.event.ApplicationStartingEvent; 9 | import org.springframework.context.ApplicationListener; 10 | 11 | import java.util.Date; 12 | 13 | /** 14 | * @author lzm 15 | * @desc 系统启动事件 16 | * @date 2024/08/13 17 | */ 18 | 19 | @Slf4j 20 | public class AioRuntimeApplicationStartingEventListener implements ApplicationListener { 21 | 22 | @Override 23 | public void onApplicationEvent(ApplicationStartingEvent event) { 24 | TraceId.setTraceId("start_"+ DateUtil.format(new Date(),"yyyyMMdd日HH时mm分ss秒")); 25 | SystemRuntimeInfo.systemStarting(); 26 | Console.log("#### 系统运行时模块启动 ####"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /docs/建表语句.md: -------------------------------------------------------------------------------- 1 | ```sql 2 | CREATE TABLE `error_feedback_record` ( 3 | `id` varchar(32) COLLATE utf8mb4_general_ci NOT NULL, 4 | `level` varchar(8) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '等级', 5 | `create_time` datetime DEFAULT NULL COMMENT '创建时间', 6 | `message` text COLLATE utf8mb4_general_ci COMMENT '消息', 7 | `trace_id` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '追踪码', 8 | `type` varchar(15) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '类型', 9 | `api_url` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请求地址', 10 | `terminal` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '终端', 11 | `token` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'token', 12 | `terminal_info` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '终端信息', 13 | `platform` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '平台', 14 | `remark` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注', 15 | PRIMARY KEY (`id`) 16 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 17 | 18 | 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/common/interceptor/TraceIdInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.common.interceptor; 2 | 3 | import cn.aio1024.framework.basic.domain.trace.TraceId; 4 | import cn.hutool.core.util.IdUtil; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.web.servlet.HandlerInterceptor; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | /** 12 | * @author lzm 13 | * @desc: 14 | * @date 2023/7/31 18:12 15 | */ 16 | public class TraceIdInterceptor implements HandlerInterceptor { 17 | private final static String TRACE_ID_HEADER = "Trace-Id"; 18 | @Override 19 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { 20 | String traceId = request.getHeader(TRACE_ID_HEADER); 21 | if (StringUtils.isBlank(traceId)){ 22 | traceId = IdUtil.getSnowflakeNextIdStr(); 23 | } 24 | TraceId.setTraceId(traceId); 25 | response.addHeader(TRACE_ID_HEADER,traceId); 26 | return true; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/beans/domain/AioBeanBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.beans.domain; 2 | 3 | import com.aio.runtime.db.orm.annotations.AioField; 4 | import com.aio.runtime.db.orm.annotations.AioId; 5 | import com.aio.runtime.db.orm.annotations.AioTable; 6 | import com.aio.runtime.db.orm.domain.enums.AioDbTypeEnum; 7 | import lombok.Data; 8 | 9 | /** 10 | * @author lzm 11 | * @desc Bean信息 12 | * @date 2024/07/31 13 | */ 14 | @Data 15 | @AioTable(value = "aio_bean",type = AioDbTypeEnum.SQL_LITE) 16 | public class AioBeanBo { 17 | @AioId() 18 | private String id; 19 | @AioField("bean_name") 20 | private String beanName; 21 | @AioField("class_name") 22 | private String className; 23 | @AioField("dependencies") 24 | private String dependencies; 25 | @AioField("scope") 26 | private String scope; 27 | @AioField("aliases") 28 | private String aliases; 29 | @AioField("interfaces") 30 | private String interfaces; 31 | @AioField("superclass") 32 | private String superclass; 33 | @AioField("resource") 34 | private String resource; 35 | } 36 | -------------------------------------------------------------------------------- /console/src/views/table/ArticleView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 48 | -------------------------------------------------------------------------------- /console/src/api/logApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function getLogPageApi(data,page) { 4 | return request({ 5 | url: '/runtime/aio/log/page', 6 | method: 'post', 7 | data, 8 | params:page 9 | }) 10 | } 11 | 12 | export function getLogSchemeOptionsApi(data,page) { 13 | return request({ 14 | url: '/runtime/aio/log/scheme/options', 15 | method: 'get', 16 | params:data 17 | }) 18 | } 19 | 20 | export function getLogSchemeDetailsApi(id) { 21 | return request({ 22 | url: '/runtime/aio/log/scheme', 23 | method: 'get', 24 | params:{id:id} 25 | }) 26 | } 27 | 28 | export function getLogLevelListApi(data) { 29 | return request({ 30 | url: '/runtime/aio/log/level/list', 31 | method: 'get', 32 | params:data 33 | }) 34 | } 35 | 36 | export function updateLogLevelApi(data) { 37 | return request({ 38 | url: '/runtime/aio/log/level', 39 | method: 'put', 40 | data 41 | }) 42 | } 43 | 44 | 45 | export function saveLogSchemeApi(data) { 46 | return request({ 47 | url: '/runtime/aio/log/scheme', 48 | method: 'post', 49 | data 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/common/info/SystemRuntimeInfo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.common.info; 2 | 3 | import cn.hutool.core.date.DateUtil; 4 | import cn.hutool.core.util.ObjectUtil; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author lzm 10 | * @desc 系统运行时信息 11 | * @date 2024/08/16 12 | */ 13 | 14 | public class SystemRuntimeInfo { 15 | private static Date SYSTEM_STARTING_TIME; 16 | private static Date SYSTEM_STARTED_TIME; 17 | 18 | public static void systemStarted(){ 19 | SYSTEM_STARTED_TIME = new Date(); 20 | } 21 | public static void systemStarting(){ 22 | SYSTEM_STARTING_TIME = new Date(); 23 | } 24 | public static String getSystemStartingTime(){ 25 | if (ObjectUtil.isNull(SYSTEM_STARTING_TIME)){ 26 | return null; 27 | } 28 | return DateUtil.formatDateTime(SYSTEM_STARTING_TIME); 29 | } 30 | 31 | public static String getSystemStartedTime(){ 32 | if (ObjectUtil.isNull(SYSTEM_STARTED_TIME)){ 33 | return null; 34 | } 35 | return DateUtil.formatDateTime(SYSTEM_STARTED_TIME); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/config/RuntimeLogWebViewConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.config; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 6 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | /** 10 | * @author lizhenming 11 | * @desc: web视图配置 12 | * @date 2022/12/19 14:58 13 | */ 14 | 15 | @Configuration 16 | @Slf4j 17 | 18 | public class RuntimeLogWebViewConfig implements WebMvcConfigurer { 19 | 20 | @Override 21 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 22 | registry.addResourceHandler("/view/runtime/**").addResourceLocations("classpath:/templates/runtime/console/"); 23 | } 24 | 25 | @Override 26 | public void addViewControllers(ViewControllerRegistry registry) { 27 | registry.addRedirectViewController("/view/runtime","/view/runtime/index.html"); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /console/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present PanJiaChen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/append/AioLogAppenderRunner.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.append; 2 | 3 | import ch.qos.logback.classic.LoggerContext; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.slf4j.Logger; 6 | import org.slf4j.impl.StaticLoggerBinder; 7 | import org.springframework.boot.ApplicationArguments; 8 | import org.springframework.boot.ApplicationRunner; 9 | import org.springframework.stereotype.Component; 10 | 11 | /** 12 | * @author lzm 13 | * @desc 订阅错误日志 14 | * @date 2024/07/22 15 | */ 16 | @Component 17 | @Slf4j 18 | public class AioLogAppenderRunner implements ApplicationRunner { 19 | @Override 20 | public void run(ApplicationArguments args) throws Exception { 21 | LoggerContext context = (LoggerContext)StaticLoggerBinder.getSingleton().getLoggerFactory(); 22 | AioLogLiteAppender appender = new AioLogLiteAppender(); 23 | appender.setContext(context); 24 | appender.setName("aioLogLiteAppender"); 25 | appender.start(); 26 | ch.qos.logback.classic.Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME); 27 | logger.addAppender(appender); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/domain/params/AddErrorParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.domain.params; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author lzm 7 | * @desc 错误上报参数 8 | * @date 2024/10/17 9 | */ 10 | @Data 11 | public class AddErrorParams { 12 | /** 13 | * 错误级别,info (信息),warn (警告),error (错误),fatal(灾难) 14 | */ 15 | private String level; 16 | /** 17 | * 错误信息 18 | */ 19 | private String message; 20 | /** 21 | * 追踪码 22 | */ 23 | private String traceId; 24 | /** 25 | * 错误类型 26 | */ 27 | private String type; 28 | /** 29 | * 错误接口地址 30 | */ 31 | private String apiUrl; 32 | /** 33 | * 非必填,如果有,系统会记录用户信息 34 | */ 35 | private String token; 36 | /** 37 | * 终端。web ,PC , Android ,ios,微信小程序 ,H5 ,微信公众号 等 38 | */ 39 | private String terminal; 40 | /** 41 | * 终端信息。例如:浏览器版本,系统版本,设备型号等 42 | */ 43 | private String terminalInfo; 44 | /** 45 | * 项目平台。例如 车管业务的 车主端,金融机构端 46 | */ 47 | private String platform; 48 | /** 49 | * 备注 50 | */ 51 | private String remark; 52 | } 53 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/user/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.user.controller; 2 | 3 | import cn.hutool.core.util.IdUtil; 4 | import com.alibaba.fastjson.JSON; 5 | import com.guodun.aio.document.user.domain.params.LoginParams; 6 | import cn.aio1024.framework.basic.domain.amis.AmisResult; 7 | 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | /** 15 | * @author lizhenming 16 | * @desc: 17 | * @date 2022/12/9 22:49 18 | */ 19 | @RestController 20 | @Slf4j 21 | @RequestMapping("/kgo/login") 22 | public class LoginController { 23 | @PostMapping( ) 24 | public AmisResult login(@RequestBody LoginParams loginParams){ 25 | log.info("登录请求入参 : {} ", JSON.toJSONString(loginParams)); 26 | AmisResult success = AmisResult.success(); 27 | success.setToken(IdUtil.fastSimpleUUID()); 28 | return success; 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /console/tests/unit/utils/formatTime.spec.js: -------------------------------------------------------------------------------- 1 | import { formatTime } from '@/utils/index.js' 2 | 3 | describe('Utils:formatTime', () => { 4 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" 5 | const retrofit = 5 * 1000 6 | 7 | it('ten digits timestamp', () => { 8 | expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分') 9 | }) 10 | it('test now', () => { 11 | expect(formatTime(+new Date() - 1)).toBe('刚刚') 12 | }) 13 | it('less two minute', () => { 14 | expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前') 15 | }) 16 | it('less two hour', () => { 17 | expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前') 18 | }) 19 | it('less one day', () => { 20 | expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前') 21 | }) 22 | it('more than one day', () => { 23 | expect(formatTime(d)).toBe('7月13日17时54分') 24 | }) 25 | it('format', () => { 26 | expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') 27 | expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') 28 | expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/domain/SubscribeLogVo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import lombok.Data; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author lzm 10 | * @desc 订阅日志对象 视图层 11 | * @date 2024/07/24 12 | */ 13 | @Data 14 | public class SubscribeLogVo { 15 | private String id; 16 | private String userId; 17 | private String subscribeName; 18 | private String companyId; 19 | /** 20 | * 错误码 21 | */ 22 | private String traceId; 23 | /** 24 | * 类名 25 | */ 26 | private String className; 27 | /** 28 | * 方法名 29 | */ 30 | private String methodName; 31 | /** 32 | * 错误信息 33 | */ 34 | private String message; 35 | 36 | /** 37 | * 创建时间 38 | */ 39 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 40 | private Date createTime; 41 | /** 42 | * 处理时间 43 | */ 44 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 45 | private Date handleTime; 46 | private Integer handleStatus; 47 | private String handleStatusDesc; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/security/RuntimeSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.security; 2 | 3 | import com.aio.runtime.security.domain.RuntimeSecurityProperties; 4 | import cn.aio1024.framework.basic.adapter.user.AioSecurityAdapter; 5 | import cn.aio1024.framework.basic.adapter.user.impl.AioSecurityAdapter4RAM; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.ComponentScan; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | /** 13 | * @author lzm 14 | * @desc 安全模块配置 15 | * @date 2024/08/07 16 | */ 17 | @Configuration 18 | @ComponentScan({"com.aio.runtime.security"}) 19 | @EnableConfigurationProperties(RuntimeSecurityProperties.class) 20 | @ConditionalOnProperty(prefix = "aio.runtime.security",name = "enable",havingValue = "true",matchIfMissing = true) 21 | public class RuntimeSecurityConfig { 22 | 23 | @Bean 24 | public AioSecurityAdapter aioSecurityAdapter4RAM(){ 25 | return new AioSecurityAdapter4RAM(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /console/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | @import './mixin.scss'; 3 | @import './transition.scss'; 4 | @import './element-ui.scss'; 5 | @import './sidebar.scss'; 6 | 7 | body { 8 | height: 100%; 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-font-smoothing: antialiased; 11 | text-rendering: optimizeLegibility; 12 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; 13 | } 14 | 15 | label { 16 | font-weight: 700; 17 | } 18 | 19 | html { 20 | height: 100%; 21 | box-sizing: border-box; 22 | } 23 | 24 | #app { 25 | height: 100%; 26 | } 27 | 28 | *, 29 | *:before, 30 | *:after { 31 | box-sizing: inherit; 32 | } 33 | 34 | a:focus, 35 | a:active { 36 | outline: none; 37 | } 38 | 39 | a, 40 | a:focus, 41 | a:hover { 42 | cursor: pointer; 43 | color: inherit; 44 | text-decoration: none; 45 | } 46 | 47 | div:focus { 48 | outline: none; 49 | } 50 | 51 | .clearfix { 52 | &:after { 53 | visibility: hidden; 54 | display: block; 55 | font-size: 0; 56 | content: " "; 57 | clear: both; 58 | height: 0; 59 | } 60 | } 61 | 62 | // main-container global css 63 | .app-container { 64 | padding: 20px; 65 | } 66 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/user/TestAioUserApiImpl.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.user; 2 | 3 | import cn.hutool.core.util.IdUtil; 4 | import cn.aio1024.framework.basic.integration.user.AioUserApi; 5 | import cn.aio1024.framework.basic.integration.user.domain.AioUser; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @author lzm 10 | * @desc 测试集成用户权限 11 | * @date 2024/05/13 12 | */ 13 | @Component 14 | public class TestAioUserApiImpl implements AioUserApi { 15 | @Override 16 | public AioUser getCurrentUser() { 17 | AioUser aioUser = new AioUser(); 18 | aioUser.setUserId(String.valueOf(System.currentTimeMillis())); 19 | aioUser.setUserName("李振明"); 20 | aioUser.setCompanyId(IdUtil.getSnowflakeNextIdStr()); 21 | aioUser.setCompanyName("山东国盾网"); 22 | return aioUser; 23 | } 24 | 25 | @Override 26 | public AioUser getUserById(String userId) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public AioUser getUserByUsername(String username) { 32 | return null; 33 | } 34 | 35 | @Override 36 | public AioUser getUserByCardNo(String cardNo) { 37 | return null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/service/AbstractMappingLogService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.service; 2 | 3 | import com.aio.runtime.record.log.domain.MappingRecordBo; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.concurrent.*; 8 | 9 | public abstract class AbstractMappingLogService implements MappingLogService{ 10 | public static BlockingQueue RECORD_QUEUE = new LinkedBlockingQueue<>(10000); 11 | private ScheduledExecutorService executorMappingLogService = Executors.newScheduledThreadPool(1); 12 | public AbstractMappingLogService(){ 13 | Runnable task = () -> { 14 | List recordBos = drainTo(); 15 | batchSave(recordBos); 16 | }; 17 | executorMappingLogService.scheduleAtFixedRate(task, 30, 2, TimeUnit.SECONDS); 18 | 19 | } 20 | @Override 21 | public void temporaryStorage(MappingRecordBo mappingRecord) { 22 | RECORD_QUEUE.add(mappingRecord); 23 | } 24 | 25 | @Override 26 | public List drainTo() { 27 | List records = new ArrayList<>(); 28 | RECORD_QUEUE.drainTo(records); 29 | return records; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /console/src/icons/svg/eye-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /console/src/store/modules/app.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const state = { 4 | sidebar: { 5 | opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, 6 | withoutAnimation: false 7 | }, 8 | device: 'desktop' 9 | } 10 | 11 | const mutations = { 12 | TOGGLE_SIDEBAR: state => { 13 | state.sidebar.opened = !state.sidebar.opened 14 | state.sidebar.withoutAnimation = false 15 | if (state.sidebar.opened) { 16 | Cookies.set('sidebarStatus', 1) 17 | } else { 18 | Cookies.set('sidebarStatus', 0) 19 | } 20 | }, 21 | CLOSE_SIDEBAR: (state, withoutAnimation) => { 22 | Cookies.set('sidebarStatus', 0) 23 | state.sidebar.opened = false 24 | state.sidebar.withoutAnimation = withoutAnimation 25 | }, 26 | TOGGLE_DEVICE: (state, device) => { 27 | state.device = device 28 | } 29 | } 30 | 31 | const actions = { 32 | toggleSideBar({ commit }) { 33 | commit('TOGGLE_SIDEBAR') 34 | }, 35 | closeSideBar({ commit }, { withoutAnimation }) { 36 | commit('CLOSE_SIDEBAR', withoutAnimation) 37 | }, 38 | toggleDevice({ commit }, device) { 39 | commit('TOGGLE_DEVICE', device) 40 | } 41 | } 42 | 43 | export default { 44 | namespaced: true, 45 | state, 46 | mutations, 47 | actions 48 | } 49 | -------------------------------------------------------------------------------- /console/tests/unit/utils/parseTime.spec.js: -------------------------------------------------------------------------------- 1 | import { parseTime } from '@/utils/index.js' 2 | 3 | describe('Utils:parseTime', () => { 4 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" 5 | it('timestamp', () => { 6 | expect(parseTime(d)).toBe('2018-07-13 17:54:01') 7 | }) 8 | it('timestamp string', () => { 9 | expect(parseTime((d + ''))).toBe('2018-07-13 17:54:01') 10 | }) 11 | it('ten digits timestamp', () => { 12 | expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01') 13 | }) 14 | it('new Date', () => { 15 | expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01') 16 | }) 17 | it('format', () => { 18 | expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') 19 | expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') 20 | expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') 21 | }) 22 | it('get the day of the week', () => { 23 | expect(parseTime(d, '{a}')).toBe('五') // 星期五 24 | }) 25 | it('get the day of the week', () => { 26 | expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日 27 | }) 28 | it('empty argument', () => { 29 | expect(parseTime()).toBeNull() 30 | }) 31 | 32 | it('null', () => { 33 | expect(parseTime(null)).toBeNull() 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/domain/params/QueryErrorParams.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.domain.params; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 错误上报参数 10 | * @date 2024/10/17 11 | */ 12 | @Data 13 | public class QueryErrorParams { 14 | /** 15 | * 错误级别,info (信息),warn (警告),error (错误),fatal(灾难) 16 | */ 17 | private String level; 18 | /** 19 | * 错误信息 20 | */ 21 | private String message; 22 | /** 23 | * 追踪码 24 | */ 25 | private String traceId; 26 | /** 27 | * 错误类型 28 | */ 29 | private String type; 30 | /** 31 | * 错误接口地址 32 | */ 33 | private String apiUrl; 34 | /** 35 | * 非必填,如果有,系统会记录用户信息 36 | */ 37 | private String token; 38 | /** 39 | * 终端。web,PC , Android,ios,微信小程序,H5,微信公众号 等 40 | */ 41 | private String terminal; 42 | /** 43 | * 终端信息。例如:浏览器版本,系统版本,设备型号等 44 | */ 45 | private String terminalInfo; 46 | /** 47 | * 项目平台。例如 车管业务的 车主端,金融机构端 48 | */ 49 | private String platform; 50 | /** 51 | * 备注 52 | */ 53 | private String remark; 54 | 55 | private List keywords; 56 | 57 | private Long createToTime; 58 | private Long createFromTime; 59 | } 60 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/domain/MappingRecordBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.domain; 2 | 3 | import lombok.Data; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | import java.util.Date; 7 | import java.util.List; 8 | 9 | /** 10 | * @author lzm 11 | * @desc 请求日志记录 12 | * @date 2024/05/13 13 | */ 14 | @Data 15 | public class MappingRecordBo { 16 | private String id; 17 | private long createTimestamp; 18 | private Date createTime; 19 | private String httpMethod; 20 | private String url; 21 | 22 | private String userId; 23 | private String userName; 24 | private String companyId; 25 | private String companyName; 26 | 27 | private String mappingClass; 28 | private String mappingMethod; 29 | private List paramsClass; 30 | private String params; 31 | private String result; 32 | private String traceId; 33 | private String stackTrace; 34 | private String throwable; 35 | private String exceptionMsg; 36 | private Boolean success; 37 | private Boolean deprecated = false; 38 | 39 | 40 | public void setBasicUrl(String url) { 41 | if (!StringUtils.startsWith(url, "/")) { 42 | this.url = "/" + url; 43 | } else { 44 | this.url = url; 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/ErrorReportedConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported; 2 | 3 | import com.aio.runtime.reported.domain.ErrorReportedProperties; 4 | import com.alibaba.fastjson.JSON; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 9 | import org.springframework.context.annotation.ComponentScan; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | /** 13 | * @author lzm 14 | * @desc 错误上报 15 | * @date 2024/10/17 16 | */ 17 | @ComponentScan("com.aio.runtime.reported") 18 | @Slf4j 19 | @Configuration 20 | @ConditionalOnProperty(prefix = ErrorReportedProperties.PREFIX, value = "enable", havingValue = "true", matchIfMissing = true) 21 | @MapperScan("com.aio.runtime.reported.mapper") 22 | @EnableConfigurationProperties(ErrorReportedProperties.class) 23 | public class ErrorReportedConfig { 24 | private final ErrorReportedProperties errorReportedProperties; 25 | public ErrorReportedConfig(ErrorReportedProperties properties) { 26 | this.errorReportedProperties = properties; 27 | log.info("错误上报初始化,配置属性 : {} ", JSON.toJSONString(errorReportedProperties)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /console/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets 4 | 5 | import ElementUI from 'element-ui' 6 | import 'element-ui/lib/theme-chalk/index.css' 7 | import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n 8 | 9 | import '@/styles/index.scss' // global css 10 | import '@/styles/custom-awesome-json-theme.scss'; 11 | import App from './App' 12 | import store from './store' 13 | import router from './router' 14 | 15 | import '@/icons' // icon 16 | import '@/permission' // permission control 17 | import Highlight from '@/utils/highlight' 18 | import JsonViewer from 'vue-json-viewer' 19 | Vue.use(JsonViewer) 20 | Vue.use(Highlight) 21 | 22 | /** 23 | * If you don't want to use mock-server 24 | * you want to use MockJs for mock api 25 | * you can execute: mockXHR() 26 | * 27 | * Currently MockJs will be used in the production environment, 28 | * please remove it before going online ! ! ! 29 | */ 30 | if (process.env.NODE_ENV === 'production') { 31 | const { mockXHR } = require('../mock') 32 | mockXHR() 33 | } 34 | 35 | // set ElementUI lang to EN 36 | Vue.use(ElementUI, { locale }) 37 | // 如果想要中文版 element-ui,按如下方式声明 38 | // Vue.use(ElementUI) 39 | 40 | Vue.config.productionTip = false 41 | 42 | new Vue({ 43 | el: '#app', 44 | router, 45 | store, 46 | render: h => h(App) 47 | }) 48 | -------------------------------------------------------------------------------- /console/src/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 32 | 33 | 45 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/integration/RuntimeRecordModuleDiscover.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.integration; 2 | 3 | import cn.aio1024.framework.basic.discover.AioDiscover; 4 | import cn.aio1024.framework.basic.discover.domain.ModuleDetails; 5 | import cn.aio1024.framework.basic.discover.domain.ModuleEnvironmentVariable; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.List; 10 | 11 | @Component 12 | public class RuntimeRecordModuleDiscover implements AioDiscover { 13 | @Value("${runtime.version}") 14 | private String version; 15 | @Override 16 | public String getVersion() { 17 | return version; 18 | } 19 | 20 | @Override 21 | public ModuleDetails getDetails() { 22 | ModuleDetails moduleDetails = new ModuleDetails(); 23 | moduleDetails.setName("系统运行记录"); 24 | moduleDetails.setOpsUrl("/view/runtime"); 25 | moduleDetails.setDesc("系统运行记录"); 26 | moduleDetails.setTag("runtimeLog"); 27 | moduleDetails.setVersion(getVersion()); 28 | moduleDetails.setLogo("/static/runtimeLogo.png"); 29 | return moduleDetails; 30 | } 31 | 32 | @Override 33 | public List getEnvironmentVariables() { 34 | return null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/domain/constants/MappingLogFieldConstant.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.domain.constants; 2 | 3 | /** 4 | * @author lzm 5 | * @desc Mapping日志字段常量 6 | * @date 2024/05/14 7 | */ 8 | public class MappingLogFieldConstant { 9 | public static final String ID = "id"; 10 | public static final String CREATE_TIMESTAMP = "createTimestamp"; 11 | public static final String HTTP_METHOD = "httpMethod"; 12 | public static final String URL = "url"; 13 | public static final String USER_ID = "userId"; 14 | public static final String USER_NAME = "userName"; 15 | public static final String COMPANY_ID = "companyId"; 16 | public static final String COMPANY_NAME = "companyName"; 17 | public static final String MAPPING_CLASS = "mappingClass"; 18 | public static final String MAPPING_METHOD = "mappingMethod"; 19 | public static final String PARAMS = "params"; 20 | public static final String SUCCESS = "success"; 21 | public static final String STACK_TRACE = "stackTrace"; 22 | public static final String EXCEPTION_MSG = "exceptionMsg"; 23 | public static final String THROWABLE = "throwable"; 24 | public static final String TRACE_ID = "traceId"; 25 | public static final String RESULT = "result"; 26 | public static final String DEPRECATED = "deprecated"; 27 | 28 | 29 | 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /console/src/styles/my-awesome-json-theme.scss: -------------------------------------------------------------------------------- 1 | // values are default one from jv-light template 2 | .my-awesome-json-theme { 3 | background: #fff; 4 | white-space: nowrap; 5 | color: #525252; 6 | font-size: 14px; 7 | font-family: Consolas, Menlo, Courier, monospace; 8 | 9 | .jv-ellipsis { 10 | color: #999; 11 | background-color: #eee; 12 | display: inline-block; 13 | line-height: 0.9; 14 | font-size: 0.9em; 15 | padding: 0px 4px 2px 4px; 16 | border-radius: 3px; 17 | vertical-align: 2px; 18 | cursor: pointer; 19 | user-select: none; 20 | } 21 | .jv-button { color: #49b3ff } 22 | .jv-key { color: #111111 } 23 | .jv-item { 24 | &.jv-array { color: #111111 } 25 | &.jv-boolean { color: #fc1e70 } 26 | &.jv-function { color: #067bca } 27 | &.jv-number { color: #fc1e70 } 28 | &.jv-number-float { color: #fc1e70 } 29 | &.jv-number-integer { color: #fc1e70 } 30 | &.jv-object { color: #111111 } 31 | &.jv-undefined { color: #e08331 } 32 | &.jv-string { 33 | color: #42b983; 34 | word-break: break-word; 35 | white-space: normal; 36 | } 37 | } 38 | .jv-code { 39 | .jv-toggle { 40 | &:before { 41 | padding: 0px 2px; 42 | border-radius: 2px; 43 | } 44 | &:hover { 45 | &:before { 46 | background: #eee; 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /console/src/styles/custom-awesome-json-theme.scss: -------------------------------------------------------------------------------- 1 | // values are default one from jv-light template 2 | .my-awesome-json-theme { 3 | background: #393D49; 4 | white-space: nowrap; 5 | color: #525252; 6 | font-size: 14px; 7 | font-family: Consolas, Menlo, Courier, monospace; 8 | 9 | .jv-ellipsis { 10 | color: #999; 11 | background-color: #eee; 12 | display: inline-block; 13 | line-height: 0.9; 14 | font-size: 0.9em; 15 | padding: 0px 4px 2px 4px; 16 | border-radius: 3px; 17 | vertical-align: 2px; 18 | cursor: pointer; 19 | user-select: none; 20 | } 21 | .jv-button { color: #49b3ff } 22 | .jv-key { color: #FFB800 } 23 | .jv-item { 24 | &.jv-array { color: #FF5722 } 25 | &.jv-boolean { color: #fc1e70 } 26 | &.jv-function { color: #067bca } 27 | &.jv-number { color: #fc1e70 } 28 | &.jv-number-float { color: #fc1e70 } 29 | &.jv-number-integer { color: #fc1e70 } 30 | &.jv-object { color: #FF5722 } 31 | &.jv-undefined { color: #e08331 } 32 | &.jv-string { 33 | color: #42b983; 34 | word-break: break-word; 35 | white-space: normal; 36 | } 37 | } 38 | .jv-code { 39 | .jv-toggle { 40 | &:before { 41 | padding: 0px 2px; 42 | border-radius: 2px; 43 | } 44 | &:hover { 45 | &:before { 46 | background: #eee; 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/log/SubscribeAppenderRunner.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.log; 2 | 3 | import ch.qos.logback.classic.LoggerContext; 4 | import cn.aio1024.framework.basic.integration.user.AioUserApi; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.slf4j.Logger; 7 | import org.slf4j.impl.StaticLoggerBinder; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.ApplicationArguments; 10 | import org.springframework.boot.ApplicationRunner; 11 | import org.springframework.stereotype.Component; 12 | 13 | /** 14 | * @author lzm 15 | * @desc 订阅错误日志 16 | * @date 2024/07/22 17 | */ 18 | @Component 19 | @Slf4j 20 | public class SubscribeAppenderRunner implements ApplicationRunner { 21 | @Autowired(required = false) 22 | private AioUserApi aioUserApi; 23 | 24 | @Override 25 | public void run(ApplicationArguments args) throws Exception { 26 | LoggerContext context = (LoggerContext)StaticLoggerBinder.getSingleton().getLoggerFactory(); 27 | SubscribeErrorLogAppender appender = new SubscribeErrorLogAppender(aioUserApi); 28 | appender.setContext(context); 29 | appender.setName("SubscribeErrorLogAppender"); 30 | appender.start(); 31 | ch.qos.logback.classic.Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME); 32 | logger.addAppender(appender); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /console/src/api/runtimeApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | 4 | export function getRunTimeVersionApi() { 5 | return request({ 6 | url: '/runtime/aio/version', 7 | method: 'get' 8 | }) 9 | } 10 | 11 | 12 | export function getRunTimeWorkspaceApi() { 13 | return request({ 14 | url: '/runtime/aio/workspace', 15 | method: 'get' 16 | }) 17 | } 18 | 19 | export function getSystemStartingTimeApi() { 20 | return request({ 21 | url: '/runtime/aio/system/starting/time', 22 | method: 'get' 23 | }) 24 | } 25 | 26 | export function getSystemStartedTimeApi() { 27 | return request({ 28 | url: '/runtime/aio/system/started/time', 29 | method: 'get' 30 | }) 31 | } 32 | 33 | export function getHostInfoApi() { 34 | return request({ 35 | url: '/runtime/aio/system/hostInfo', 36 | method: 'get' 37 | }) 38 | } 39 | 40 | export function getPIDApi() { 41 | return request({ 42 | url: '/runtime/aio/system/pid', 43 | method: 'get' 44 | }) 45 | } 46 | export function getOSApi() { 47 | return request({ 48 | url: '/runtime/aio/system/os', 49 | method: 'get' 50 | }) 51 | } 52 | 53 | export function getMemoryChartLineApi() { 54 | return request({ 55 | url: '/runtime/aio/jvm/memory/chart/line', 56 | method: 'get' 57 | }) 58 | } 59 | 60 | export function clearJvmDataApi() { 61 | return request({ 62 | url: '/runtime/aio/jvm/clear', 63 | method: 'delete' 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /console/src/layout/mixin/ResizeHandler.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | const { body } = document 4 | const WIDTH = 992 // refer to Bootstrap's responsive design 5 | 6 | export default { 7 | watch: { 8 | $route(route) { 9 | if (this.device === 'mobile' && this.sidebar.opened) { 10 | store.dispatch('app/closeSideBar', { withoutAnimation: false }) 11 | } 12 | } 13 | }, 14 | beforeMount() { 15 | window.addEventListener('resize', this.$_resizeHandler) 16 | }, 17 | beforeDestroy() { 18 | window.removeEventListener('resize', this.$_resizeHandler) 19 | }, 20 | mounted() { 21 | const isMobile = this.$_isMobile() 22 | if (isMobile) { 23 | store.dispatch('app/toggleDevice', 'mobile') 24 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) 25 | } 26 | }, 27 | methods: { 28 | // use $_ for mixins properties 29 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential 30 | $_isMobile() { 31 | const rect = body.getBoundingClientRect() 32 | return rect.width - 1 < WIDTH 33 | }, 34 | $_resizeHandler() { 35 | if (!document.hidden) { 36 | const isMobile = this.$_isMobile() 37 | store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') 38 | 39 | if (isMobile) { 40 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/controller/ErrorReportedController.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.controller; 2 | 3 | import cn.aio1024.framework.basic.domain.amis.AmisResult; 4 | import cn.aio1024.framework.basic.domain.page.KgoPage; 5 | import cn.aio1024.framework.basic.domain.page.PageResult; 6 | import com.aio.runtime.reported.domain.params.AddErrorParams; 7 | import com.aio.runtime.reported.domain.params.QueryErrorParams; 8 | import com.aio.runtime.reported.service.ErrorReportedService; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | /** 14 | * @author lzm 15 | * @desc 错误上报接口 16 | * @date 2024/10/17 17 | */ 18 | @RestController 19 | @Slf4j 20 | @RequestMapping("/runtime/aio/error/reported") 21 | public class ErrorReportedController { 22 | @Autowired 23 | private ErrorReportedService errorReportedService; 24 | @PostMapping() 25 | public AmisResult addErrorReported(@RequestBody AddErrorParams params){ 26 | errorReportedService.addError(params); 27 | return AmisResult.success(); 28 | } 29 | @PostMapping("page") 30 | public AmisResult getErrorReportedPage(@RequestBody QueryErrorParams params , @ModelAttribute KgoPage page){ 31 | PageResult pageResult = errorReportedService.getPage(params,page); 32 | return AmisResult.success(pageResult); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/jvm/domain/AioJvmBo.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.jvm.domain; 2 | 3 | import com.aio.runtime.db.orm.annotations.AioField; 4 | import com.aio.runtime.db.orm.annotations.AioId; 5 | import com.aio.runtime.db.orm.annotations.AioTable; 6 | import com.aio.runtime.db.orm.domain.enums.AioDbTypeEnum; 7 | import lombok.Data; 8 | 9 | import java.util.Date; 10 | 11 | /** 12 | * @author lzm 13 | * @desc 运行时 14 | * @date 2024/08/16 15 | */ 16 | @Data 17 | @AioTable(value = "aio_jvm_statistics",type = AioDbTypeEnum.SQL_LITE) 18 | public class AioJvmBo { 19 | @AioId() 20 | private String id; 21 | /** 22 | * jvm 最大运行的内存 23 | */ 24 | @AioField("jvm_memory_max") 25 | private String jvmMemoryMax; 26 | /** 27 | * jvm 使用的内存 28 | */ 29 | @AioField("jvm_memory_used") 30 | private String jvmMemoryUsed; 31 | /** 32 | * JVM 中已经分配的内存量 33 | */ 34 | @AioField("jvm_memory_committed") 35 | private String jvmMemoryCommitted; 36 | 37 | /** 38 | * 守护线程数量 39 | */ 40 | @AioField("jvm_threads_daemon") 41 | private String jvmThreadsDaemon; 42 | 43 | /** 44 | * jvm 线程最多的时候的数量 45 | */ 46 | @AioField("jvm_threads_peak") 47 | private String jvmThreadsPeak; 48 | 49 | /** 50 | * jvm 获取线程数量 51 | */ 52 | @AioField("jvm_threads_live") 53 | private String jvmThreadsLive; 54 | 55 | @AioField("create_time") 56 | private Date createTime; 57 | } 58 | -------------------------------------------------------------------------------- /console/src/api/articleApi.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function addArticle(data) { 4 | return request({ 5 | url: '/article', 6 | method: 'post', 7 | data:data 8 | }) 9 | } 10 | export function saveArticle(data) { 11 | return request({ 12 | url: '/article', 13 | method: 'put', 14 | data:data 15 | }) 16 | } 17 | 18 | export function addArticleLabel(label) { 19 | return request({ 20 | url: '/article/label', 21 | method: 'post', 22 | data:{articleLabel:label} 23 | }) 24 | } 25 | 26 | export function getArticleLabel(label) { 27 | return request({ 28 | url: '/article/label/options', 29 | method: 'get', 30 | params:{label:label} 31 | }) 32 | } 33 | export function getArticleLabelList(articleId) { 34 | return request({ 35 | url: '/article/label', 36 | method: 'get', 37 | params:{articleId:articleId} 38 | }) 39 | } 40 | 41 | export function getHelpArticle(params) { 42 | return request({ 43 | url: '/article/help/list', 44 | method: 'post', 45 | data:params 46 | }) 47 | } 48 | export function getArticleById(articleId) { 49 | return request({ 50 | url: '/article', 51 | method: 'get', 52 | params:{id:articleId} 53 | }) 54 | } 55 | export function getArticlePage(params) { 56 | return request({ 57 | url: '/article/page', 58 | method: 'get', 59 | params:params 60 | }) 61 | } 62 | 63 | export function cleanArticleLabel() { 64 | return request({ 65 | url: '/article/clean/label', 66 | method: 'delete' 67 | }) 68 | } 69 | 70 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/controller/SubscribeLogController.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.controller; 2 | 3 | import com.aio.runtime.subscribe.domain.params.QuerySubscribeLogParams; 4 | import com.aio.runtime.subscribe.domain.params.UpdateSubscribeLogStatusParams; 5 | import com.aio.runtime.subscribe.service.SubscribeLogService; 6 | import cn.aio1024.framework.basic.domain.amis.AmisResult; 7 | import cn.aio1024.framework.basic.domain.page.KgoPage; 8 | import cn.aio1024.framework.basic.domain.page.PageResult; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | /** 14 | * @author lzm 15 | * @desc Mapping日志控制器 16 | * @date 2024/05/13 17 | */ 18 | @RestController 19 | @Slf4j 20 | @RequestMapping("/runtime/aio/log/subscribe/") 21 | public class SubscribeLogController { 22 | @Autowired 23 | private SubscribeLogService subscribeLogService; 24 | @GetMapping("page") 25 | public AmisResult getRecordPage(@ModelAttribute QuerySubscribeLogParams params , @ModelAttribute KgoPage page){ 26 | PageResult pageResult = subscribeLogService.getPage(params,page); 27 | return AmisResult.success(pageResult); 28 | } 29 | @PostMapping("handled") 30 | public AmisResult updateSubscribeToHandled(@RequestBody UpdateSubscribeLogStatusParams params){ 31 | subscribeLogService.updateSubscribeLogStatusToHandled(params); 32 | return AmisResult.success("标记日志为已处理"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /console/src/icons/svg/error-code.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/controller/MappingLogController.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log.controller; 2 | 3 | import com.aio.runtime.record.log.domain.QueryRecordParams; 4 | import com.aio.runtime.record.log.service.MappingLogService; 5 | import cn.aio1024.framework.basic.domain.amis.AmisResult; 6 | import cn.aio1024.framework.basic.domain.page.KgoPage; 7 | import cn.aio1024.framework.basic.domain.page.PageResult; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.ModelAttribute; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | /** 16 | * @author lzm 17 | * @desc Mapping日志控制器 18 | * @date 2024/05/13 19 | */ 20 | @RestController 21 | @Slf4j 22 | @RequestMapping("/runtime/aio/log/mapping/record") 23 | public class MappingLogController { 24 | @Autowired 25 | private MappingLogService mappingLogService; 26 | @GetMapping("page") 27 | public AmisResult getRecordPage(@ModelAttribute QueryRecordParams params , @ModelAttribute KgoPage page){ 28 | PageResult pageResult = mappingLogService.searchRecords(params,page); 29 | return AmisResult.success(pageResult); 30 | } 31 | @GetMapping("info") 32 | public AmisResult getRecordInfo(){ 33 | return AmisResult.success(mappingLogService.getRecordInfo()); 34 | } 35 | 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /docs/jvm线程相关.md: -------------------------------------------------------------------------------- 1 | ## jvm.threads.states 2 | 3 | `jvm.threads.states` 是一个与 JVM(Java Virtual Machine)线程状态相关的指标,通常用于监控和分析应用程序中的线程活动。这个指标显示了所有线程的当前状态,可以帮助开发者理解线程的行为和性能。 4 | 5 | ### 主要线程状态 6 | 7 | 1. **NEW**:线程已创建,但尚未启动。 8 | 2. **RUNNABLE**:线程正在运行或准备运行。可以是实际运行的线程或在可运行队列中的线程。 9 | 3. **BLOCKED**:线程在等待获取一个锁,无法继续执行。 10 | 4. **WAITING**:线程正在等待另一个线程的通知(如 `Object.wait()`)。 11 | 5. **TIMED_WAITING**:线程在等待另一个线程的通知或达到特定时间(如 `Thread.sleep(timeout)`)。 12 | 6. **TERMINATED**:线程已完成执行。 13 | 14 | ### 监控用途 15 | 16 | - **性能分析**:通过实时监控线程状态,可以发现容易导致性能问题的瓶颈。 17 | - **死锁检测**:可以识别 BLOCKED 状态的线程,从而帮助定位死锁。 18 | - **资源管理**:掌握线程状态有助于优化资源使用,避免过多的线程竞争。 19 | 20 | ### 可能的应用 21 | 22 | - **诊断**:用来诊断应用性能问题时,检查线程状态分布非常重要。 23 | - **调优**:根据监控数据调整线程池大小或其他资源分配策略。 24 | 25 | 26 | ## jvm.threads.daemon 27 | 28 | `jvm.threads.daemon` 指标表示当前 JVM 中的守护线程(daemon threads)的数量。守护线程是与用户线程相对的线程,它们在应用程序中通常用于执行支持性任务,如垃圾回收、监控、后台日志记录等。守护线程的主要特点是它们不会阻止 JVM 退出。 29 | 30 | ### 指标意义 31 | 32 | - **性能监控**:帮助开发者了解应用程序对系统资源的使用情况。 33 | - **调优**:通过监控守护线程数量,开发者可以判断应用是否需要调整线程配置。 34 | - **问题诊断**:如果守护线程数量异常,可能会影响应用行为或性能。 35 | 36 | 37 | ## jvm.threads.peak 38 | 39 | 40 | `jvm.threads.peak` 指标表示 JVM 运行期间创建的线程的最大数量。这个指标对于监控和优化 Java 应用程序的性能非常重要,尤其是在处理多线程的场景中。 41 | 42 | ### 指标意义 43 | 44 | - **资源使用**:帮助开发者分析应用程序对线程资源的使用情况。 45 | - **性能调优**:识别潜在的线程泄漏或不当线程管理,及时调整应用配置。 46 | - **行为预测**:在负载高峰期,监控该指标可以帮助预测应用的行为。 47 | 48 | 49 | ## jvm.threads.live 50 | 51 | `jvm.threads.live` 是一个指示当前活跃线程数量的指标。当你在监控 Java 应用时,它可以帮助你了解正在执行的线程数量。 52 | 53 | ### 指标意义 54 | 55 | - **系统负载**:显示当前同时运行的线程,可以帮助评估系统负载。 56 | - **性能监控**:了解应用的多线程性能,识别潜在的性能瓶颈。 57 | - **资源管理**:监控活跃线程有助于管理系统资源,确保线程使用的高效性。 58 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/user/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.user.controller; 2 | 3 | import com.aio.runtime.security.domain.UserInfoResult; 4 | import cn.aio1024.framework.basic.domain.amis.AmisResult; 5 | 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import java.util.Arrays; 14 | 15 | /** 16 | * @author lizhenming 17 | * @desc: 18 | * @date 2022/12/9 22:49 19 | */ 20 | @RestController 21 | @Slf4j 22 | @RequestMapping("/kgo/user") 23 | public class UserController { 24 | @GetMapping() 25 | public AmisResult getUser(){ 26 | UserInfoResult userInfoResult = new UserInfoResult(); 27 | userInfoResult.setName("李振明"); 28 | userInfoResult.setRoles(Arrays.asList("admin")); 29 | return AmisResult.success(userInfoResult); 30 | } 31 | @GetMapping("id") 32 | public AmisResult getUser2(@RequestParam String userId){ 33 | if (StringUtils.isNotBlank(userId)){ 34 | throw new RuntimeException("这是一个测试异常的请求"); 35 | } 36 | UserInfoResult userInfoResult = new UserInfoResult(); 37 | userInfoResult.setName("李振明"); 38 | userInfoResult.setRoles(Arrays.asList("admin")); 39 | return AmisResult.success(userInfoResult); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/mappings/controller/AioMappingController.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.mappings.controller; 2 | 3 | import cn.aio1024.framework.basic.domain.amis.AmisResult; 4 | import cn.aio1024.framework.basic.domain.page.KgoPage; 5 | import cn.aio1024.framework.basic.domain.page.PageResult; 6 | import com.aio.runtime.mappings.domain.QueryMappingParams; 7 | import com.aio.runtime.mappings.service.IAioMappingService; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 12 | import org.springframework.web.bind.annotation.GetMapping; 13 | import org.springframework.web.bind.annotation.ModelAttribute; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RestController; 16 | 17 | /** 18 | * @author lzm 19 | * @desc 接口控制器 20 | * @date 2024/07/27 21 | */ 22 | @RestController 23 | @Slf4j 24 | @RequestMapping("/runtime/aio/mapping") 25 | @ConditionalOnClass(MappingsEndpoint.class) 26 | public class AioMappingController { 27 | @Autowired(required = false) 28 | private IAioMappingService aioMappingService; 29 | @GetMapping("page") 30 | public AmisResult getEnvironmentItemPage(@ModelAttribute QueryMappingParams params , @ModelAttribute KgoPage page){ 31 | PageResult pageResult = aioMappingService.getPage(params,page); 32 | return AmisResult.success(pageResult); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/subscribe/log/SubscribeMarker.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.subscribe.log; 2 | 3 | import org.slf4j.Marker; 4 | 5 | import java.util.Iterator; 6 | 7 | /** 8 | * @author lzm 9 | * @desc 订阅标识 10 | * @date 2024/07/22 11 | */ 12 | public class SubscribeMarker implements Marker { 13 | private String name; 14 | public static SubscribeMarker getMarker(){ 15 | return new SubscribeMarker("subscribe"); 16 | } 17 | public static SubscribeMarker getErrorMarker(){ 18 | return new SubscribeMarker("error"); 19 | } 20 | public static SubscribeMarker getMarker(String name){ 21 | return new SubscribeMarker(name); 22 | } 23 | public SubscribeMarker(String name){ 24 | this.name = name; 25 | } 26 | @Override 27 | public String getName() { 28 | return this.name; 29 | } 30 | 31 | @Override 32 | public void add(Marker marker) { 33 | 34 | } 35 | 36 | @Override 37 | public boolean remove(Marker marker) { 38 | return false; 39 | } 40 | 41 | @Override 42 | public boolean hasChildren() { 43 | return false; 44 | } 45 | 46 | @Override 47 | public boolean hasReferences() { 48 | return false; 49 | } 50 | 51 | @Override 52 | public Iterator iterator() { 53 | return null; 54 | } 55 | 56 | @Override 57 | public boolean contains(Marker marker) { 58 | return false; 59 | } 60 | 61 | @Override 62 | public boolean contains(String s) { 63 | return false; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /console/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 47 | 48 | 63 | -------------------------------------------------------------------------------- /console/src/views/user/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 48 | 49 | 54 | 55 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/environment/controller/AioEnvironmentController.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.environment.controller; 2 | 3 | import com.aio.runtime.environment.domain.QueryEnvironmentParams; 4 | import com.aio.runtime.environment.service.IAioEnvironmentService; 5 | import cn.aio1024.framework.basic.domain.amis.AmisResult; 6 | import cn.aio1024.framework.basic.domain.page.KgoPage; 7 | import cn.aio1024.framework.basic.domain.page.PageResult; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.actuate.env.EnvironmentEndpoint; 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 12 | import org.springframework.web.bind.annotation.GetMapping; 13 | import org.springframework.web.bind.annotation.ModelAttribute; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RestController; 16 | 17 | /** 18 | * @author lzm 19 | * @desc 环境信息查询接口 20 | * @date 2024/07/26 21 | */ 22 | @RestController 23 | @Slf4j 24 | @RequestMapping("/runtime/aio/environment") 25 | @ConditionalOnClass(EnvironmentEndpoint.class) 26 | public class AioEnvironmentController { 27 | @Autowired 28 | private IAioEnvironmentService iAioEnvironmentService; 29 | @GetMapping("page") 30 | public AmisResult getEnvironmentItemPage(@ModelAttribute QueryEnvironmentParams params , @ModelAttribute KgoPage page){ 31 | PageResult pageResult = iAioEnvironmentService.getPage(params,page); 32 | return AmisResult.success(pageResult); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /console/mock/index.js: -------------------------------------------------------------------------------- 1 | const Mock = require('mockjs') 2 | const { param2Obj } = require('./utils') 3 | 4 | const user = require('./user') 5 | const table = require('./table') 6 | 7 | const mocks = [ 8 | ...user, 9 | ...table 10 | ] 11 | 12 | // for front mock 13 | // please use it cautiously, it will redefine XMLHttpRequest, 14 | // which will cause many of your third-party libraries to be invalidated(like progress event). 15 | function mockXHR() { 16 | // mock patch 17 | // https://github.com/nuysoft/Mock/issues/300 18 | Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send 19 | Mock.XHR.prototype.send = function() { 20 | if (this.custom.xhr) { 21 | this.custom.xhr.withCredentials = this.withCredentials || false 22 | 23 | if (this.responseType) { 24 | this.custom.xhr.responseType = this.responseType 25 | } 26 | } 27 | this.proxy_send(...arguments) 28 | } 29 | 30 | function XHR2ExpressReqWrap(respond) { 31 | return function(options) { 32 | let result = null 33 | if (respond instanceof Function) { 34 | const { body, type, url } = options 35 | // https://expressjs.com/en/4x/api.html#req 36 | result = respond({ 37 | method: type, 38 | body: JSON.parse(body), 39 | query: param2Obj(url) 40 | }) 41 | } else { 42 | result = respond 43 | } 44 | return Mock.mock(result) 45 | } 46 | } 47 | 48 | for (const i of mocks) { 49 | Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) 50 | } 51 | } 52 | 53 | module.exports = { 54 | mocks, 55 | mockXHR 56 | } 57 | 58 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/resources/chart/MemoryChartLine.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAxis": { 3 | "data": [], 4 | "boundaryGap": false, 5 | "axisTick": { 6 | "show": false 7 | } 8 | }, 9 | "grid": { 10 | "left": 10, 11 | "right": 10, 12 | "bottom": 20, 13 | "top": 30, 14 | "containLabel": true 15 | }, 16 | "tooltip": { 17 | "trigger": "axis", 18 | "axisPointer": { 19 | "type": "cross" 20 | }, 21 | "padding": [ 22 | 5, 23 | 10 24 | ] 25 | }, 26 | "yAxis": { 27 | "axisTick": { 28 | "show": false 29 | } 30 | }, 31 | "legend": { 32 | "data": [ 33 | "已使用内存", 34 | "已分配内存" 35 | ] 36 | }, 37 | "series": [ 38 | { 39 | "name": "已使用内存", 40 | "itemStyle": { 41 | "normal": { 42 | "color": "#FF005A", 43 | "lineStyle": { 44 | "color": "#FF005A", 45 | "width": 2 46 | } 47 | } 48 | }, 49 | "smooth": true, 50 | "type": "line", 51 | "data": [], 52 | "animationDuration": 2800, 53 | "animationEasing": "cubicInOut" 54 | }, 55 | { 56 | "name": "已分配内存", 57 | "smooth": true, 58 | "type": "line", 59 | "itemStyle": { 60 | "normal": { 61 | "color": "#3888fa", 62 | "lineStyle": { 63 | "color": "#3888fa", 64 | "width": 2 65 | }, 66 | "areaStyle": { 67 | "color": "#f3f8ff" 68 | } 69 | } 70 | }, 71 | "data": [], 72 | "animationDuration": 2800, 73 | "animationEasing": "quadraticOut" 74 | } 75 | ] 76 | } 77 | -------------------------------------------------------------------------------- /runtime-record-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "groups": [ 4 | { 5 | "name": "aio.runtime.security", 6 | "type": "com.aio.runtime.security.domain.RuntimeSecurityProperties", 7 | "sourceType": "com.aio.runtime.security.domain.RuntimeSecurityProperties" 8 | }, 9 | { 10 | "name": "aio.runtime.log", 11 | "type": "com.aio.runtime.log.domain.AioLogAppendProperties", 12 | "sourceType": "com.aio.runtime.log.domain.AioLogAppendProperties" 13 | } 14 | ], 15 | "properties": [ 16 | { 17 | "name": "aio.runtime.security.enable", 18 | "type": "java.lang.Boolean", 19 | "description": "是否启动运行时默认的安全配置", 20 | "defaultValue": false 21 | }, 22 | { 23 | "name": "aio.runtime.security.username", 24 | "type": "java.lang.String", 25 | "description": "用户名", 26 | "defaultValue": "admin" 27 | }, 28 | { 29 | "name": "aio.runtime.security.password", 30 | "type": "java.lang.String", 31 | "description": "用户密码" 32 | }, 33 | { 34 | "name": "aio.runtime.log.enable", 35 | "type": "java.lang.Boolean", 36 | "description": "是否启动日志模块", 37 | "defaultValue": true 38 | }, 39 | { 40 | "name": "aio.runtime.log.past-day", 41 | "type": "java.lang.Integer", 42 | "description": "日志保存的时间(单位 天 )默认90天", 43 | "defaultValue": 90 44 | }, 45 | { 46 | "name": "aio.runtime.log.index-period", 47 | "type": "java.lang.String", 48 | "description": "索引周期 默认小时 hour , 可选 day ", 49 | "defaultValue": "hour" 50 | } 51 | ] 52 | } 53 | 54 | -------------------------------------------------------------------------------- /console/src/components/md/MdEdit.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 62 | -------------------------------------------------------------------------------- /console/src/layout/components/Sidebar/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 57 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/zuul/UserCenterZuulFilter.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.zuul; 2 | 3 | import com.guodun.security.client.http.config.HttpClientProperties; 4 | import com.netflix.zuul.ZuulFilter; 5 | import com.netflix.zuul.context.RequestContext; 6 | import com.netflix.zuul.exception.ZuulException; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | 13 | /** 14 | * @author lizhenming 15 | * @desc: 16 | * @date 2023/11/7 14:23 17 | */ 18 | //@Component 19 | @Slf4j 20 | public class UserCenterZuulFilter extends ZuulFilter { 21 | @Autowired 22 | private HttpClientProperties clientProperties; 23 | 24 | @Override 25 | public String filterType() { 26 | return "pre"; 27 | } 28 | 29 | @Override 30 | public int filterOrder() { 31 | return 0; 32 | } 33 | 34 | @Override 35 | public boolean shouldFilter() { 36 | return true; 37 | } 38 | 39 | @Override 40 | public Object run() throws ZuulException { 41 | RequestContext rc = RequestContext.getCurrentContext(); 42 | HttpServletRequest request = rc.getRequest(); 43 | if (request.getRequestURI().indexOf("login") > 0) { 44 | String credential = clientProperties.getCredential(); 45 | rc.addZuulRequestHeader("App_credential", credential); 46 | } 47 | String token = request.getHeader("token"); 48 | if (StringUtils.isNotBlank(token)){ 49 | rc.addZuulRequestHeader("token", token); 50 | } 51 | return null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /console/src/icons/svg/tree.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/record/log/RuntimeRecordConfig.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.record.log; 2 | 3 | import com.aio.runtime.beans.AioRuntimeBeansConfig; 4 | import com.aio.runtime.cache.AioCacheManageConfig; 5 | import com.aio.runtime.jvm.AioJvmConfig; 6 | import com.aio.runtime.log.AioLogAppendConfig; 7 | import com.aio.runtime.record.log.config.properties.AioMappingLogProperties; 8 | import com.aio.runtime.reported.ErrorReportedConfig; 9 | import com.aio.runtime.security.RuntimeSecurityConfig; 10 | import com.aio.runtime.subscribe.AioSubscribeConfig; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 13 | import org.springframework.context.annotation.ComponentScan; 14 | import org.springframework.context.annotation.Configuration; 15 | import org.springframework.context.annotation.Import; 16 | import org.springframework.context.annotation.PropertySource; 17 | 18 | /** 19 | * @author lzm 20 | * @desc 电子印章销售模块配置 21 | * @date 2024/04/18 22 | */ 23 | @Configuration 24 | @ComponentScan({ 25 | "com.aio.runtime.record.log", 26 | "com.aio.runtime.environment", 27 | "com.aio.runtime.common", 28 | "com.aio.runtime.mappings" 29 | }) 30 | @Slf4j 31 | @Import({ 32 | 33 | AioSubscribeConfig.class, 34 | AioRuntimeBeansConfig.class, 35 | AioRuntimeBeansConfig.class, 36 | RuntimeSecurityConfig.class, 37 | AioLogAppendConfig.class, 38 | AioJvmConfig.class, 39 | AioCacheManageConfig.class, 40 | ErrorReportedConfig.class 41 | 42 | }) 43 | @EnableConfigurationProperties(AioMappingLogProperties.class) 44 | @PropertySource("classpath:runtime-log-version.properties") 45 | public class RuntimeRecordConfig { 46 | 47 | } 48 | -------------------------------------------------------------------------------- /console/src/views/tree/index.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 78 | 79 | -------------------------------------------------------------------------------- /console/src/components/selects/ArticleLabelSearchSelect.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 65 | 66 | 68 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/service/AbstractAioLogService.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.service; 2 | 3 | import cn.hutool.core.date.DateUtil; 4 | import cn.hutool.core.io.FileUtil; 5 | import cn.hutool.core.util.ObjectUtil; 6 | import cn.hutool.core.util.StrUtil; 7 | import com.aio.runtime.log.domain.AioLogBo; 8 | import com.aio.runtime.log.save.LogSaveCache; 9 | import lombok.extern.slf4j.Slf4j; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | import java.util.concurrent.Executors; 14 | import java.util.concurrent.ScheduledExecutorService; 15 | import java.util.concurrent.TimeUnit; 16 | 17 | /** 18 | * @author lzm 19 | * @desc 日志管理抽象类 20 | * @date 2024/08/08 21 | */ 22 | @Slf4j 23 | public abstract class AbstractAioLogService implements AioLogService { 24 | private ScheduledExecutorService logThreadPool = Executors.newScheduledThreadPool(5); 25 | 26 | public AbstractAioLogService(){ 27 | Runnable task = () -> { 28 | long start = System.currentTimeMillis(); 29 | List aioLogList = LogSaveCache.drainTo(); 30 | batchSaveLogs(aioLogList); 31 | if (ObjectUtil.isNotEmpty(aioLogList)){ 32 | String logStr = StrUtil.format("存储日志任务,执行时间[ {} ] ,日志共 [ {} ] 行 , 耗时[ {} ]", DateUtil.now(),aioLogList.size(),System.currentTimeMillis()-start); 33 | FileUtil.appendUtf8Lines(Arrays.asList(logStr), "D:\\home\\record\\log\\logSave.log"); 34 | } 35 | 36 | 37 | }; 38 | Runnable clearTask = () -> { 39 | clearLogs(); 40 | }; 41 | logThreadPool.scheduleAtFixedRate(task, 30, 300, TimeUnit.MILLISECONDS); 42 | logThreadPool.scheduleAtFixedRate(clearTask, 1, 2, TimeUnit.HOURS); 43 | } 44 | public abstract void batchSaveLogs(List aioLogList); 45 | public abstract void clearLogs(); 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | 2 | spring.datasource.url=jdbc:mysql://192.168.1.24:8306/runtime_dev?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8 3 | spring.datasource.username=root 4 | spring.datasource.password=sdgd@2019 5 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 6 | spring.datasource.hikari.minimum-idle=10 7 | spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver 8 | spring.datasource.hikari.maximum-pool-size=100 9 | spring.datasource.hikari.max-lifetime=300000 10 | spring.datasource.hikari.connection-test-query=SELECT 1 11 | # mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl 12 | 13 | spring.data.solr.host=http://192.168.2.154:8983/solr 14 | 15 | 16 | #project.workspace.path=D:/home/record 17 | project.workspace.path=D:/home/workspace/runtime-log 18 | #project.workspace.path=D:/home/electronic-seal-servlet 19 | 20 | guodun.security.client.http.addr=http://192.168.1.232:8765 21 | guodun.security.client.http.credential=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJ1bmlmaWVkSWRlbnRpdHkiLCJpYXQiOjE3MTE2MzAzOTUsImFwcGxpY2F0aW9uSWQiOiIxNzQ5NzEwOTUwNjc0MzMzNjk2IiwiYXBwbGljYXRpb25OYW1lIjoi6IGK5Z-O6L2m566hIn0.DYWzF0e2yUzZqEPX36sy2zq0bV-VbcfGV72bQ8OrwUqcz2eoBIu36yptHM4E4GqC65cCMt4WDcb-3kDkNP0WgZOnoQnSYZOfhXuTy8V4f10bkm71KGrOjGhQ0zd6SXMSgerI8pgOXeRC_fswAqVOtmtce_UlcqOS_2Y2CsKdrxQ 22 | zuul.routes.user.path=/security/** 23 | zuul.routes.user.url=${guodun.security.client.http.addr}/security/ 24 | spring.boot.admin.client.url=http://localhost:9985 25 | spring.boot.admin.client.instance.prefer-ip=true 26 | management.endpoints.web.exposure.include=* 27 | management.endpoint.health.show-details=always 28 | info.name=dog 29 | info.sex=women 30 | aio.runtime.log.subscribe.markers=test,test1,test2 31 | aio.runtime.log.subscribe.feishu.webhook=https://open.feishu.cn/open-apis/bot/v2/hook/c91f856d-5f0f-468b-a16d-efc899dce88a 32 | -------------------------------------------------------------------------------- /console/mock/user.js: -------------------------------------------------------------------------------- 1 | 2 | const tokens = { 3 | admin: { 4 | token: 'admin-token' 5 | }, 6 | editor: { 7 | token: 'editor-token' 8 | } 9 | } 10 | 11 | const users = { 12 | 'admin-token': { 13 | roles: ['admin'], 14 | introduction: 'I am a super administrator', 15 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', 16 | name: 'Super Admin' 17 | }, 18 | 'editor-token': { 19 | roles: ['editor'], 20 | introduction: 'I am an editor', 21 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', 22 | name: 'Normal Editor' 23 | } 24 | } 25 | 26 | module.exports = [ 27 | // user login 28 | { 29 | url: '/vue-admin-template/user/login', 30 | type: 'post', 31 | response: config => { 32 | const { username } = config.body 33 | const token = tokens[username] 34 | 35 | // mock error 36 | if (!token) { 37 | return { 38 | code: 60204, 39 | message: 'Account and password are incorrect.' 40 | } 41 | } 42 | 43 | return { 44 | code: 20000, 45 | data: token 46 | } 47 | } 48 | }, 49 | 50 | // get user info 51 | { 52 | url: '/vue-admin-template/user/info\.*', 53 | type: 'get', 54 | response: config => { 55 | const { token } = config.query 56 | const info = users[token] 57 | 58 | // mock error 59 | if (!info) { 60 | return { 61 | code: 50008, 62 | message: 'Login failed, unable to get user details.' 63 | } 64 | } 65 | 66 | return { 67 | code: 20000, 68 | data: info 69 | } 70 | } 71 | }, 72 | 73 | // user logout 74 | { 75 | url: '/vue-admin-template/user/logout', 76 | type: 'post', 77 | response: _ => { 78 | return { 79 | code: 20000, 80 | data: 'success' 81 | } 82 | } 83 | } 84 | ] 85 | -------------------------------------------------------------------------------- /console/src/permission.js: -------------------------------------------------------------------------------- 1 | import router from './router' 2 | import store from './store' 3 | import { Message } from 'element-ui' 4 | import NProgress from 'nprogress' // progress bar 5 | import 'nprogress/nprogress.css' // progress bar style 6 | import { getToken } from '@/utils/auth' // get token from cookie 7 | import getPageTitle from '@/utils/get-page-title' 8 | 9 | NProgress.configure({ showSpinner: false }) // NProgress Configuration 10 | 11 | const whiteList = ['/login'] // no redirect whitelist 12 | 13 | router.beforeEach(async(to, from, next) => { 14 | // start progress bar 15 | NProgress.start() 16 | 17 | // set page title 18 | document.title = getPageTitle(to.meta.title) 19 | 20 | // determine whether the user has logged in 21 | const hasToken = getToken() 22 | 23 | if (hasToken) { 24 | if (to.path === '/login') { 25 | // if is logged in, redirect to the home page 26 | next({ path: '/' }) 27 | NProgress.done() 28 | } else { 29 | const hasGetUserInfo = store.getters.name 30 | if (hasGetUserInfo) { 31 | next() 32 | } else { 33 | try { 34 | // get user info 35 | await store.dispatch('user/getInfo') 36 | 37 | next() 38 | } catch (error) { 39 | // remove token and go to login page to re-login 40 | await store.dispatch('user/resetToken') 41 | Message.error(error || 'Has Error') 42 | next(`/login?redirect=${to.path}`) 43 | NProgress.done() 44 | } 45 | } 46 | } 47 | } else { 48 | /* has no token*/ 49 | 50 | if (whiteList.indexOf(to.path) !== -1) { 51 | // in the free login whitelist, go directly 52 | next() 53 | } else { 54 | // other pages that do not have permission to access are redirected to the login page. 55 | next(`/login?redirect=${to.fullPath}`) 56 | NProgress.done() 57 | } 58 | } 59 | }) 60 | 61 | router.afterEach(() => { 62 | // finish progress bar 63 | NProgress.done() 64 | }) 65 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/log/append/AioLogLiteAppender.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.log.append; 2 | 3 | import ch.qos.logback.classic.spi.ILoggingEvent; 4 | import ch.qos.logback.core.UnsynchronizedAppenderBase; 5 | import cn.hutool.core.util.IdUtil; 6 | import cn.hutool.core.util.ObjectUtil; 7 | import com.aio.runtime.log.domain.AioLogBo; 8 | import com.aio.runtime.log.save.LogSaveCache; 9 | import cn.aio1024.framework.basic.domain.trace.TraceId; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.slf4j.MDC; 13 | 14 | import java.util.Map; 15 | 16 | /** 17 | * @author lzm 18 | * @desc 订阅错误日志 19 | * @date 2024/07/22 20 | */ 21 | @Slf4j 22 | public class AioLogLiteAppender extends UnsynchronizedAppenderBase { 23 | @Override 24 | protected void append(ILoggingEvent event) { 25 | 26 | Map mdcPropertyMap = event.getMDCPropertyMap(); 27 | AioLogBo logBo = new AioLogBo(); 28 | logBo.setMdc(mdcPropertyMap); 29 | logBo.setMessage(event.getFormattedMessage()); 30 | 31 | if (ObjectUtil.isNotEmpty(event.getCallerData())){ 32 | StackTraceElement source = event.getCallerData()[0]; 33 | logBo.setMethodName(source.getMethodName()); 34 | logBo.setClassName(source.getClassName()); 35 | } 36 | 37 | logBo.setId(IdUtil.getSnowflakeNextIdStr()); 38 | logBo.setCreateTime(event.getTimeStamp()); 39 | logBo.setThreadName(event.getThreadName()); 40 | logBo.setLevel(event.getLevel().levelStr); 41 | 42 | if (StringUtils.isBlank(TraceId.getTraceId())){ 43 | String traceId = MDC.get("traceId"); 44 | if (StringUtils.isNotBlank(traceId)){ 45 | TraceId.setTraceId(traceId); 46 | } 47 | } 48 | 49 | logBo.setTraceId(TraceId.getTraceId()); 50 | 51 | if (ObjectUtil.isNotEmpty(event.getMarker())){ 52 | logBo.setMarker(event.getMarker().getName()); 53 | } 54 | LogSaveCache.addLog(logBo); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /console/src/layout/components/Sidebar/Logo.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 33 | 34 | 83 | -------------------------------------------------------------------------------- /runtime-record-servlet/src/main/java/com/guodun/aio/document/controller/TestCacheManageController.java: -------------------------------------------------------------------------------- 1 | package com.guodun.aio.document.controller; 2 | 3 | import com.guodun.aio.document.domain.TestCacheConstants; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.cache.annotation.CacheEvict; 6 | import org.springframework.cache.annotation.CachePut; 7 | import org.springframework.cache.annotation.Cacheable; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | /** 11 | * @author lzm 12 | * @desc 测试创建日志 13 | * @date 2024/08/09 14 | */ 15 | @RestController 16 | @Slf4j 17 | @RequestMapping("/test/cache") 18 | public class TestCacheManageController { 19 | @Cacheable(cacheNames = TestCacheConstants.FORM_FIELD_MAP,key = "#id",cacheManager = TestCacheConstants.FORM_FIELD_MAP) 20 | @GetMapping("cache1") 21 | public String getCache1(@RequestParam String id){ 22 | log.info("查询一个Cache : {} ",id); 23 | return id; 24 | } 25 | 26 | @Cacheable(cacheNames = "testCache2",key = "#id",cacheManager = TestCacheConstants.FORM_FIELD_MAP) 27 | @GetMapping("cache2") 28 | public String getCache2(@RequestParam String id){ 29 | log.info("查询一个Cache2 : {} ",id); 30 | return id; 31 | } 32 | 33 | @Cacheable(cacheNames = "cache_name_3",key = "#id",cacheManager = TestCacheConstants.FORM_FIELD_MAP) 34 | @GetMapping("cache3") 35 | public String getCache3(@RequestParam String id){ 36 | log.info("查询一个Cache3 : {} ",id); 37 | return id; 38 | } 39 | 40 | @CachePut(cacheNames = TestCacheConstants.FORM_FIELD_MAP,key = "#id",cacheManager = TestCacheConstants.FORM_FIELD_MAP) 41 | @PutMapping("cache1") 42 | public String saveCache1(@RequestParam String id){ 43 | log.info("新增一个Cache : {} ",id); 44 | return id; 45 | } 46 | 47 | 48 | @CacheEvict(value = TestCacheConstants.FORM_FIELD_MAP,cacheManager = TestCacheConstants.FORM_FIELD_MAP,key = "#id") 49 | @DeleteMapping("cache1") 50 | public String deleteCache1(@RequestParam String id){ 51 | log.info("这是删除缓存 : {} ",id); 52 | return id; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /console/src/icons/svg/config.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/java/com/aio/runtime/reported/service/impl/AbstractErrorReportedServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.aio.runtime.reported.service.impl; 2 | 3 | import cn.hutool.core.convert.Convert; 4 | import cn.hutool.core.util.IdUtil; 5 | import cn.hutool.core.util.ObjectUtil; 6 | import com.aio.runtime.reported.domain.dao.ErrorReportDo; 7 | import com.aio.runtime.reported.domain.params.AddErrorParams; 8 | import com.aio.runtime.reported.service.ErrorReportedService; 9 | import org.springframework.scheduling.annotation.Scheduled; 10 | 11 | import java.util.ArrayList; 12 | import java.util.Date; 13 | import java.util.List; 14 | import java.util.concurrent.BlockingQueue; 15 | import java.util.concurrent.LinkedBlockingQueue; 16 | 17 | /** 18 | * @author lzm 19 | * @desc 抽象类 20 | * @date 2024/10/26 21 | */ 22 | public abstract class AbstractErrorReportedServiceImpl implements ErrorReportedService { 23 | public static BlockingQueue ERROR_REPORTED_QUEUE = new LinkedBlockingQueue<>(2000); 24 | 25 | @Override 26 | public void addError(AddErrorParams params){ 27 | if (ObjectUtil.isNull(params)){ 28 | return; 29 | } 30 | if (ERROR_REPORTED_QUEUE.size() >= 1990){ 31 | drainTo(); 32 | batchSaveError(drainTo()); 33 | } 34 | ErrorReportDo reportDo = Convert.convert(ErrorReportDo.class,params); 35 | reportDo.setCreateTime(new Date()); 36 | reportDo.setId(IdUtil.getSnowflakeNextIdStr()); 37 | ERROR_REPORTED_QUEUE.add(reportDo); 38 | 39 | } 40 | @Scheduled(cron = "0/10 * * * * ? ") 41 | private void batchBatchSaveErrorTask(){ 42 | List errorReportDos = drainTo(); 43 | if (ObjectUtil.isEmpty(errorReportDos)){ 44 | return; 45 | } 46 | batchSaveError(errorReportDos); 47 | } 48 | public static List drainTo() { 49 | List records = new ArrayList<>(); 50 | ERROR_REPORTED_QUEUE.drainTo(records); 51 | return records; 52 | } 53 | public abstract void batchSaveError(List recordList); 54 | } 55 | -------------------------------------------------------------------------------- /runtime-record-core/src/main/resources/chart/ThreadChartLine.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAxis": { 3 | "data": [], 4 | "boundaryGap": false, 5 | "axisTick": { 6 | "show": false 7 | } 8 | }, 9 | "grid": { 10 | "left": 10, 11 | "right": 10, 12 | "bottom": 20, 13 | "top": 30, 14 | "containLabel": true 15 | }, 16 | "tooltip": { 17 | "trigger": "axis", 18 | "axisPointer": { 19 | "type": "cross" 20 | }, 21 | "padding": [ 22 | 5, 23 | 10 24 | ] 25 | }, 26 | "yAxis": { 27 | "axisTick": { 28 | "show": false 29 | } 30 | }, 31 | "legend": { 32 | "data": [ 33 | "守护线程数量", 34 | "线程顶峰数量", 35 | "活跃线程" 36 | ] 37 | }, 38 | "series": [ 39 | { 40 | "name": "守护线程数量", 41 | "itemStyle": { 42 | "normal": { 43 | "color": "#009688", 44 | "lineStyle": { 45 | "color": "#009688", 46 | "width": 2 47 | } 48 | } 49 | }, 50 | "smooth": true, 51 | "type": "line", 52 | "data": [], 53 | "animationDuration": 2800, 54 | "animationEasing": "cubicInOut" 55 | }, 56 | { 57 | "name": "线程顶峰数量", 58 | "smooth": true, 59 | "type": "line", 60 | "itemStyle": { 61 | "normal": { 62 | "color": "#FF5722", 63 | "lineStyle": { 64 | "color": "#FF5722", 65 | "width": 2 66 | }, 67 | "areaStyle": { 68 | "color": "#f3f8ff" 69 | } 70 | } 71 | }, 72 | "data": [], 73 | "animationDuration": 2800, 74 | "animationEasing": "quadraticOut" 75 | }, 76 | { 77 | "name": "活跃线程", 78 | "smooth": true, 79 | "type": "line", 80 | "itemStyle": { 81 | "normal": { 82 | "color": "#3888fa", 83 | "lineStyle": { 84 | "color": "#3888fa", 85 | "width": 2 86 | }, 87 | "areaStyle": { 88 | "color": "#f3f8ff" 89 | } 90 | } 91 | }, 92 | "data": [], 93 | "animationDuration": 2800, 94 | "animationEasing": "quadraticOut" 95 | } 96 | ] 97 | } 98 | -------------------------------------------------------------------------------- /console/src/components/GDJsonEditor/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | 61 | 62 | 83 | -------------------------------------------------------------------------------- /console/src/components/Breadcrumb/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 64 | 65 | 78 | -------------------------------------------------------------------------------- /console/src/icons/svg/dashboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /console/src/layout/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 52 | 53 | 94 | -------------------------------------------------------------------------------- /console/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-admin-template", 3 | "version": "4.4.0", 4 | "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint", 5 | "author": "Pan ", 6 | "scripts": { 7 | "dev": "vue-cli-service serve", 8 | "build:prod": "vue-cli-service build --mode production", 9 | "build:stage": "vue-cli-service build --mode staging", 10 | "preview": "node build/index.js --preview", 11 | "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", 12 | "lint": "eslint --ext .js,.vue src", 13 | "test:unit": "jest --clearCache && vue-cli-service test:unit", 14 | "test:ci": "npm run lint && npm run test:unit" 15 | }, 16 | "dependencies": { 17 | "axios": "0.18.1", 18 | "codemirror": "^5.65.13", 19 | "core-js": "3.6.5", 20 | "echarts": "^5.5.1", 21 | "element-ui": "2.15.14", 22 | "highlight.js": "^11.7.0", 23 | "js-cookie": "2.2.0", 24 | "jsonlint": "^1.6.3", 25 | "mavon-editor": "^2.10.4", 26 | "normalize.css": "7.0.0", 27 | "nprogress": "0.2.0", 28 | "path-to-regexp": "2.4.0", 29 | "script-loader": "^0.7.2", 30 | "vue": "2.6.10", 31 | "vue-json-viewer": "^2.2.22", 32 | "vue-router": "3.0.6", 33 | "vuex": "3.1.0" 34 | }, 35 | "devDependencies": { 36 | "@vue/cli-plugin-babel": "4.4.4", 37 | "@vue/cli-plugin-eslint": "4.4.4", 38 | "@vue/cli-plugin-unit-jest": "4.4.4", 39 | "@vue/cli-service": "4.4.4", 40 | "@vue/test-utils": "1.0.0-beta.29", 41 | "autoprefixer": "9.5.1", 42 | "babel-eslint": "10.1.0", 43 | "babel-jest": "23.6.0", 44 | "babel-plugin-dynamic-import-node": "2.3.3", 45 | "chalk": "2.4.2", 46 | "connect": "3.6.6", 47 | "eslint": "6.7.2", 48 | "eslint-plugin-vue": "6.2.2", 49 | "html-webpack-plugin": "3.2.0", 50 | "mockjs": "1.0.1-beta3", 51 | "runjs": "4.3.2", 52 | "sass": "1.26.8", 53 | "sass-loader": "8.0.2", 54 | "script-ext-html-webpack-plugin": "2.1.3", 55 | "serve-static": "1.13.2", 56 | "svg-sprite-loader": "4.1.3", 57 | "svgo": "1.2.2", 58 | "vue-template-compiler": "2.6.10" 59 | }, 60 | "browserslist": [ 61 | "> 1%", 62 | "last 2 versions" 63 | ], 64 | "engines": { 65 | "node": ">=8.9", 66 | "npm": ">= 3.0.0" 67 | }, 68 | "license": "MIT" 69 | } 70 | --------------------------------------------------------------------------------