管理员
2 years ago
18 changed files with 1127 additions and 1 deletions
@ -0,0 +1,24 @@ |
|||
package org.nl.modules.logging; |
|||
|
|||
/** |
|||
* @author: lyd |
|||
* @description: |
|||
* @Date: 2022/10/11 |
|||
*/ |
|||
public enum InterfaceLogType { |
|||
DEFAULT("默认"), |
|||
LMS_TO_ACS("LMS请求ACS"), |
|||
ACS_TO_LMS("ACS请求LMS"), |
|||
ACS_TO_LK("ACS请求立库"), |
|||
LK_TO_ACS("立库请求ACS"); |
|||
|
|||
private String desc; |
|||
|
|||
InterfaceLogType(String desc) { |
|||
this.desc=desc; |
|||
} |
|||
|
|||
public String getDesc() { |
|||
return desc; |
|||
} |
|||
} |
@ -0,0 +1,62 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.annotation; |
|||
|
|||
import org.nl.modules.logging.InterfaceLogType; |
|||
|
|||
import java.lang.annotation.ElementType; |
|||
import java.lang.annotation.Retention; |
|||
import java.lang.annotation.RetentionPolicy; |
|||
import java.lang.annotation.Target; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
@Target(ElementType.METHOD) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
public @interface Log { |
|||
String value() default ""; |
|||
|
|||
/** |
|||
* 是否打印到日志文件 |
|||
* |
|||
* @return |
|||
*/ |
|||
boolean isPrintToLogFile() default false; |
|||
|
|||
|
|||
/** |
|||
* 是否插入操作日志表 |
|||
* |
|||
* @return |
|||
*/ |
|||
boolean isAddLogTable() default true; |
|||
|
|||
/** |
|||
* 是否接口日志 |
|||
* |
|||
* @return |
|||
*/ |
|||
boolean isInterfaceLog() default false; |
|||
|
|||
/** |
|||
* 接口日志类型 |
|||
* |
|||
* @return |
|||
*/ |
|||
InterfaceLogType interfaceLogType() default InterfaceLogType.DEFAULT; |
|||
} |
@ -0,0 +1,168 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.aspect; |
|||
|
|||
import cn.hutool.core.date.DateUtil; |
|||
import cn.hutool.core.util.StrUtil; |
|||
import cn.hutool.json.JSONUtil; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.aspectj.lang.ProceedingJoinPoint; |
|||
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.nl.common.utils.IdUtil; |
|||
import org.nl.modules.common.utils.RequestHolder; |
|||
import org.nl.modules.common.utils.StringUtils; |
|||
import org.nl.modules.common.utils.ThrowableUtil; |
|||
import org.nl.modules.logging.domain.Log; |
|||
import org.nl.modules.logging.service.LogService; |
|||
import org.nl.modules.wql.core.bean.WQLObject; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.lang.reflect.Method; |
|||
import java.lang.reflect.Parameter; |
|||
import java.util.*; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
@Component |
|||
@Aspect |
|||
@Slf4j |
|||
public class LogAspect { |
|||
|
|||
private final LogService logService; |
|||
|
|||
public LogAspect(LogService logService) { |
|||
this.logService = logService; |
|||
} |
|||
|
|||
/** |
|||
* 配置切入点 |
|||
*/ |
|||
@Pointcut("@annotation(org.nl.modules.logging.annotation.Log)") |
|||
public void logPointcut() { |
|||
// 该方法无方法体,主要为了让同类中其他方法使用此切入点
|
|||
} |
|||
|
|||
/** |
|||
* 配置环绕通知,使用在方法logPointcut()上注册的切入点 |
|||
* |
|||
* @param joinPoint join point for advice |
|||
*/ |
|||
@Around("logPointcut()") |
|||
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { |
|||
String trackId = UUID.randomUUID().toString(); |
|||
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
|||
Method method = signature.getMethod(); |
|||
// 方法路径
|
|||
String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; |
|||
String params = getParameter(method, joinPoint.getArgs()); |
|||
|
|||
org.nl.modules.logging.annotation.Log logInfo = method.getAnnotation(org.nl.modules.logging.annotation.Log.class); |
|||
|
|||
//是否输出到日志文件
|
|||
if (logInfo.isPrintToLogFile()) { |
|||
log.info("track_id:{},请求方法:{},请求方法参数:{}", trackId, methodName, params); |
|||
} |
|||
HttpServletRequest request = RequestHolder.getHttpServletRequest(); |
|||
String requestIp = StringUtils.getIp(request); |
|||
Object result; |
|||
long startTime = System.currentTimeMillis(); |
|||
try { |
|||
result = joinPoint.proceed(); |
|||
//是否把日志存到日志表
|
|||
if (logInfo.isAddLogTable()) { |
|||
Log log = new Log("INFO", System.currentTimeMillis() - startTime); |
|||
logService.save("", StringUtils.getBrowser(request), requestIp, joinPoint, log); |
|||
} |
|||
if (logInfo.isInterfaceLog()) { |
|||
try { |
|||
WQLObject interfaceLog = WQLObject.getWQLObject("sys_interface_log"); |
|||
JSONObject json = new JSONObject(); |
|||
json.put("log_id", IdUtil.getStringId()); |
|||
json.put("description", logInfo.value()); |
|||
json.put("log_type", logInfo.interfaceLogType().getDesc()); |
|||
json.put("log_level", "1"); |
|||
json.put("method", methodName); |
|||
json.put("params", getParameter(method, joinPoint.getArgs())); |
|||
json.put("request_ip", StringUtils.getIp(request)); |
|||
json.put("time", System.currentTimeMillis() - startTime); |
|||
json.put("username", ""); |
|||
json.put("address", StringUtils.getCityInfo(requestIp)); |
|||
json.put("browser", StringUtils.getBrowser(request)); |
|||
json.put("exception_detail", IdUtil.getStringId()); |
|||
json.put("create_time", DateUtil.now()); |
|||
json.put("return_result", result.toString()); |
|||
interfaceLog.insert(json); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} catch (Exception ex) { |
|||
log.error("track_id:{},error:{}", trackId, ex.getMessage()); |
|||
Log log = new Log("ERROR", System.currentTimeMillis() - startTime); |
|||
log.setExceptionDetail(ThrowableUtil.getStackTrace(ex).getBytes()); |
|||
logService.save("", StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint) joinPoint, log); |
|||
throw ex; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 根据方法和传入的参数获取请求参数 |
|||
*/ |
|||
private String getParameter(Method method, Object[] args) { |
|||
List<Object> argList = new ArrayList<>(); |
|||
Parameter[] parameters = method.getParameters(); |
|||
for (int i = 0; i < parameters.length; i++) { |
|||
//将RequestBody注解修饰的参数作为请求参数
|
|||
RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); |
|||
if (requestBody != null) { |
|||
argList.add(args[i]); |
|||
} |
|||
//将RequestParam注解修饰的参数作为请求参数
|
|||
RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); |
|||
if (requestParam != null) { |
|||
Map<String, Object> map = new HashMap<>(); |
|||
String key = parameters[i].getName(); |
|||
if (!StrUtil.isEmpty(requestParam.value())) { |
|||
key = requestParam.value(); |
|||
} |
|||
map.put(key, args[i]); |
|||
argList.add(map); |
|||
} |
|||
} |
|||
if (argList.size() == 0) { |
|||
return ""; |
|||
} |
|||
return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList); |
|||
} |
|||
|
|||
// public String getUsername() {
|
|||
// try {
|
|||
// return SecurityUtils.getCurrentUsername();
|
|||
// } catch (Exception e) {
|
|||
// return "";
|
|||
// }
|
|||
// }
|
|||
} |
@ -0,0 +1,82 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.domain; |
|||
|
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.Setter; |
|||
import org.hibernate.annotations.CreationTimestamp; |
|||
|
|||
import javax.persistence.*; |
|||
import java.io.Serializable; |
|||
import java.sql.Timestamp; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
@Entity |
|||
@Getter |
|||
@Setter |
|||
@Table(name = "sys_log") |
|||
@NoArgsConstructor |
|||
public class Log implements Serializable { |
|||
|
|||
@Id |
|||
@Column(name = "log_id") |
|||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
|||
private Long id; |
|||
|
|||
/** 操作用户 */ |
|||
private String username; |
|||
|
|||
/** 描述 */ |
|||
private String description; |
|||
|
|||
/** 方法名 */ |
|||
private String method; |
|||
|
|||
/** 参数 */ |
|||
private String params; |
|||
|
|||
/** 日志类型 */ |
|||
private String logType; |
|||
|
|||
/** 请求ip */ |
|||
private String requestIp; |
|||
|
|||
/** 地址 */ |
|||
private String address; |
|||
|
|||
/** 浏览器 */ |
|||
private String browser; |
|||
|
|||
/** 请求耗时 */ |
|||
private Long time; |
|||
|
|||
/** 异常详细 */ |
|||
private byte[] exceptionDetail; |
|||
|
|||
/** 创建日期 */ |
|||
@CreationTimestamp |
|||
private Timestamp createTime; |
|||
|
|||
public Log(String logType, Long time) { |
|||
this.logType = logType; |
|||
this.time = time; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,39 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.repository; |
|||
|
|||
import org.nl.modules.logging.domain.Log; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; |
|||
import org.springframework.data.jpa.repository.Modifying; |
|||
import org.springframework.data.jpa.repository.Query; |
|||
import org.springframework.stereotype.Repository; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
@Repository |
|||
public interface LogRepository extends JpaRepository<Log,Long>, JpaSpecificationExecutor<Log> { |
|||
|
|||
/** |
|||
* 根据日志类型删除信息 |
|||
* @param logType 日志类型 |
|||
*/ |
|||
@Modifying |
|||
@Query(value = "delete from sys_log where log_type = ?1", nativeQuery = true) |
|||
void deleteByLogType(String logType); |
|||
} |
@ -0,0 +1,51 @@ |
|||
package org.nl.modules.logging.rest; |
|||
|
|||
import io.swagger.annotations.Api; |
|||
import io.swagger.annotations.ApiOperation; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.nl.modules.logging.annotation.Log; |
|||
import org.nl.modules.logging.service.InterfaceLogService; |
|||
import org.springframework.data.domain.Pageable; |
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @author ldjun |
|||
* @version 1.0 |
|||
* @date 2023年01月29日 18:55 |
|||
* @desc desc |
|||
*/ |
|||
|
|||
@RestController |
|||
@RequiredArgsConstructor |
|||
@RequestMapping("/api/interfaceLog") |
|||
@Api(tags = "系统:接口日志管理") |
|||
public class InterfaceLogController { |
|||
private final InterfaceLogService interfaceLogService; |
|||
|
|||
@GetMapping |
|||
@Log("查询接口日志") |
|||
@ApiOperation("查询接口日志") |
|||
//@SaCheckPermission("point:list")
|
|||
public ResponseEntity<Object> query(@RequestParam Map whereJson, Pageable page) { |
|||
return new ResponseEntity<>(interfaceLogService.queryAll(whereJson, page), HttpStatus.OK); |
|||
} |
|||
|
|||
@DeleteMapping(value = "/delLogs") |
|||
@Log("删除所有接口日志") |
|||
@ApiOperation("删除所有接口日志") |
|||
public ResponseEntity<Object> delLogs(){ |
|||
interfaceLogService.delLogs(); |
|||
return new ResponseEntity<>(HttpStatus.OK); |
|||
} |
|||
|
|||
@GetMapping("/logTypeList") |
|||
@Log("查询接口日志类型下拉框") |
|||
@ApiOperation("查询接口日志类型下拉框") |
|||
public ResponseEntity<Object> logTypeList() { |
|||
return new ResponseEntity<>(interfaceLogService.logTypeList(), HttpStatus.OK); |
|||
} |
|||
} |
@ -0,0 +1,88 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.rest; |
|||
|
|||
import io.swagger.annotations.Api; |
|||
import io.swagger.annotations.ApiOperation; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.nl.common.utils.SecurityUtils; |
|||
import org.nl.modules.logging.annotation.Log; |
|||
import org.nl.modules.logging.service.LogService; |
|||
import org.nl.modules.logging.service.dto.LogQueryCriteria; |
|||
import org.springframework.data.domain.Pageable; |
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
@RestController |
|||
@RequiredArgsConstructor |
|||
@RequestMapping("/api/logs") |
|||
@Api(tags = "系统:日志管理") |
|||
public class LogController { |
|||
|
|||
private final LogService logService; |
|||
@GetMapping |
|||
@ApiOperation("日志查询") |
|||
//@SaCheckPermission("@el.check()")
|
|||
public ResponseEntity<Object> query(LogQueryCriteria criteria, Pageable pageable){ |
|||
criteria.setLogType("INFO"); |
|||
return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK); |
|||
} |
|||
|
|||
@GetMapping(value = "/user") |
|||
// @ApiOperation("用户日志查询")
|
|||
public ResponseEntity<Object> queryUserLog(LogQueryCriteria criteria, Pageable pageable){ |
|||
criteria.setLogType("INFO"); |
|||
criteria.setBlurry(SecurityUtils.getCurrentUsername()); |
|||
return new ResponseEntity<>(logService.queryAllByUser(criteria,pageable), HttpStatus.OK); |
|||
} |
|||
|
|||
@GetMapping(value = "/error") |
|||
@ApiOperation("错误日志查询") |
|||
// @SaCheckPermission("@el.check()")
|
|||
public ResponseEntity<Object> queryErrorLog(LogQueryCriteria criteria, Pageable pageable){ |
|||
criteria.setLogType("ERROR"); |
|||
return new ResponseEntity<>(logService.queryAll(criteria,pageable), HttpStatus.OK); |
|||
} |
|||
|
|||
@GetMapping(value = "/error/{id}") |
|||
@ApiOperation("日志异常详情查询") |
|||
// @SaCheckPermission("@el.check()")
|
|||
public ResponseEntity<Object> queryErrorLogs(@PathVariable Long id){ |
|||
return new ResponseEntity<>(logService.findByErrDetail(id), HttpStatus.OK); |
|||
} |
|||
@DeleteMapping(value = "/del/error") |
|||
@Log("删除所有ERROR日志") |
|||
@ApiOperation("删除所有ERROR日志") |
|||
// @SaCheckPermission("@el.check()")
|
|||
public ResponseEntity<Object> delAllErrorLog(){ |
|||
logService.delAllByError(); |
|||
return new ResponseEntity<>(HttpStatus.OK); |
|||
} |
|||
|
|||
@DeleteMapping(value = "/del/info") |
|||
@Log("删除所有INFO日志") |
|||
@ApiOperation("删除所有INFO日志") |
|||
// @SaCheckPermission("@el.check()")
|
|||
public ResponseEntity<Object> delAllInfoLog(){ |
|||
logService.delAllByInfo(); |
|||
return new ResponseEntity<>(HttpStatus.OK); |
|||
} |
|||
} |
@ -0,0 +1,44 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service; |
|||
|
|||
import com.alibaba.fastjson.JSONArray; |
|||
import org.springframework.data.domain.Pageable; |
|||
|
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
public interface InterfaceLogService { |
|||
|
|||
/** |
|||
* 查询数据分页 |
|||
* @param whereJson 条件 |
|||
* @param page 分页参数 |
|||
* @return Map<String,Object> |
|||
*/ |
|||
Map<String,Object> queryAll(Map whereJson, Pageable page); |
|||
|
|||
|
|||
/** |
|||
* 删除所有日志 |
|||
*/ |
|||
void delLogs(); |
|||
|
|||
JSONArray logTypeList(); |
|||
} |
@ -0,0 +1,82 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service; |
|||
|
|||
import org.aspectj.lang.ProceedingJoinPoint; |
|||
import org.nl.modules.logging.domain.Log; |
|||
import org.nl.modules.logging.service.dto.LogQueryCriteria; |
|||
import org.springframework.data.domain.Pageable; |
|||
import org.springframework.scheduling.annotation.Async; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
public interface LogService { |
|||
|
|||
/** |
|||
* 分页查询 |
|||
* @param criteria 查询条件 |
|||
* @param pageable 分页参数 |
|||
* @return / |
|||
*/ |
|||
Object queryAll(LogQueryCriteria criteria, Pageable pageable); |
|||
|
|||
/** |
|||
* 查询全部数据 |
|||
* @param criteria 查询条件 |
|||
* @return / |
|||
*/ |
|||
List<Log> queryAll(LogQueryCriteria criteria); |
|||
|
|||
/** |
|||
* 查询用户日志 |
|||
* @param criteria 查询条件 |
|||
* @param pageable 分页参数 |
|||
* @return - |
|||
*/ |
|||
Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable); |
|||
|
|||
/** |
|||
* 保存日志数据 |
|||
* @param username 用户 |
|||
* @param browser 浏览器 |
|||
* @param ip 请求IP |
|||
* @param joinPoint / |
|||
* @param log 日志实体 |
|||
*/ |
|||
@Async |
|||
void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log log); |
|||
|
|||
/** |
|||
* 查询异常详情 |
|||
* @param id 日志ID |
|||
* @return Object |
|||
*/ |
|||
Object findByErrDetail(Long id); |
|||
|
|||
/** |
|||
* 删除所有错误日志 |
|||
*/ |
|||
void delAllByError(); |
|||
|
|||
/** |
|||
* 删除所有INFO日志 |
|||
*/ |
|||
void delAllByInfo(); |
|||
} |
@ -0,0 +1,47 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service.dto; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.sql.Timestamp; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2019-5-22 |
|||
*/ |
|||
@Data |
|||
public class LogErrorDTO implements Serializable { |
|||
|
|||
private Long id; |
|||
|
|||
private String username; |
|||
|
|||
private String description; |
|||
|
|||
private String method; |
|||
|
|||
private String params; |
|||
|
|||
private String browser; |
|||
|
|||
private String requestIp; |
|||
|
|||
private String address; |
|||
|
|||
private Timestamp createTime; |
|||
} |
@ -0,0 +1,40 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service.dto; |
|||
|
|||
import lombok.Data; |
|||
import org.nl.modules.common.annotation.Query; |
|||
|
|||
import java.sql.Timestamp; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 日志查询类 |
|||
* @author Zheng Jie |
|||
* @date 2019-6-4 09:23:07 |
|||
*/ |
|||
@Data |
|||
public class LogQueryCriteria { |
|||
|
|||
@Query(blurry = "username,description,address,requestIp,method,params") |
|||
private String blurry; |
|||
|
|||
@Query |
|||
private String logType; |
|||
|
|||
@Query(type = Query.Type.BETWEEN) |
|||
private List<Timestamp> createTime; |
|||
} |
@ -0,0 +1,41 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service.dto; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.sql.Timestamp; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2019-5-22 |
|||
*/ |
|||
@Data |
|||
public class LogSmallDTO implements Serializable { |
|||
|
|||
private String description; |
|||
|
|||
private String requestIp; |
|||
|
|||
private Long time; |
|||
|
|||
private String address; |
|||
|
|||
private String browser; |
|||
|
|||
private Timestamp createTime; |
|||
} |
@ -0,0 +1,70 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service.impl; |
|||
|
|||
import com.alibaba.fastjson.JSONArray; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.nl.modules.logging.InterfaceLogType; |
|||
import org.nl.modules.logging.service.InterfaceLogService; |
|||
import org.nl.modules.wql.WQL; |
|||
import org.nl.modules.wql.core.bean.WQLObject; |
|||
import org.nl.modules.wql.util.WqlUtil; |
|||
import org.springframework.data.domain.Pageable; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
@Service |
|||
@RequiredArgsConstructor |
|||
@Slf4j |
|||
public class InterfaceLogServiceImpl implements InterfaceLogService { |
|||
|
|||
|
|||
@Override |
|||
public Map<String, Object> queryAll(Map whereJson, Pageable pageable) { |
|||
HashMap map = new HashMap(); |
|||
map.put("flag", "1"); |
|||
map.put("blurry", whereJson.get("blurry")); |
|||
map.put("logType", whereJson.get("logType")); |
|||
map.put("begin_time", whereJson.get("begin_time")); |
|||
map.put("end_time", whereJson.get("end_time")); |
|||
JSONObject json = WQL.getWO("QSCH_INTERFACE_LOGS").addParamMap(map).pageQuery(WqlUtil.getHttpContext(pageable), "create_time desc"); |
|||
return json; |
|||
} |
|||
|
|||
@Override |
|||
public void delLogs() { |
|||
WQLObject logTab = WQLObject.getWQLObject("sys_interface_log"); |
|||
logTab.delete("log_id is not null"); |
|||
} |
|||
|
|||
@Override |
|||
public JSONArray logTypeList() { |
|||
JSONArray jsonArray = new JSONArray(); |
|||
InterfaceLogType[] values = InterfaceLogType.values(); |
|||
for (InterfaceLogType value : values) { |
|||
jsonArray.add(value.getDesc()); |
|||
} |
|||
return jsonArray; |
|||
} |
|||
} |
@ -0,0 +1,158 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service.impl; |
|||
|
|||
import cn.hutool.core.lang.Dict; |
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import cn.hutool.core.util.StrUtil; |
|||
import cn.hutool.json.JSONUtil; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.aspectj.lang.ProceedingJoinPoint; |
|||
import org.aspectj.lang.reflect.MethodSignature; |
|||
import org.nl.modules.common.utils.PageUtil; |
|||
import org.nl.modules.common.utils.QueryHelp; |
|||
import org.nl.modules.common.utils.StringUtils; |
|||
import org.nl.modules.common.utils.ValidationUtil; |
|||
import org.nl.modules.logging.domain.Log; |
|||
import org.nl.modules.logging.repository.LogRepository; |
|||
import org.nl.modules.logging.service.LogService; |
|||
import org.nl.modules.logging.service.dto.LogQueryCriteria; |
|||
import org.nl.modules.logging.service.mapstruct.LogErrorMapper; |
|||
import org.nl.modules.logging.service.mapstruct.LogSmallMapper; |
|||
import org.springframework.data.domain.Page; |
|||
import org.springframework.data.domain.Pageable; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
|
|||
import java.lang.reflect.Method; |
|||
import java.lang.reflect.Parameter; |
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2018-11-24 |
|||
*/ |
|||
@Service |
|||
@RequiredArgsConstructor |
|||
@Slf4j |
|||
public class LogServiceImpl implements LogService { |
|||
private final LogRepository logRepository; |
|||
private final LogErrorMapper logErrorMapper; |
|||
private final LogSmallMapper logSmallMapper; |
|||
|
|||
@Override |
|||
public Object queryAll(LogQueryCriteria criteria, Pageable pageable) { |
|||
Page<Log> page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); |
|||
String status = "ERROR"; |
|||
if (status.equals(criteria.getLogType())) { |
|||
return PageUtil.toPage(page.map(logErrorMapper::toDto)); |
|||
} |
|||
return page; |
|||
} |
|||
|
|||
@Override |
|||
public List<Log> queryAll(LogQueryCriteria criteria) { |
|||
return logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb))); |
|||
} |
|||
|
|||
@Override |
|||
public Object queryAllByUser(LogQueryCriteria criteria, Pageable pageable) { |
|||
Page<Log> page = logRepository.findAll(((root, criteriaQuery, cb) -> QueryHelp.getPredicate(root, criteria, cb)), pageable); |
|||
return PageUtil.toPage(page.map(logSmallMapper::toDto)); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log logDto) { |
|||
|
|||
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
|||
Method method = signature.getMethod(); |
|||
org.nl.modules.logging.annotation.Log aopLog = method.getAnnotation(org.nl.modules.logging.annotation.Log.class); |
|||
|
|||
// 方法路径
|
|||
String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; |
|||
|
|||
// 描述
|
|||
if (logDto != null) { |
|||
logDto.setDescription(aopLog.value()); |
|||
} |
|||
assert logDto != null; |
|||
logDto.setRequestIp(ip); |
|||
|
|||
logDto.setAddress(StringUtils.getCityInfo(logDto.getRequestIp())); |
|||
logDto.setMethod(methodName); |
|||
logDto.setUsername(username); |
|||
logDto.setParams(getParameter(method, joinPoint.getArgs())); |
|||
logDto.setBrowser(browser); |
|||
logRepository.save(logDto); |
|||
} |
|||
|
|||
/** |
|||
* 根据方法和传入的参数获取请求参数 |
|||
*/ |
|||
private String getParameter(Method method, Object[] args) { |
|||
List<Object> argList = new ArrayList<>(); |
|||
Parameter[] parameters = method.getParameters(); |
|||
for (int i = 0; i < parameters.length; i++) { |
|||
//将RequestBody注解修饰的参数作为请求参数
|
|||
RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); |
|||
if (requestBody != null) { |
|||
argList.add(args[i]); |
|||
} |
|||
//将RequestParam注解修饰的参数作为请求参数
|
|||
RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); |
|||
if (requestParam != null) { |
|||
Map<String, Object> map = new HashMap<>(); |
|||
String key = parameters[i].getName(); |
|||
if (!StrUtil.isEmpty(requestParam.value())) { |
|||
key = requestParam.value(); |
|||
} |
|||
map.put(key, args[i]); |
|||
argList.add(map); |
|||
} |
|||
} |
|||
if (argList.size() == 0) { |
|||
return ""; |
|||
} |
|||
return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList); |
|||
} |
|||
|
|||
@Override |
|||
public Object findByErrDetail(Long id) { |
|||
Log log = logRepository.findById(id).orElseGet(Log::new); |
|||
ValidationUtil.isNull(log.getId(), "Log", "id", id); |
|||
byte[] details = log.getExceptionDetail(); |
|||
return Dict.create().set("exception", new String(ObjectUtil.isNotNull(details) ? details : "".getBytes())); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void delAllByError() { |
|||
logRepository.deleteByLogType("ERROR"); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void delAllByInfo() { |
|||
logRepository.deleteByLogType("INFO"); |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service.mapstruct; |
|||
|
|||
import org.mapstruct.Mapper; |
|||
import org.mapstruct.ReportingPolicy; |
|||
import org.nl.modules.common.base.BaseMapper; |
|||
import org.nl.modules.logging.domain.Log; |
|||
import org.nl.modules.logging.service.dto.LogErrorDTO; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2019-5-22 |
|||
*/ |
|||
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) |
|||
public interface LogErrorMapper extends BaseMapper<LogErrorDTO, Log> { |
|||
|
|||
} |
@ -0,0 +1,31 @@ |
|||
/* |
|||
* Copyright 2019-2020 Zheng Jie |
|||
* |
|||
* 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 org.nl.modules.logging.service.mapstruct; |
|||
|
|||
import org.mapstruct.Mapper; |
|||
import org.mapstruct.ReportingPolicy; |
|||
import org.nl.modules.common.base.BaseMapper; |
|||
import org.nl.modules.logging.domain.Log; |
|||
import org.nl.modules.logging.service.dto.LogSmallDTO; |
|||
|
|||
/** |
|||
* @author Zheng Jie |
|||
* @date 2019-5-22 |
|||
*/ |
|||
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE) |
|||
public interface LogSmallMapper extends BaseMapper<LogSmallDTO, Log> { |
|||
|
|||
} |
@ -0,0 +1,68 @@ |
|||
[交易说明] |
|||
交易名: 接口日志分页查询 |
|||
所属模块: |
|||
功能简述: |
|||
版权所有: |
|||
表引用: |
|||
版本经历: |
|||
|
|||
[数据库] |
|||
--指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 |
|||
|
|||
[IO定义] |
|||
################################################# |
|||
## 表字段对应输入参数 |
|||
################################################# |
|||
输入.flag TYPEAS s_string |
|||
输入.blurry TYPEAS s_string |
|||
输入.logType TYPEAS s_string |
|||
输入.begin_time TYPEAS s_string |
|||
输入.end_time TYPEAS s_string |
|||
|
|||
|
|||
[临时表] |
|||
--这边列出来的临时表就会在运行期动态创建 |
|||
|
|||
[临时变量] |
|||
--所有中间过程变量均可在此处定义 |
|||
|
|||
[业务过程] |
|||
|
|||
########################################## |
|||
# 1、输入输出检查 # |
|||
########################################## |
|||
|
|||
|
|||
########################################## |
|||
# 2、主过程前处理 # |
|||
########################################## |
|||
|
|||
|
|||
########################################## |
|||
# 3、业务主过程 # |
|||
########################################## |
|||
|
|||
IF 输入.flag = "1" |
|||
PAGEQUERY |
|||
SELECT |
|||
* |
|||
FROM |
|||
sys_interface_log |
|||
WHERE |
|||
1=1 |
|||
OPTION 输入.blurry <> "" |
|||
description like "%" 输入.blurry "%" |
|||
ENDOPTION |
|||
OPTION 输入.logType <> "" |
|||
log_type = 输入.logType |
|||
ENDOPTION |
|||
OPTION 输入.begin_time <> "" |
|||
create_time >= 输入.begin_time |
|||
ENDOPTION |
|||
OPTION 输入.end_time <> "" |
|||
create_time <= 输入.end_time |
|||
ENDOPTION |
|||
ENDSELECT |
|||
ENDPAGEQUERY |
|||
ENDIF |
|||
|
Loading…
Reference in new issue