Skip to content

Commit

Permalink
项目优化
Browse files Browse the repository at this point in the history
  • Loading branch information
kcq committed Jul 19, 2020
1 parent 1b0d150 commit 3c93264
Show file tree
Hide file tree
Showing 27 changed files with 875 additions and 27 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
HELP.md
.flattened-pom.xml
application-autohome.properties
target/
logs/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,23 +324,26 @@ dwz45.token=t8HGzRNv9TmvqUFICNoW3SaYNA1C9OAC
* ~~增加企业微信机器人消息发送方式~~ [2020-07-05]
* ~~用户信息,团队信息,部门信息外部文件增加定期重新加载~~ [2020-07-05]
* ~~增加账号信息管理功能模块~~ [2020-07-11]
* ~~引入[maven-ci-friendly](https://maven.apache.org/maven-ci-friendly.html)实践~~ [2020-07-18]
* ~~使用[autolog4j](https://github.com/AutohomeCorp/autolog4j)程序日志格式~~ [2020-07-19]
* ~~文本日志按天滚动~~ [2020-07-19]
* 补充更详细的部署文档和使用指南
* 更新在线demo至最新
* 新功能暂时停止,代码优化改进,稳定一段时间后发布0.2-RELEASE
* 监控列表增加按团队查询;监控列表增加权限控制,监控按部门隔离
* 增加企业钉钉发消息默认实现(本地没有环境,需要帮助,欢迎有环境的同僚联系,先行谢过)
* 内置实现一个短链接功能,移除外部短链接服务依赖
* 移除SPI模块,经过一系列优化后,spi模块存在的必要性可能很低了,考虑移除掉,降低部署难度
* Elasticsearch监控数值实现同比监控
* Elasticsearch监控数值实现环比监控
* Elasticsearch数据源更新免重启加载
* Elasticsearch查询增加常用语句自动提示
* Elasticsearch查询数据柱状图可点击并自动变更时间范围
* Elasticsearch数据监控增加更多聚合类型(unique_count, percentiles)数值监控
* 增加系统配置功能模块,将启动非必要的配置用功能管理起来,减轻启动配置负担
* 移除SPI模块,经过一系列优化后,spi模块存在的必要性可能很低了,考虑移除掉,降低部署难度
* 补充更详细的部署文档
* README简化为文档目录索引形式,具体内容分散到各个文档中,方便查找
* 监控列表增加按团队查询;监控列表增加权限控制,监控按部门隔离
* 监控调度配置后显示预计调度时间
* 报警接收人可以设置为组
* 使用autolog4j程序日志格式
* 报警消息模板存库管理
* Elasticsearch数据名配置时自动提示索引名称
* Elasticsearch索引字段自动获取
Expand All @@ -355,6 +358,7 @@ dwz45.token=t8HGzRNv9TmvqUFICNoW3SaYNA1C9OAC
* 国际化
* 移除xxl-job依赖,内置实现监控调度,减小部署难度(待定)
* 发布1.0-RELEASE
* 加入更为复杂的时序数据异常检测算法规则(需要实验可行性)

## 主要技术栈

Expand Down
6 changes: 5 additions & 1 deletion ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@

* 增加query string简易教程
* 增加docker启动说明文档
* 引入[mybatis-dynamic-sql](https://github.com/mybatis/mybatis-dynamic-sql)

### Others

* Elasticsearch-Rest-Client升级至6.6.2
* 升级guava至28.2-jre
* 引入[mybatis-dynamic-sql](https://github.com/mybatis/mybatis-dynamic-sql)
* springboot升级至2.3.1-RELEASE
* 引入[maven-ci-friendly](https://maven.apache.org/maven-ci-friendly.html)实践 [2020-07-18]
* 使用[autolog4j](https://github.com/AutohomeCorp/autolog4j)程序日志格式 [2020-07-19]
* 文本日志按天滚动 [2020-07-19]

## 0.1-RELEASE

Expand Down
2 changes: 1 addition & 1 deletion doc/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ FROM maven:3.6.3-ibmjava-8-alpine
LABEL description="Frostmourne监控平台"
WORKDIR /opt/frostmourne
EXPOSE 9999
EXPOSE 10052
EXPOSE 10053
EXPOSE 10054
EXPOSE 10055
ENV XXL_JOB_VERSION=2.1.0
ENV FROSTMOURNE_VERSION=0.2-SNAPSHOT
COPY xxl-job-admin-${XXL_JOB_VERSION}.zip /opt/frostmourne/xxl-job-admin.zip
Expand Down
16 changes: 14 additions & 2 deletions frostmourne-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
<parent>
<artifactId>frostmourne</artifactId>
<groupId>com.autohome</groupId>
<version>0.2-SNAPSHOT</version>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>frostmourne-core</artifactId>

<dependencies>
Expand Down Expand Up @@ -49,5 +48,18 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.autohome.frostmourne.core.log4j2;

import org.apache.logging.log4j.core.LogEvent;

/**
* Created by kcq on 2017/6/8.
*/
public abstract class AbstractFieldParser {
public abstract String parse(String fieldName, LogEvent logEvent);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package com.autohome.frostmourne.core.log4j2;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import com.google.common.base.Strings;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.QuoteMode;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.CsvLogEventLayout;
import org.apache.logging.log4j.status.StatusLogger;

/**
* Created by kcq on 2017/6/8.
*/
@Plugin(name = "Autolog4jCsvLayout",
category = Node.CATEGORY,
elementType = Layout.ELEMENT_TYPE,
printObject = true)
public class Autolog4jCsvLayout extends CsvLogEventLayout {

private static final List<String> defaultFieldNames = Arrays.asList(FieldName.LOG_AT,
FieldName.LEVEL,
FieldName.LOGGER,
FieldName.LINE,
FieldName.EXCEPTION_TYPE,
FieldName.EXCEPTION_MESSAGE,
FieldName.CUSTOM_MESSAGE,
FieldName.CLASS_NAME,
FieldName.METHOD_NAME,
FieldName.METHOD_PARAMS,
FieldName.TRACE_ID,
FieldName.DEPARTMENT,
FieldName.TEAM,
FieldName.PROJECT,
FieldName.APP_ID,
FieldName.THREAD_ID,
FieldName.THREAD_NAME,
FieldName.HOST,
FieldName.SERVER_IP,
FieldName.URI_STEM,
FieldName.QUERY_STRING,
FieldName.FORM_STRING,
FieldName.USER_AGENT,
FieldName.STACK_TRACE
);

private String team;
private String department;
private String project;
private String appId;

private List<LayoutField> fields;
private FieldFactory fieldFactory;

protected Autolog4jCsvLayout(Configuration config, Charset charset, CSVFormat csvFormat, String header, String footer,
String department, String team, String project, String appId, FieldFactory fieldFactoryIn) {
super(config, charset, csvFormat, header, footer);
this.department = department;
this.team = team;
this.project = project;
this.appId = appId;
if (fieldFactoryIn == null) {
this.fieldFactory = new DefaultLog4jFieldFactory();
} else {
this.fieldFactory = fieldFactoryIn;
}
}

@PluginFactory
public static Autolog4jCsvLayout createLayout(
@PluginConfiguration final Configuration config,
@PluginAttribute(value = "format", defaultString = DEFAULT_FORMAT) final String format,
@PluginAttribute(value = "delimiter", defaultChar = '\t') final Character delimiter,
@PluginAttribute(value = "escape", defaultChar = '\\') final Character escape,
@PluginAttribute(value = "quote", defaultChar = '\"') final Character quote,
@PluginAttribute(value = "quoteMode", defaultString = "ALL") final QuoteMode quoteMode,
@PluginAttribute(value = "nullString", defaultString = "\"-\"") final String nullString,
@PluginAttribute(value = "recordSeparator", defaultString = "\r\n") final String recordSeparator,
@PluginAttribute(value = "charset", defaultString = DEFAULT_CHARSET) final Charset charset,
@PluginAttribute("header") final String header,
@PluginAttribute("footer") final String footer,
@PluginAttribute("department") final String department,
@PluginAttribute("team") final String team,
@PluginAttribute("project") final String project,
@PluginAttribute("appId") final String appId,
@PluginElement("FieldFactory") final FieldFactory fieldFactory) {
final CSVFormat csvFormat = createFormat(format, delimiter, escape, quote, quoteMode, nullString, recordSeparator);
return new Autolog4jCsvLayout(config, charset, csvFormat, header, footer,
department, team, project, appId, fieldFactory);
}

@Override
public String toSerializable(final LogEvent event) {
final StringBuilder buffer = getStringBuilder();
final CSVFormat format = getFormat();
if (this.fields == null || this.fields.size() == 0) {
this.fields = getDefaultFields();
}
try {
Iterator<LayoutField> fieldIterator = this.fields.iterator();
if (fieldIterator.hasNext()) {
format.print(handleEscapeChar(fieldIterator.next().format(event)), buffer, true);
while (fieldIterator.hasNext()) {
format.print(handleEscapeChar(fieldIterator.next().format(event)), buffer, false);
}
}
format.println(buffer);
return buffer.toString();
} catch (final IOException e) {
StatusLogger.getLogger().error(event.toString(), e);
return format.getCommentMarker() + " " + e;
}
}

public String getTeam() {
return team;
}

public void setTeam(String team) {
this.team = team;
}

public String getProject() {
return project;
}

public void setProject(String project) {
this.project = project;
}

public String getDepartment() {
return department;
}

public void setDepartment(String department) {
this.department = department;
}

private LayoutField createProjectField() {
if (!Strings.isNullOrEmpty(this.project)) {
this.project = this.project.toLowerCase();
}
return new LayoutField("Project", this.project);
}

private LayoutField createTeamField() {
if (!Strings.isNullOrEmpty(this.team)) {
this.team = this.team.toLowerCase();
}
return new LayoutField("Team", this.team);
}

private LayoutField createAppIdField() {
return new LayoutField("HawkKey", this.appId);
}

private List<LayoutField> getDefaultFields() {
List<LayoutField> fields = new ArrayList<>();

for (String fieldName : defaultFieldNames) {
switch (fieldName) {
case FieldName.DEPARTMENT:
fields.add(createDepartmentField());
break;
case FieldName.TEAM:
fields.add(createTeamField());
break;
case FieldName.PROJECT:
fields.add(createProjectField());
break;
case FieldName.APP_ID:
fields.add(createAppIdField());
break;
default:
fields.add(this.fieldFactory.fetchField(fieldName));
break;
}
}

return fields;
}

private String handleEscapeChar(String value) {
if (Strings.isNullOrEmpty(value) || !value.contains("\\\"")) {
return value;
}

return value.replace("\\\"", "\"");
}

private LayoutField createDepartmentField() {
if (!Strings.isNullOrEmpty(this.department)) {
this.department = this.department.toLowerCase();
}
return new LayoutField("Department", this.department);
}

public String getAppId() {
return appId;
}

public void setAppId(String appId) {
this.appId = appId;
}
}
Loading

0 comments on commit 3c93264

Please sign in to comment.