diff --git a/README.md b/README.md
index ff4b49e2..c424e7c6 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,6 @@ JetLinks 是一个物联网基础平台,用于快速建立物联网相关业务
| 线下技术支持 | ⭕ | ⭕ | ✅ |
| 定制开发 | ⭕ | ⭕ | ✅ |
| 商业限制 | 无 | 单个项目 | 无 |
-| 定价 | 免费 | 孵化中待定 | 孵化中待定 |
+| 定价 | 免费 | 联系我们 | 联系我们 |
⚠️:所有版本均不可发布为与JetLinks同类的产品进行二次销售.
\ No newline at end of file
diff --git a/jetlinks-components/logging-component/pom.xml b/jetlinks-components/logging-component/pom.xml
new file mode 100644
index 00000000..a3e6cc7d
--- /dev/null
+++ b/jetlinks-components/logging-component/pom.xml
@@ -0,0 +1,34 @@
+
+
+
+ jetlinks-components
+ org.jetlinks.community
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+ 4.0.0
+
+ logging-component
+
+
+
+
+ org.hswebframework.web
+ hsweb-access-logging-aop
+ ${hsweb.framework.version}
+
+
+
+ org.jetlinks.community
+ elasticsearch-component
+ ${project.version}
+
+
+
+ ch.qos.logback
+ logback-classic
+
+
+
\ No newline at end of file
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/access/AccessLoggingTranslator.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/access/AccessLoggingTranslator.java
new file mode 100644
index 00000000..39a7406d
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/access/AccessLoggingTranslator.java
@@ -0,0 +1,26 @@
+package org.jetlinks.community.logging.access;
+
+import org.hswebframework.web.logging.events.AccessLoggerAfterEvent;
+import org.jetlinks.community.logging.configuration.LoggingProperties;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AccessLoggingTranslator {
+
+ private final ApplicationEventPublisher eventPublisher;
+
+ private final LoggingProperties properties;
+
+ public AccessLoggingTranslator(ApplicationEventPublisher eventPublisher, LoggingProperties properties) {
+ this.eventPublisher = eventPublisher;
+ this.properties = properties;
+ }
+
+ @EventListener
+ public void translate(AccessLoggerAfterEvent event) {
+ eventPublisher.publishEvent(SerializableAccessLog.of(event.getLogger()));
+ }
+
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/access/SerializableAccessLog.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/access/SerializableAccessLog.java
new file mode 100644
index 00000000..17768585
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/access/SerializableAccessLog.java
@@ -0,0 +1,124 @@
+package org.jetlinks.community.logging.access;
+
+import com.alibaba.fastjson.JSON;
+import lombok.Getter;
+import lombok.Setter;
+import org.hswebframework.utils.StringUtils;
+import org.hswebframework.web.bean.FastBeanCopier;
+import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.logging.AccessLoggerInfo;
+import org.springframework.http.codec.multipart.FilePart;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @see org.hswebframework.web.logging.AccessLoggerInfo
+ */
+@Setter
+@Getter
+public class SerializableAccessLog implements Serializable {
+
+ /**
+ * 日志id
+ */
+ private String id;
+
+ /**
+ * 访问的操作
+ *
+ * @see AccessLogger#value()
+ */
+ private String action;
+
+ /**
+ * 描述
+ *
+ * @see AccessLogger#describe()
+ */
+ private String describe;
+
+ /**
+ * 访问对应的java方法
+ */
+ private String method;
+
+ /**
+ * 访问对应的java类
+ */
+ private String target;
+
+ /**
+ * 请求的参数,参数为java方法的参数而不是http参数,key为参数名,value为参数值.
+ */
+ private Map parameters;
+
+ /**
+ * 请求者ip地址
+ */
+ private String ip;
+
+ /**
+ * 请求的url地址
+ */
+ private String url;
+
+ /**
+ * http 请求头集合
+ */
+ private Map httpHeaders = new HashMap<>();
+
+ private Map context = new HashMap<>();
+
+ /**
+ * http 请求方法, GET,POST...
+ */
+ private String httpMethod;
+
+ /**
+ * 响应结果,方法的返回值
+ */
+ //private Object response;
+
+ /**
+ * 请求时间戳
+ *
+ * @see System#currentTimeMillis()
+ */
+ private long requestTime;
+
+ /**
+ * 响应时间戳
+ *
+ * @see System#currentTimeMillis()
+ */
+ private long responseTime;
+
+ /**
+ * 异常信息,请求对应方法抛出的异常
+ */
+ private String exception;
+
+ public static SerializableAccessLog of(AccessLoggerInfo info) {
+ SerializableAccessLog accessLog = FastBeanCopier.copy(info, new SerializableAccessLog(), "parameters", "method", "target", "exception");
+ accessLog.setMethod(info.getMethod().getName());
+ accessLog.setTarget(info.getTarget().getName());
+ accessLog.setException(info.getException() == null ? ""
+ : StringUtils.throwable2String(info.getException()));
+ Map newParameter = info.getParameters()
+ .entrySet()
+ .stream()
+ .collect(Collectors.toMap(Map.Entry::getKey, e -> {
+ Object value = e.getValue();
+ if (value instanceof FilePart) {
+ return ("file:") + ((FilePart) value).filename();
+ }
+ return JSON.toJSONString(value);
+ }));
+
+ accessLog.setParameters(newParameter);
+ return accessLog;
+ }
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/configuration/LoggingConfiguration.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/configuration/LoggingConfiguration.java
new file mode 100644
index 00000000..15951a80
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/configuration/LoggingConfiguration.java
@@ -0,0 +1,35 @@
+package org.jetlinks.community.logging.configuration;
+
+import lombok.extern.slf4j.Slf4j;
+import org.elasticsearch.client.indices.CreateIndexRequest;
+import org.jetlinks.community.elastic.search.enums.FieldDateFormat;
+import org.jetlinks.community.elastic.search.enums.FieldType;
+import org.jetlinks.community.elastic.search.index.CreateIndex;
+import org.jetlinks.community.elastic.search.service.IndexOperationService;
+import org.jetlinks.community.logging.event.handler.LoggerIndexProvider;
+import org.jetlinks.community.logging.logback.SystemLoggingAppender;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.bind.annotation.PostMapping;
+
+@Configuration
+@EnableConfigurationProperties(LoggingProperties.class)
+@Slf4j
+public class LoggingConfiguration implements ApplicationEventPublisherAware {
+
+
+ private final LoggingProperties properties;
+
+ public LoggingConfiguration(LoggingProperties properties) {
+ this.properties = properties;
+ SystemLoggingAppender.staticContext.putAll(properties.getSystem().getContext());
+ }
+
+ @Override
+ public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
+ SystemLoggingAppender.publisher = applicationEventPublisher;
+ }
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/configuration/LoggingProperties.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/configuration/LoggingProperties.java
new file mode 100644
index 00000000..2bc4bc8c
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/configuration/LoggingProperties.java
@@ -0,0 +1,60 @@
+package org.jetlinks.community.logging.configuration;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.jetlinks.community.logging.system.SerializableSystemLog;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.*;
+
+@ConfigurationProperties(prefix = "jetlinks.logging")
+@Getter
+@Setter
+public class LoggingProperties {
+
+ /**
+ * 系统日志
+ *
+ * @see lombok.extern.slf4j.Slf4j
+ * @see org.slf4j.Logger
+ * @see org.jetlinks.community.logging.logback.SystemLoggingAppender
+ * @see SerializableSystemLog
+ * @see org.jetlinks.community.logging.event.SystemLoggingEvent
+ */
+ @Getter
+ @Setter
+ private SystemLoggingProperties system = new SystemLoggingProperties();
+
+ /**
+ * 访问日志
+ *
+ * @see org.hswebframework.web.logging.AccessLogger
+ * @see org.hswebframework.web.loggin.aop.EnableAccessLogger
+ * @see org.jetlinks.community.logging.event.AccessLoggingEvent
+ * @see org.jetlinks.community.logging.access.SerializableAccessLog
+ */
+ @Setter
+ @Getter
+ private AccessLoggingProperties access = new AccessLoggingProperties();
+
+ @Getter
+ @Setter
+ public static class SystemLoggingProperties {
+ /**
+ * 系统日志上下文,通常用于在日志中标识当前服务等
+ *
+ * @see org.hswebframework.web.logger.ReactiveLogger#mdc(String, String)
+ * @see org.slf4j.MDC
+ */
+ private Map context = new HashMap<>();
+
+ }
+
+ @Getter
+ @Setter
+ public static class AccessLoggingProperties {
+ //指定按path过滤日志
+ private List pathExcludes = new ArrayList<>();
+ }
+
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/AccessLoggingEvent.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/AccessLoggingEvent.java
new file mode 100644
index 00000000..3f74f41d
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/AccessLoggingEvent.java
@@ -0,0 +1,13 @@
+package org.jetlinks.community.logging.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetlinks.community.logging.access.SerializableAccessLog;
+
+@Getter
+@Setter
+@AllArgsConstructor
+public class AccessLoggingEvent {
+ SerializableAccessLog log;
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/SystemLoggingEvent.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/SystemLoggingEvent.java
new file mode 100644
index 00000000..2e600f8e
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/SystemLoggingEvent.java
@@ -0,0 +1,13 @@
+package org.jetlinks.community.logging.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetlinks.community.logging.system.SerializableSystemLog;
+
+@Getter
+@Setter
+@AllArgsConstructor
+public class SystemLoggingEvent {
+ SerializableSystemLog log;
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/AccessLoggerEventHandler.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/AccessLoggerEventHandler.java
new file mode 100644
index 00000000..72bd9891
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/AccessLoggerEventHandler.java
@@ -0,0 +1,53 @@
+package org.jetlinks.community.logging.event.handler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.elasticsearch.client.indices.CreateIndexRequest;
+import org.jetlinks.community.elastic.search.enums.FieldDateFormat;
+import org.jetlinks.community.elastic.search.enums.FieldType;
+import org.jetlinks.community.elastic.search.index.CreateIndex;
+import org.jetlinks.community.elastic.search.service.ElasticSearchService;
+import org.jetlinks.community.elastic.search.service.IndexOperationService;
+import org.jetlinks.community.logging.access.SerializableAccessLog;
+import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author bsetfeng
+ * @since 1.0
+ **/
+@Component
+@Slf4j
+@Order(5)
+public class AccessLoggerEventHandler {
+
+ private final ElasticSearchService elasticSearchService;
+
+ public AccessLoggerEventHandler(ElasticSearchService elasticSearchService, IndexOperationService indexOperationService) {
+ this.elasticSearchService = elasticSearchService;
+ CreateIndexRequest accessLoggerIndex = CreateIndex.createInstance()
+ .addIndex(LoggerIndexProvider.ACCESS.getStandardIndex())
+ .createMapping()
+ .addFieldName("requestTime").addFieldType(FieldType.DATE).addFieldDateFormat(FieldDateFormat.epoch_millis, FieldDateFormat.simple_date, FieldDateFormat.strict_date_time).commit()
+ .addFieldName("responseTime").addFieldType(FieldType.DATE).addFieldDateFormat(FieldDateFormat.epoch_millis, FieldDateFormat.simple_date, FieldDateFormat.strict_date_time).commit()
+ .addFieldName("action").addFieldType(FieldType.KEYWORD).commit()
+ .addFieldName("ip").addFieldType(FieldType.KEYWORD).commit()
+ .addFieldName("url").addFieldType(FieldType.KEYWORD).commit()
+ .addFieldName("httpHeaders").addFieldType(FieldType.OBJECT).commit()
+ .addFieldName("context").addFieldType(FieldType.OBJECT).commit()
+ .end()
+ .createIndexRequest();
+ indexOperationService.init(accessLoggerIndex)
+ .doOnError(err -> log.error(err.getMessage(), err))
+ .subscribe();
+ }
+
+
+ @EventListener
+ public void acceptAccessLoggerInfo(SerializableAccessLog info) {
+ elasticSearchService.commit(LoggerIndexProvider.ACCESS, Mono.just(info)).subscribe();
+ }
+
+
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/LoggerIndexProvider.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/LoggerIndexProvider.java
new file mode 100644
index 00000000..9e27a152
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/LoggerIndexProvider.java
@@ -0,0 +1,21 @@
+package org.jetlinks.community.logging.event.handler;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.jetlinks.community.elastic.search.index.ElasticIndex;
+
+/**
+ * @author bsetfeng
+ * @since 1.0
+ **/
+@Getter
+@AllArgsConstructor
+public enum LoggerIndexProvider implements ElasticIndex {
+
+ ACCESS("access_log", "_doc"),
+ SYSTEM("system_log", "_doc");
+
+ private String index;
+
+ private String type;
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/SystemLoggerEventHandler.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/SystemLoggerEventHandler.java
new file mode 100644
index 00000000..73aea0bf
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/event/handler/SystemLoggerEventHandler.java
@@ -0,0 +1,52 @@
+package org.jetlinks.community.logging.event.handler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.elasticsearch.client.indices.CreateIndexRequest;
+import org.jetlinks.community.elastic.search.enums.FieldDateFormat;
+import org.jetlinks.community.elastic.search.enums.FieldType;
+import org.jetlinks.community.elastic.search.index.CreateIndex;
+import org.jetlinks.community.elastic.search.service.ElasticSearchService;
+import org.jetlinks.community.elastic.search.service.IndexOperationService;
+import org.jetlinks.community.logging.system.SerializableSystemLog;
+import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author bsetfeng
+ * @since 1.0
+ **/
+@Component
+@Slf4j
+@Order(5)
+public class SystemLoggerEventHandler {
+
+
+ private final ElasticSearchService elasticSearchService;
+
+ public SystemLoggerEventHandler(ElasticSearchService elasticSearchService, IndexOperationService indexOperationService) {
+ this.elasticSearchService = elasticSearchService;
+
+ CreateIndexRequest systemLoggerIndex = CreateIndex.createInstance()
+ .addIndex(LoggerIndexProvider.SYSTEM.getStandardIndex())
+ .createMapping()
+ .addFieldName("createTime").addFieldType(FieldType.DATE).addFieldDateFormat(FieldDateFormat.epoch_millis, FieldDateFormat.simple_date, FieldDateFormat.strict_date_time).commit()
+ .addFieldName("name").addFieldType(FieldType.KEYWORD).commit()
+ .addFieldName("level").addFieldType(FieldType.KEYWORD).commit()
+ .addFieldName("message").addFieldType(FieldType.KEYWORD).commit()
+ .end()
+ .createIndexRequest();
+
+ indexOperationService.init(systemLoggerIndex)
+ .doOnError(err -> log.error(err.getMessage(), err))
+ .subscribe();
+ }
+
+ @EventListener
+ public void acceptAccessLoggerInfo(SerializableSystemLog info) {
+ elasticSearchService.commit(LoggerIndexProvider.SYSTEM, Mono.just(info))
+ .subscribe();
+ }
+
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/logback/SystemLoggingAppender.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/logback/SystemLoggingAppender.java
new file mode 100644
index 00000000..91c4185c
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/logback/SystemLoggingAppender.java
@@ -0,0 +1,108 @@
+package org.jetlinks.community.logging.logback;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.classic.spi.IThrowableProxy;
+import ch.qos.logback.classic.spi.StackTraceElementProxy;
+import ch.qos.logback.classic.spi.ThrowableProxyUtil;
+import ch.qos.logback.core.CoreConstants;
+import ch.qos.logback.core.UnsynchronizedAppenderBase;
+import lombok.extern.slf4j.Slf4j;
+import org.hswebframework.web.id.IDGenerator;
+import org.hswebframework.web.utils.ModuleUtils;
+import org.jetlinks.community.logging.system.SerializableSystemLog;
+import org.slf4j.MDC;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringJoiner;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+public class SystemLoggingAppender extends UnsynchronizedAppenderBase {
+
+ public static ApplicationEventPublisher publisher;
+
+ public static final Map staticContext = new ConcurrentHashMap<>();
+
+ @Override
+ protected void append(ILoggingEvent event) {
+
+ if (publisher == null) {
+ return;
+ }
+
+ StackTraceElement element = event.getCallerData()[0];
+ IThrowableProxy proxies = event.getThrowableProxy();
+ String message = event.getFormattedMessage();
+ String stack = null;
+ if (null != proxies) {
+ int commonFrames = proxies.getCommonFrames();
+ StackTraceElementProxy[] stepArray = proxies.getStackTraceElementProxyArray();
+ StringJoiner joiner = new StringJoiner("\n", message + "\n[", "]");
+ StringBuilder stringBuilder = new StringBuilder();
+ ThrowableProxyUtil.subjoinFirstLine(stringBuilder, proxies);
+ joiner.add(stringBuilder);
+ for (int i = 0; i < stepArray.length - commonFrames; i++) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(CoreConstants.TAB);
+ ThrowableProxyUtil.subjoinSTEP(sb, stepArray[i]);
+ joiner.add(sb);
+ }
+ stack = joiner.toString();
+ }
+
+
+ try {
+ String gitLocation = null;
+ String mavenModule = null;
+ try {
+ Class clazz = Class.forName(element.getClassName());
+ ModuleUtils.ModuleInfo moduleInfo = ModuleUtils.getModuleByClass(clazz);
+ if (!StringUtils.isEmpty(moduleInfo.getGitRepository())) {
+ StringBuilder javaSb = new StringBuilder();
+ javaSb.append(moduleInfo.getGitLocation());
+ javaSb.append("src/main/java/");
+ javaSb.append((ClassUtils.getPackageName(Class.forName(element.getClassName())).replace(".", "/")));
+ javaSb.append("/");
+ javaSb.append(Class.forName(element.getClassName()).getSimpleName());
+ javaSb.append(".java#L");
+ javaSb.append(element.getLineNumber());
+ gitLocation = javaSb.toString();
+ }
+ mavenModule = moduleInfo.getArtifactId();
+ } catch (Exception e) {
+ log.warn("记录系统日志时,加载类:{}错误。{}", element.getClassName(), e);
+ }
+ Map context = new HashMap<>(staticContext);
+ Map mdc = MDC.getCopyOfContextMap();
+ if (mdc != null) {
+ context.putAll(mdc);
+ }
+ SerializableSystemLog info = SerializableSystemLog.builder()
+ .id(IDGenerator.SNOW_FLAKE_STRING.generate())
+ .mavenModule(mavenModule)
+ .context(context)
+ .name(event.getLoggerName())
+ .level(event.getLevel().levelStr)
+ .className(element.getClassName())
+ .methodName(element.getMethodName())
+ .lineNumber(element.getLineNumber())
+ .exceptionStack(stack)
+ .java(gitLocation)
+ .threadName(event.getThreadName())
+ .createTime(event.getTimeStamp())
+ .message(message)
+ .threadId(String.valueOf(Thread.currentThread().getId()))
+ .build();
+ try {
+ publisher.publishEvent(info);
+ }catch (Exception ignore){}
+ } catch (Exception e) {
+ log.error("组装系统日志错误", e);
+ }
+
+ }
+}
diff --git a/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/system/SerializableSystemLog.java b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/system/SerializableSystemLog.java
new file mode 100644
index 00000000..2366a9f2
--- /dev/null
+++ b/jetlinks-components/logging-component/src/main/java/org/jetlinks/community/logging/system/SerializableSystemLog.java
@@ -0,0 +1,42 @@
+package org.jetlinks.community.logging.system;
+
+import lombok.*;
+
+import java.io.Serializable;
+import java.util.Map;
+
+@Builder
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class SerializableSystemLog implements Serializable {
+
+ private String id;
+
+ private String mavenModule;
+
+ private String name;
+
+ private String threadName;
+
+ private String level;
+
+ private String className;
+
+ private String methodName;
+
+ private int lineNumber;
+
+ private String java;
+
+ private String message;
+
+ private String exceptionStack;
+
+ private Long createTime;
+
+ private String threadId;
+
+ private Map context;
+}
diff --git a/jetlinks-components/pom.xml b/jetlinks-components/pom.xml
index eaff3fae..7ab4a349 100644
--- a/jetlinks-components/pom.xml
+++ b/jetlinks-components/pom.xml
@@ -20,6 +20,7 @@
dashboard-component
common-component
notify-component
+ logging-component
jetlinks-components
diff --git a/jetlinks-manager/logging-manager/.gitignore b/jetlinks-manager/logging-manager/.gitignore
new file mode 100644
index 00000000..c08f8301
--- /dev/null
+++ b/jetlinks-manager/logging-manager/.gitignore
@@ -0,0 +1,29 @@
+**/pom.xml.versionsBackup
+**/target/
+**/out/
+*.class
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+.idea/
+/nbproject
+*.ipr
+*.iws
+*.iml
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.log
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+**/transaction-logs/
+!/.mvn/wrapper/maven-wrapper.jar
+/data/
+*.db
+/static/
+/upload
+/ui/upload/
+docker/data
+!ip2region.db
+!device-simulator.jar
\ No newline at end of file
diff --git a/jetlinks-manager/logging-manager/pom.xml b/jetlinks-manager/logging-manager/pom.xml
new file mode 100644
index 00000000..00e1195d
--- /dev/null
+++ b/jetlinks-manager/logging-manager/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+
+ org.jetlinks.community
+ jetlinks-manager
+ 1.0-SNAPSHOT
+
+ logging-manager
+
+
+
+ 4.0.0-SNAPSHOT
+
+
+
+
+
+ org.hswebframework.web
+ hsweb-access-logging-aop
+ ${hsweb.framework.version}
+
+
+
+ org.hswebframework.web
+ hsweb-starter
+ ${hsweb.framework.version}
+
+
+
+ org.springframework.boot.experimental
+ spring-boot-starter-data-r2dbc
+
+
+
+ org.jetlinks.community
+ logging-component
+ ${project.version}
+
+
+
+ io.r2dbc
+ r2dbc-h2
+
+
+
+ org.hswebframework
+ hsweb-easy-orm-rdb
+
+
+
+
+
+
+
diff --git a/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/controller/AccessLoggerController.java b/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/controller/AccessLoggerController.java
new file mode 100644
index 00000000..24cbf5db
--- /dev/null
+++ b/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/controller/AccessLoggerController.java
@@ -0,0 +1,35 @@
+package org.jetlinks.community.logging.controller;
+
+import org.hswebframework.ezorm.core.param.QueryParam;
+import org.hswebframework.web.api.crud.entity.PagerResult;
+import org.hswebframework.web.authorization.annotation.QueryAction;
+import org.hswebframework.web.authorization.annotation.Resource;
+import org.jetlinks.community.logging.access.SerializableAccessLog;
+import org.jetlinks.community.logging.service.AccessLoggerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author bsetfeng
+ * @since 1.0
+ **/
+@RestController
+@RequestMapping("/logger/access")
+@Resource(id="access-logger",name = "访问日志")
+public class AccessLoggerController {
+
+ @Autowired
+ private AccessLoggerService loggerService;
+
+ @GetMapping("/_query")
+ @QueryAction
+ public Mono> getAccessLogger(QueryParam queryParam) {
+ return loggerService.getAccessLogger(queryParam);
+ }
+
+
+
+}
diff --git a/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/controller/SystemLoggerController.java b/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/controller/SystemLoggerController.java
new file mode 100644
index 00000000..b4fe9a72
--- /dev/null
+++ b/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/controller/SystemLoggerController.java
@@ -0,0 +1,34 @@
+package org.jetlinks.community.logging.controller;
+
+import org.hswebframework.ezorm.core.param.QueryParam;
+import org.hswebframework.web.api.crud.entity.PagerResult;
+import org.hswebframework.web.authorization.annotation.QueryAction;
+import org.hswebframework.web.authorization.annotation.Resource;
+import org.jetlinks.community.logging.service.SystemLoggerService;
+import org.jetlinks.community.logging.system.SerializableSystemLog;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author bsetfeng
+ * @since 1.0
+ **/
+@RestController
+@RequestMapping("/logger/system")
+@Resource(id="system-logger",name = "系统日志")
+public class SystemLoggerController {
+
+ @Autowired
+ private SystemLoggerService loggerService;
+
+ @GetMapping("/_query")
+ @QueryAction
+ public Mono> getSystemLogger(QueryParam queryParam) {
+ return loggerService.getSystemLogger(queryParam);
+ }
+
+
+}
diff --git a/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/service/AccessLoggerService.java b/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/service/AccessLoggerService.java
new file mode 100644
index 00000000..7de1ae1e
--- /dev/null
+++ b/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/service/AccessLoggerService.java
@@ -0,0 +1,26 @@
+package org.jetlinks.community.logging.service;
+
+
+import org.hswebframework.ezorm.core.param.QueryParam;
+import org.hswebframework.web.api.crud.entity.PagerResult;
+import org.jetlinks.community.elastic.search.service.ElasticSearchService;
+import org.jetlinks.community.logging.access.SerializableAccessLog;
+import org.jetlinks.community.logging.event.handler.LoggerIndexProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+/**
+ * @version 1.0
+ **/
+@Service
+public class AccessLoggerService {
+
+ @Autowired
+ private ElasticSearchService searchService;
+
+ public Mono> getAccessLogger(QueryParam queryParam) {
+ return searchService.queryPager(LoggerIndexProvider.ACCESS, queryParam, SerializableAccessLog.class);
+ }
+
+}
diff --git a/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/service/SystemLoggerService.java b/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/service/SystemLoggerService.java
new file mode 100644
index 00000000..aa6b499e
--- /dev/null
+++ b/jetlinks-manager/logging-manager/src/main/java/org/jetlinks/community/logging/service/SystemLoggerService.java
@@ -0,0 +1,25 @@
+package org.jetlinks.community.logging.service;
+
+
+import org.hswebframework.ezorm.core.param.QueryParam;
+import org.hswebframework.web.api.crud.entity.PagerResult;
+import org.jetlinks.community.elastic.search.service.ElasticSearchService;
+import org.jetlinks.community.logging.event.handler.LoggerIndexProvider;
+import org.jetlinks.community.logging.system.SerializableSystemLog;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+/**
+ * @version 1.0
+ **/
+@Service
+public class SystemLoggerService {
+
+ @Autowired
+ private ElasticSearchService searchService;
+
+ public Mono> getSystemLogger(QueryParam queryParam) {
+ return searchService.queryPager(LoggerIndexProvider.SYSTEM, queryParam, SerializableSystemLog.class);
+ }
+}
diff --git a/jetlinks-manager/pom.xml b/jetlinks-manager/pom.xml
index 6d736f1f..7136082c 100644
--- a/jetlinks-manager/pom.xml
+++ b/jetlinks-manager/pom.xml
@@ -16,6 +16,7 @@
device-manager
network-manager
notify-manager
+ logging-manager
\ No newline at end of file
diff --git a/jetlinks-standalone/pom.xml b/jetlinks-standalone/pom.xml
index f1972834..2511cfb1 100644
--- a/jetlinks-standalone/pom.xml
+++ b/jetlinks-standalone/pom.xml
@@ -129,6 +129,12 @@
${project.version}
+
+ ${project.groupId}
+ logging-manager
+ ${project.version}
+
+
org.jetlinks
jetlinks-supports