赞
踩
目录
2.实现行为日志接口(之前的项目是插入数据库的这个实现用来插入ES)
3.创建ConsoleLogAppender用于Log4j2输出配置
1.编写日志类型枚举(老大之前写的,之前的日志是插入到数据库的.copy一下哈哈)
五.log4j2.xml配置文件增加ConsoleLogAppender
九.在kibana中创建仪表盘等(前提是ES有了一定量数据哈)
https://blog.csdn.net/qq_40174211/article/details/113255162
按照文章中的步骤 只搭建ES和Kibana集群即可
- <!--ElasticSearch 依赖-->
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- <version>7.8.1</version>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch</groupId>
- <artifactId>elasticsearch</artifactId>
- <version>7.8.1</version>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-client</artifactId>
- <version>7.8.1</version>
- </dependency>
- package com.sinosoft.springbootplus.util;
-
- import cn.hutool.core.util.IdUtil;
- import com.alibaba.fastjson.JSONObject;
- import org.apache.commons.collections.CollectionUtils;
- import org.apache.commons.collections.MapUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.elasticsearch.action.bulk.BulkRequest;
- import org.elasticsearch.action.get.GetRequest;
- import org.elasticsearch.action.get.GetResponse;
- import org.elasticsearch.action.index.IndexRequest;
- import org.elasticsearch.action.index.IndexResponse;
- import org.elasticsearch.action.search.SearchRequest;
- import org.elasticsearch.action.search.SearchResponse;
- import org.elasticsearch.action.update.UpdateRequest;
- import org.elasticsearch.action.update.UpdateResponse;
- import org.elasticsearch.client.RequestOptions;
- import org.elasticsearch.client.RestHighLevelClient;
- import org.elasticsearch.common.unit.TimeValue;
- import org.elasticsearch.index.query.*;
- import org.elasticsearch.index.reindex.BulkByScrollResponse;
- import org.elasticsearch.index.reindex.DeleteByQueryRequest;
- import org.elasticsearch.search.SearchHit;
- import org.elasticsearch.search.builder.SearchSourceBuilder;
- import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
- import org.springframework.context.annotation.Configuration;
-
- import javax.annotation.Resource;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
-
- /**
- * @author fan
- */
- @Configuration
- public class ElasticSearchUtils {
-
- @Resource
- private RestHighLevelClient restHighLevelClient;
-
-
- // ================================新增========================================
-
- /**
- *
- * * @Description: 更新文档
- * * @param [index 索引, id 索引id, map 待更新内容]
- * * @return java.lang.String
- * * @author fan
- * * @date 2021/4/28 14:58
- *
- **/
- public String updateDoc(String index, String id, Map<String, Object> map) throws IOException {
- UpdateRequest updateRequest = new UpdateRequest(index, id);
- updateRequest.doc(map);
- UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
- return updateResponse.getResult().getLowercase();
- }
-
- /**
- *
- * * @Description: 新增文档
- * * @param [index 索引, id doc的 _id, map 待插入内容]
- * * @return java.lang.String
- * * @author fan
- * * @date 2021/4/28 14:59
- *
- **/
- public String addDoc(String index, Map<String, Object> map) throws IOException {
- IndexRequest indexRequest = new IndexRequest(index);
- indexRequest.source(map);
- indexRequest.id(IdUtil.simpleUUID());
- IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
- return indexResponse.getResult().getLowercase();
- }
-
-
- /**
- * @Description: 批量插入文档
- * @param [index 索引, id 索引id, list 待插入内容]
- * @return void
- * @author fan
- * @date 2021/4/28 14:59
- **/
- public void bulkInsertDoc(String index, String id, List<Map<String, Object>> list) throws IOException {
- if (StringUtils.isBlank(index) || StringUtils.isBlank(id) || CollectionUtils.isEmpty(list)) {
- return;
- }
- BulkRequest bulkRequest = new BulkRequest();
- list.forEach(map -> {
- IndexRequest indexRequest = new IndexRequest(index);
- indexRequest.source(map);
- indexRequest.id(map.get(id).toString());
- bulkRequest.add(indexRequest);
- });
-
- restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
- }
-
- // ======================删除======================================
-
- /**
- * @Description: 根据文档Id删除数据
- * @param [index 索引, id 文档id]
- * @return long
- * @author fan
- * @date 2021/4/29 14:19
- **/
- public long deleteDocById(String index, String id) throws IOException {
-
- if (StringUtils.isBlank(index) || StringUtils.isBlank(id)) {
- return -1;
- }
- return deleteDocByValue(index, "_id", id);
- }
-
-
- /**
- * @Description: 根据字段值 删除数据
- * @param [index 索引, fieldName 映射名, value 文档值]
- * @return long
- * @author fan
- * @date 2021/4/29 16:36
- **/
- public long deleteDocByValue(String index, String fieldName, String value) throws IOException {
-
- if (StringUtils.isBlank(index) || StringUtils.isBlank(fieldName) || StringUtils.isBlank(value)) {
- return -1;
- }
- DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index);
- //设置版本冲突时继续执行
- deleteByQueryRequest.setConflicts("proceed");
- // 设置查询条件
- deleteByQueryRequest.setQuery(new TermQueryBuilder(fieldName, value));
- deleteByQueryRequest.setMaxDocs(60);
- deleteByQueryRequest.setBatchSize(1000);
- // 并行
- deleteByQueryRequest.setSlices(2);
- // 使用滚动参数来控制“搜索上下文”存活的时间
- deleteByQueryRequest.setScroll(TimeValue.timeValueMinutes(10));
- // 超时
- deleteByQueryRequest.setTimeout(TimeValue.timeValueMinutes(2));
- // 刷新索引
- deleteByQueryRequest.setRefresh(true);
-
- BulkByScrollResponse response = restHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
- return response.getStatus().getUpdated();
- }
-
-
- // ====================查询======================================
-
- /**
- * @Description: 多字段匹配查询
- * @param [index 索引, fieldMap 字段map]
- * @return java.lang.String
- * @author fan
- * @date 2021/4/29 16:39
- **/
- public String getByMultiFieldNames(String index, Map<String, Object> fieldMap) throws IOException {
- if (StringUtils.isBlank(index) || MapUtils.isEmpty(fieldMap)) {
- return null;
- }
- SearchRequest searchRequest = new SearchRequest(index);
-
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- //循环传入搜索参数
- fieldMap.forEach((key, value) -> {
- boolQueryBuilder.must(QueryBuilders.termQuery(key, value));
- });
-
- sourceBuilder.query(boolQueryBuilder);
- searchRequest.source(sourceBuilder);
- SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
- return handleSearchResponse2Json(searchResponse);
- }
-
-
- /**
- * @Description: 根据文档id 查询
- * @param [index 索引, id 文档id]
- * @return java.lang.String
- * @author fan
- * @date 2021/4/29 16:39
- **/
- public String getByIndexAndDocId(String index, String id) throws IOException {
- if (StringUtils.isBlank(index) || StringUtils.isBlank(id)) {
- return null;
- }
- GetRequest getRequest = new GetRequest(index, id);
- GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
- return getResponse.getSourceAsString();
- }
-
- /**
- * @Description: 根据索引分页查询
- * @param [index 索引, pageNum, pageSize]
- * @return java.lang.String
- * @author fan
- * @date 2021/4/29 16:41
- **/
- public String getByDoc(String index, int pageNum, int pageSize) throws IOException {
- if (StringUtils.isBlank(index)) {
- return null;
- }
-
- // 搜索请求
- SearchRequest searchRequest = new SearchRequest(index);
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
-
- // 分页
- if (pageNum >= 0 && pageSize >= 0) {
- searchSourceBuilder.from(pageSize * (pageNum - 1));
- searchSourceBuilder.size(pageSize);
- } else {
- // 如果不传分页参数 默认给20条数据
- searchSourceBuilder.from(0);
- searchSourceBuilder.size(19);
- }
-
- // 查询条件
- MatchAllQueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
-
- // 传入搜索条件
- searchSourceBuilder.query(queryBuilder);
- searchRequest.source(searchSourceBuilder);
-
- SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
- return handleSearchResponse2Json(searchResponse);
- }
-
-
- /**
- * @Description: 根据映射查询
- * @param [index 索引, fileName 映射, value 映射值]
- * @return java.lang.String
- * @author fan
- * @date 2021/4/29 16:44
- **/
- public String getByFieldName(String index, String fileName, String value) throws IOException {
-
- if (StringUtils.isBlank(index) || StringUtils.isBlank(fileName) || StringUtils.isBlank(value)) {
- return null;
- }
- SearchRequest searchRequest = new SearchRequest(index);
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- QueryBuilder queryBuilder = QueryBuilders.matchQuery(fileName, value);
- sourceBuilder.query(queryBuilder);
-
- searchRequest.source(sourceBuilder);
- SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
- return handleSearchResponse2Json(searchResponse);
- }
-
- /**
- * @Description: 在多个映射中查找一个值
- * @param [index 索引, value 要查找的值, fieldNames 映射]
- * @return java.lang.String
- * @author fan
- * @date 2021/4/29 16:45
- **/
- public String multiFieldsMatchOneValue(String index, String value, String... fieldNames) throws IOException {
-
- if (StringUtils.isBlank(index) || StringUtils.isBlank(value) || null == fieldNames) {
- return null;
- }
- SearchRequest searchRequest = new SearchRequest(index);
-
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(value, fieldNames);
- sourceBuilder.query(queryBuilder);
-
- searchRequest.source(sourceBuilder);
- SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
- return handleSearchResponse2Json(searchResponse);
- }
-
-
- /**
- * @Description: 字段模糊匹配
- * @param [index 索引, fieldName 映射, wildValueStr 模糊值]
- * @return java.lang.String
- * @author fan
- * @date 2021/4/29 16:48
- **/
- public String getByFieldNameWild(String index, String fieldName, String wildValueStr) throws IOException {
-
- if (StringUtils.isBlank(index) || StringUtils.isBlank(fieldName) || StringUtils.isBlank(wildValueStr)) {
- return null;
- }
-
- SearchRequest searchRequest = new SearchRequest(index);
-
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
- WildcardQueryBuilder queryBuilder = QueryBuilders.wildcardQuery(fieldName, wildValueStr);
- sourceBuilder.query(queryBuilder);
-
- searchRequest.source(sourceBuilder);
- SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
- return handleSearchResponse2Json(searchResponse);
- }
-
- /**
- * @Description: 范围查询
- * @param [index 索引, fieldName 映射, start 开始, includeUpperStart 是否包含开始, end 结束, includeUpperEnd 是否包含结束]
- * @return java.lang.String
- * @author fan
- * @date 2021/4/29 16:48
- **/
- public String getByFieldRange(String index, String fieldName, String start, boolean includeUpperStart, String end, boolean includeUpperEnd) throws IOException {
- if (StringUtils.isBlank(index) || StringUtils.isBlank(fieldName)) {
- return null;
- }
-
- SearchRequest searchRequest = new SearchRequest(index);
-
- RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(fieldName);
- rangeQueryBuilder.from(start, includeUpperStart);
- rangeQueryBuilder.to(end, includeUpperEnd);
-
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
- searchSourceBuilder.query(rangeQueryBuilder);
- searchRequest.source(searchSourceBuilder);
- SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
- return handleSearchResponse2Json(searchResponse);
- }
-
- /**
- * @Description: 根据文档id判断文档是否存在
- * @param [index 索引, id 文档id]
- * @return boolean
- * @author fan
- * @date 2021/4/29 16:49
- **/
- public boolean isExists(String index, String id) throws IOException {
- if (StringUtils.isBlank(index) || StringUtils.isBlank(id)) {
- return Boolean.FALSE;
- }
- GetRequest getRequest = new GetRequest(index, id);
- //禁用fetching _source
- getRequest.fetchSourceContext(new FetchSourceContext(false));
- // 关闭 存储字段
- getRequest.storedFields("_none_");
-
- return restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
- }
-
- /**
- * @Description: 将SearchResponse 取出数据 转换成json
- * @param [searchResponse 查询结果]
- * @return java.lang.String
- * @author fan
- * @date 2021/4/29 16:50
- **/
- private String handleSearchResponse2Json(SearchResponse searchResponse) {
- SearchHit[] hits = searchResponse.getHits().getHits();
- if (hits.length == 0) {
- return null;
- }
- List<Map<String, Object>> dataList = new ArrayList<>(hits.length);
- for (int i = 0; i < hits.length; i++) {
- dataList.add(hits[i].getSourceAsMap());
- }
- return JSONObject.toJSONString(dataList);
- }
-
-
- }
- package com.sinosoft.springbootplus.config;
-
- import org.apache.http.HttpHost;
- import org.elasticsearch.client.RestClient;
- import org.elasticsearch.client.RestClientBuilder;
- import org.elasticsearch.client.RestHighLevelClient;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- import javax.annotation.PostConstruct;
- import java.util.ArrayList;
- import java.util.List;
-
- /**
- * @Description: ElasticSearch 配置类
- * @Author: karma
- * @Date: 2019/11/25 3:11 下午
- */
- @Configuration
- public class ElasticSearchConfig {
-
- /**
- * 集群地址,多个用,隔开
- **/
- @Value("${elasticSearch.hosts}")
- private String hosts;
-
- /**
- * 端口号
- **/
- @Value("${elasticSearch.port}")
- private int port;
-
- /**
- * 使用的协议
- **/
- @Value("${elasticSearch.schema}")
- private String schema;
-
- /**
- * 连接超时时间
- **/
- @Value("${elasticSearch.client.connectTimeOut}")
- private int connectTimeOut;
-
- /**
- * 连接超时时间
- **/
- @Value("${elasticSearch.client.socketTimeOut}")
- private int socketTimeOut;
-
- /**
- * 获取连接的超时时间
- **/
- @Value("${elasticSearch.client.connectionRequestTimeOut}")
- private static int connectionRequestTimeOut;
-
- /**
- * 最大连接数
- **/
- @Value("${elasticSearch.client.maxConnectNum}")
- private static int maxConnectNum;
-
- /**
- * 最大路由连接数
- **/
- @Value("${elasticSearch.client.maxConnectPerRoute}")
- private static int maxConnectPerRoute;
-
-
- private List<HttpHost> hostList = new ArrayList<>();
-
- @PostConstruct
- private void init(){
- hostList = new ArrayList<>();
- String[] hostArray = hosts.split(",");
- for (String host : hostArray) {
- hostList.add(new HttpHost(host, port, schema));
- }
- }
-
- @Bean
- public RestHighLevelClient getRestHighLevelClient() {
-
- RestClientBuilder builder = RestClient.builder(hostList.toArray(new HttpHost[0]));
- // 异步httpclient连接延时配置
- builder.setRequestConfigCallback(requestConfigBuilder -> {
- requestConfigBuilder.setConnectTimeout(connectTimeOut);
- requestConfigBuilder.setSocketTimeout(socketTimeOut);
- requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);
- return requestConfigBuilder;
- });
- // 异步httpclient连接数配置
- builder.setHttpClientConfigCallback(httpClientBuilder -> {
- httpClientBuilder.setMaxConnTotal(maxConnectNum);
- httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
- return httpClientBuilder;
- });
- RestHighLevelClient client = new RestHighLevelClient(builder);
- return client;
- }
-
- }
-
-
- package com.sinosoft.springbootplus.log4j2.service;
-
-
- import java.util.List;
-
- /**
- * <pre>
- * 系统行为日志
- * </pre>
- *
- * @author 波哥
- * @since 2020-02-23
- */
- public interface BaseLogService {
- /**
- * 单条保存行为日志
- */
- void save(String loginfoJson);
-
- /**
- * 批量保存行为日志
- */
- void saveBatch(List<String> loginfoJsons);
- }
- package com.sinosoft.springbootplus.impl;
-
- import com.sinosoft.springbootplus.log4j2.service.BaseLogService;
- import com.sinosoft.springbootplus.entity.EsSaveInfo;
- import com.sinosoft.springbootplus.util.ElasticSearchUtils;
- import com.sinosoft.springbootplus.util.Jackson;
- import com.sinosoft.springbootplus.util.MapperUtils;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Component;
-
- import java.util.List;
-
- /**
- * @author fan
- * @Date 2021/5/14 10:36 <pre>
- *
- * </per>
- */
- @Slf4j
- @Component
- public class EsLogServiceImpl implements BaseLogService {
-
- ElasticSearchUtils elasticSearchUtils;
-
- public EsLogServiceImpl(ElasticSearchUtils elasticSearchUtils) {
- this.elasticSearchUtils = elasticSearchUtils;
- }
-
- @Override
- public void save(String logInfoJson) {
- log.info(Jackson.toJsonString(logInfoJson));
- try {
- saveSingle(logInfoJson);
- } catch (Exception e) {
- log.error("ES保存操作异常,【{}】",e.getMessage(),e);
- }
- }
-
- private void saveSingle(String logParamJson) throws Exception {
- EsSaveInfo esSaveInfo = MapperUtils.json2pojo(logParamJson, EsSaveInfo.class);
- elasticSearchUtils.addDoc(esSaveInfo.getIndex(), esSaveInfo.getEsSaveDetail());
- }
-
- @Override
- public void saveBatch(List<String> logInfoJsons) {
- log.info(Jackson.toJsonString(logInfoJsons));
- try {
- for (String logParamJson : logInfoJsons) {
- saveSingle(logParamJson);
- }
- } catch (Exception e) {
- log.error("ES批量保存操作异常,【{}】",e.getMessage(),e);
- }
- }
- }
- package com.sinosoft.springbootplus.log4j2;
-
- import cn.hutool.json.JSONUtil;
- import com.sinosoft.springbootplus.log4j2.service.BaseLogService;
- import com.sinosoft.springbootplus.util.SpringContextUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.logging.log4j.core.Filter;
- import org.apache.logging.log4j.core.Layout;
- import org.apache.logging.log4j.core.LogEvent;
- import org.apache.logging.log4j.core.appender.AbstractAppender;
- import org.apache.logging.log4j.core.config.Property;
- 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.PluginElement;
- import org.apache.logging.log4j.core.config.plugins.PluginFactory;
- import org.apache.logging.log4j.core.layout.PatternLayout;
-
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.List;
-
- /**
- * @author 波哥
- * @Title:
- * @Description: 添加类的描述
- * @date 2020/2/22 18:05
- */
- @Slf4j
- @Plugin(name = "ConsoleLogAppender", category = "Core", elementType = "appender", printObject = true)
- public class ConsoleLogAppender extends AbstractAppender {
- /**
- * 日志出现延迟时间大于1秒时开启批量入库
- */
- private static final int DELAY_TIME = 1000;
- /**
- * 出现延迟后每次批量的插入的数量
- */
- private static final int BATCH_SIZE = 20;
- /**
- * 日志服务用于保存日志
- */
- private BaseLogService baseLogService;
- private List<String> list = new ArrayList<>();
-
- private ConsoleLogAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions) {
-
- super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
- }
-
- @Override
- public void append(LogEvent logEvent) {
- if (baseLogService == null) {
- baseLogService = SpringContextUtil.getBean(BaseLogService.class);
- }
- int size = list.size();
- long curr = System.currentTimeMillis();
- if ((curr - logEvent.getTimeMillis()) > DELAY_TIME && size < BATCH_SIZE) {
- list.add(logEvent.getMessage().getFormattedMessage());
- } else if (size == 0) {
- try {
- //baseLogService.save(JSONUtil.toBean(logEvent.getMessage().getFormattedMessage(), SysLog.class));
- baseLogService.save(logEvent.getMessage().getFormattedMessage());
- } catch (Exception e) {
- log.error("保存操作异常,【{}】,未保存日志【{}】",e.getMessage(),logEvent.getMessage().getFormattedMessage(),e);
- }
- } else {
- list.add(logEvent.getMessage().getFormattedMessage());
- try {
- baseLogService.saveBatch(new ArrayList<>(list));
- } catch (Exception e) {
- log.error("保存操作异常,【{}】,未保存日志【{}】",e.getMessage(),JSONUtil.toJsonStr(list),e);
- }
- list.clear();
- }
-
- }
-
- @PluginFactory
- public static ConsoleLogAppender createAppender(@PluginAttribute(value = "name", defaultString = "consoleLog") String name,
- @PluginElement("Filter") final Filter filter,
- @PluginElement("Layout") Layout<? extends Serializable> layout,
- @PluginAttribute(value = "ignoreExceptions") boolean ignoreExceptions
- ) {
- if (layout == null) {
- layout = PatternLayout.createDefaultLayout();
- }
- return new ConsoleLogAppender(name, filter, layout, ignoreExceptions);
-
- }
- }
- package com.sinosoft.springbootplus.common.enums;
-
- /**
- * 枚举类型父接口
- *
- * @author 波哥
- */
- public interface BaseEnum {
-
- /**
- * 获取枚举索引
- *
- * @return
- */
- Integer getCode();
-
- /**
- * 获取描述
- *
- * @return
- */
- String getDesc();
-
- }
- package com.sinosoft.springbootplus.log4j2.enums;
-
- import com.sinosoft.springbootplus.common.enums.BaseEnum;
-
- /**
- * 日志类型枚举
- * @author 波哥
- * @date 2020/2/23 11:40
- */
-
- public enum LogTypeEnum implements BaseEnum {
- SEARCH(1, "查询"),
- UPDATE(2, "更新"),
- DELETE(3,"删除"),
- INSERT(4,"新增"),
- UPLOAD(5,"上传"),
- DOWNLOAD(6,"下载");
-
- private Integer code;
- private String desc;
-
- LogTypeEnum(Integer code, String desc) {
- this.code = code;
- this.desc = desc;
- }
-
- @Override
- public Integer getCode() {
- return this.code;
- }
-
- @Override
- public String getDesc() {
- return this.desc;
- }
- }
- import com.sinosoft.springbootplus.log4j2.enums.LogTypeEnum;
-
- import java.lang.annotation.*;
-
- /**
- *
- * ES日志注解
- * @author fan
- */
-
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface SysLogEs {
- String value() default "";
- LogTypeEnum type() default LogTypeEnum.SEARCH;
- String index() default "";
- }
- /*
- * Copyright 2019-2029 geekidea(https://github.com/geekidea)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.sinosoft.springbootplus.log4j2.aop;
-
- import cn.hutool.json.JSONUtil;
- import com.alibaba.fastjson.JSONObject;
- import com.sinosoft.springbootplus.core.context.RequestContext;
- import com.sinosoft.springbootplus.log4j2.entity.SysLog;
- import com.sinosoft.springbootplus.log4j2.entity.SysLogEs;
- import com.sinosoft.springbootplus.util.ClientInfoUtil;
- import com.sinosoft.springbootplus.util.IpUtil;
- import com.sinosoft.springbootplus.util.vo.ClientInfo;
- import lombok.extern.slf4j.Slf4j;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.Signature;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Pointcut;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Component;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.context.request.RequestContextHolder;
- import org.springframework.web.context.request.ServletRequestAttributes;
- import org.springframework.web.multipart.MultipartFile;
- import org.springframework.web.servlet.ModelAndView;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
-
- /**
- * 用于保存请求数据到Es
- *
- * @author fan
- */
- @Aspect
- @Component
- @Slf4j
- public class SysLogAopEs {
- private static final Logger logLogger = LoggerFactory.getLogger("sinosoft.consoleLog");
-
- /**
- * POST请求
- **/
- private static final String POST = "POST";
-
- @Pointcut("@annotation(com.sinosoft.springbootplus.log4j2.annotation.SysLogEs)")
- public void consoleLog() {
- }
-
- @Around("consoleLog()")
- public Object handle(ProceedingJoinPoint joinPoint) throws Throwable {
- SysLogEs sysLogEs = new SysLogEs();
- SysLog sysLog = new SysLog();
- sysLogEs.setEsSaveMap(sysLog);
- // 获取请求相关信息
- try {
- // 获取当前的HttpServletRequest对象
- ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- if (attributes == null) {
- throw new RuntimeException("获取ServletRequestAttributes为空");
- }
- HttpServletRequest request = attributes.getRequest();
- // 获取请求类名和方法名称
- Signature signature = joinPoint.getSignature();
-
- // 获取真实的方法对象
- MethodSignature methodSignature = (MethodSignature) signature;
- Method method = methodSignature.getMethod();
- //获取拦截额日志注解
- com.sinosoft.springbootplus.log4j2.annotation.SysLogEs sysLogAnnotation = method.getAnnotation(com.sinosoft.springbootplus.log4j2.annotation.SysLogEs.class);
- //获取注解中的信息,包括描述
- sysLog.setTitle(sysLogAnnotation.value());
- //获取操作类型
- sysLog.setType(sysLogAnnotation.type().getDesc());
- //获取索引
- sysLogEs.setIndex(sysLogAnnotation.index());
- // 请求全路径
- String url = request.getRequestURI();
- sysLog.setRequestUri(url);
- // IP地址
- String ip = IpUtil.getRequestIp();
- sysLog.setRemoteAddr(ip);
- ClientInfo clientInfo = ClientInfoUtil.get(request);
- sysLog.setBrowser(clientInfo.toString());
- //设置当前用户
- sysLog.setUsername(RequestContext.getLoginUserNickName());
- sysLog.setUserId(RequestContext.getLoginUserId());
- } catch (Exception e) {
- log.error("获取操作日志信息过程异常,【{}】", e.getMessage(), e);
- }
- long b = System.currentTimeMillis();
- // 执行目标方法,获得返回值
- try {
- Object result = joinPoint.proceed();
- long e = System.currentTimeMillis();
- sysLog.setUseTime(e - b);
- logLogger.info(JSONUtil.toJsonStr(sysLogEs));
- return result;
- } catch (Exception ep) {
- long e = System.currentTimeMillis();
- sysLog.setUseTime(e - b);
- sysLog.setException(ep.getMessage());
- logLogger.info(JSONUtil.toJsonStr(sysLogEs));
- throw ep;
- }
- }
-
- /**
- * 获取请求参数JSON字符串
- */
- private Object getRequestParamJsonString(ProceedingJoinPoint joinPoint, HttpServletRequest request, String requestMethod, boolean isRequestBody) {
- Object paramObject;
- if (POST.equals(requestMethod) && isRequestBody) {
- Object[] args = joinPoint.getArgs();
- paramObject = argsArrayToJsonString(args);
- } else {
- Map<String, String[]> paramsMap = request.getParameterMap();
- paramObject = getJsonForParamMap(paramsMap);
- }
- return paramObject;
- }
-
- /**
- * 判断控制器方法参数中是否有RequestBody注解
- */
- private boolean isRequestBody(Annotation[][] annotations) {
- boolean isRequestBody = false;
- for (Annotation[] annotationArray : annotations) {
- for (Annotation annotation : annotationArray) {
- if (annotation instanceof RequestBody) {
- isRequestBody = true;
- break;
- }
- }
- }
- return isRequestBody;
- }
-
- /**
- * 请求参数拼装
- */
- private Object argsArrayToJsonString(Object[] args) {
- if (args == null) {
- return null;
- }
- // 去掉HttpServletRequest和HttpServletResponse
- List<Object> realArgs = new ArrayList<>();
- for (Object arg : args) {
- if (arg instanceof HttpServletRequest) {
- continue;
- }
- if (arg instanceof HttpServletResponse) {
- continue;
- }
- if (arg instanceof MultipartFile) {
- continue;
- }
- if (arg instanceof ModelAndView) {
- continue;
- }
- realArgs.add(arg);
- }
- if (realArgs.size() == 1) {
- return realArgs.get(0);
- } else {
- return realArgs;
- }
- }
-
-
- /**
- * 获取参数Map的JSON字符串
- */
- private JSONObject getJsonForParamMap(Map<String, String[]> paramsMap) {
- if (paramsMap == null || paramsMap.size() == 0) {
- return null;
- }
- JSONObject jsonObject = new JSONObject();
- for (Map.Entry<String, String[]> kv : paramsMap.entrySet()) {
- String key = kv.getKey();
- String[] values = kv.getValue();
- // 没有值
- if (values == null) {
- jsonObject.put(key, null);
- // 一个值
- } else if (values.length == 1) {
- jsonObject.put(key, values[0]);
- // 多个值
- } else {
- jsonObject.put(key, values);
- }
- }
- return jsonObject;
- }
-
- }
- <Appenders>
- <ConsoleLogAppender >
- <PatternLayout pattern="%msg" charset="${CHARSET}"/>
- </ConsoleLogAppender>
- </Appenders>
- <Loggers>
- <AsyncLogger name="sinosoft.consoleLog" additivity="false">
- <AppenderRef ref="consoleLog" />
- </AsyncLogger>
- </Loggers>
- package com.sinosoft.springbootplus;
-
- import com.sinosoft.springbootplus.log4j2.annotation.SysLogEs;
- import com.sinosoft.springbootplus.log4j2.enums.LogTypeEnum;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- /**
- * @Auther: fan
- * @Date 2021/5/20 16:11 <pre>
- *
- * </per>
- */
- @Slf4j
- @RestController
- @RequestMapping("/www")
- public class Controller {
- @GetMapping("/bbb")
- @SysLogEs(value = "testDDD",type= LogTypeEnum.DELETE,index = "user_action")
- public void addJwBjAllBaseinfo() {
- System.out.println("====");
- }
- }
- PUT user_action
- PUT user_action/_mapping
- {
- "properties": {
- "id": {
- "type": "keyword"
- },
- "type": {
- "type": "keyword"
- },
- "title": {
- "type": "keyword"
- },
- "remoteAddr": {
- "type": "ip"
- },
- "userId": {
- "type": "keyword"
- },
- "username": {
- "type": "text",
- "fielddata": true
- },
- "requestUri": {
- "type": "text"
- },
- "useTime": {
- "type": "integer"
- },
- "browser": {
- "type": "text"
- },
- "exception": {
- "type": "text"
- },
- "requestTime": {
- "type": "date"
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。