You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

707 lines
23 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.engine.salary.elog.util;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.engine.salary.elog.entity.dto.LoggerContext;
import com.engine.salary.elog.enums.FromTerminalType;
import com.engine.salary.elog.threadlocal.ElogThreadLocal;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import weaver.hrm.User;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class ElogUtils {
private static final Logger logger = LoggerFactory.getLogger(ElogUtils.class);
private static final String TABLE_SPACER = "_";
private static final String TABLE_SUFFIX = "logs";
private static final String DETAIL_TABLE_SUFFIX = "_detail";
public static final String BASE_TABLE = "BASE_ELOG_TABLE";
public String getApplicationName() {
return applicationName;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
// @Value("${spring.application.name}")
public static String applicationName;
public static String getTableName(String module, String function) {
return getTableName(module, function, false);
}
public static String getTableName(String module, String function, boolean isDetail) {
String tablename = module + TABLE_SPACER + function + TABLE_SUFFIX + (isDetail ? DETAIL_TABLE_SUFFIX : "");
// SecurityUtil.sqlCheck(tablename);
return tablename;
}
/**
* String 转枚举
*
* @param c
* @param string
* @param <T>
* @return
*/
public static <T extends Enum<T>> T getEnumFromString(Class<T> c, String string) {
if (c != null && string != null) {
try {
return Enum.valueOf(c, string.trim().toUpperCase());
} catch (IllegalArgumentException ex) {
}
}
return null;
}
/**
* 获取ip地址
*
* @param request
* @return
*/
public static String getIp(HttpServletRequest request) {
String ipAddress = request.getHeader("x-forwarded-for");
String unknown = "unknown";
if (ipAddress == null || ipAddress.length() == 0 || unknown.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || unknown.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || unknown.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
String benji = "127.0.0.1";
String bj = "0:0:0:0:0:0:0:1";
if (benji.equals(ipAddress) || bj.equals(ipAddress)) {
///根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
logger.error("UnknownHostException", e);
}
if (inet != null) {
ipAddress = inet.getHostAddress();
}
}
}
///对于通过多个代理的情况第一个IP为客户端真实IP,多个IP按照','分割
int i = 15;
String s = ",";
if (ipAddress != null && ipAddress.length() > i) {
if (ipAddress.indexOf(s) > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
return ipAddress;
}
/**
* 获取设备信息
*
* @param request
* @return
*/
public static String getDevice(HttpServletRequest request) {
return request.getHeader("User-Agent");
}
/**
* 获取来自终端的信息
*
* @param context
* @param request
* @return
*/
public static void getFromTerminal(LoggerContext context, HttpServletRequest request) {
String fromTerminal = context.getFromTerminal();
if (StringUtils.isEmpty(fromTerminal)) {
String device = getDevice(request);
String setFT = "";
if (StringUtils.isNotEmpty(device)) {
context.setFromTerminal(getFromTerminal(device));
}
}
}
public static void initRequestInfo(HttpServletRequest request, LoggerContext context) {
if (StringUtils.isEmpty(context.getRequestUrl())) {
context.setRequestUrl(getRequestUrl(request));
}
if (StringUtils.isEmpty(context.getRequestUri())) {
context.setRequestUri(getRequestMethod(request) + ":" + getRequestUri(request));
}
//if (context.getParams() == null) {
//默认记录params此参数给true时 或报表服务,不记录
if (!context.getParamsIgnore() && !applicationName.equalsIgnoreCase("weaver-edcreportd-service")) {
context.setParams(getRequstParam(request,context));
}
// }
if (StringUtils.isEmpty(context.getClientIp())) {
context.setClientIp(getIp(request));
}
if (StringUtils.isEmpty(context.getDevice())) {
context.setDevice(getDevice(request));
}
if (StringUtils.isEmpty(context.getFromTerminal())) {
context.setFromTerminal(getFromTerminal(getDevice(request)));
}
if (StringUtils.isEmpty(context.getBelongMainId())) {
context.setBelongMainId(getTraceId(request));
}
}
private static String getTraceId(HttpServletRequest request) {
String traceId = request.getHeader("traceId");
if (StringUtils.isNotBlank(traceId)) {
//System.out.println("traceId:====="+traceId);
return traceId;
}
return "";
}
/**
* @param request
* @return localhost:9080/api/fs/demo/updateReport
*/
public static String getRequestUrl(HttpServletRequest request) {
if (Objects.isNull(request) || Objects.isNull(request.getRequestURL())) {
return null;
}
return request.getRequestURL().toString();
}
/**
* @param request
* @return /api/fs/demo/updateReport
*/
public static String getRequestUri(HttpServletRequest request) {
return request.getRequestURI();
}
/**
* @param request
* @return GET/POST
*/
public static String getRequestMethod(HttpServletRequest request) {
return request.getMethod();
}
public static Map getRequstParam(HttpServletRequest request, LoggerContext context) {
return request2Map(request, context);
}
/**
* 获取当前方法中的日志实体类
*
* @return
*/
public static LoggerContext currentElogContext() {
return ElogThreadLocal.currentLoggerContext();
}
public static Map<String, Object> request2Map(HttpServletRequest request, LoggerContext context) {
// 参数Map
Map properties = request.getParameterMap();
// 返回值Map
Map<String, Object> returnMap = new HashMap<String, Object>();
Iterator<Map.Entry> entries = properties.entrySet().iterator();
Map.Entry entry;
String name = "";
Object value = null;
while (entries.hasNext()) {
entry = (Map.Entry) entries.next();
name = (String) entry.getKey();
Object valueObj = entry.getValue();
if (null == valueObj) {
value = null;
} else if (valueObj instanceof String[]) {
String[] values = (String[]) valueObj;
if (values.length == 1) {
value = values[0];
} else {
value = values;
}
} else {
value = valueObj.toString();
}
returnMap.put(name, value);
}
//放入ip
returnMap.put("param_ip", getIp(request));
returnMap.put("request_header_user_agent", request.getHeader("user-agent"));
JSONObject body = ElogThreadLocal.getRequestBody();
if (body != null) {
// returnMap.put("request_body", body);
setReturnMapBody(returnMap,context.getParamsBodyKeys(),body);
}
return returnMap;
}
public static void setReturnMapBody(Map<String, Object> returnMap,List<String> keys,JSONObject body) {
//模块没设置则全部记录
if (CollectionUtils.isEmpty(keys)) {
returnMap.put("request_body", body);
}else {
JSONObject newBody = new JSONObject();
for (String key : keys) {
newBody.put(key,body.get(key));
}
returnMap.put("request_body", newBody);
}
}
public static int getIntValue(String v) {
return getIntValue(v, -1);
}
public static int getIntValue(String v, int def) {
try {
return Integer.parseInt(v);
} catch (Exception var3) {
return def;
}
}
public static long getLongValue(String v) {
return getLongValue(v, -1l);
}
public static long getLongValue(String v, long def) {
try {
return Long.parseLong(v);
} catch (Exception var3) {
return def;
}
}
/**
* 将对象转换程字符串
*
* @param obj 目标对象
* @param def 如果为null时的默认值
* @return
*/
public static String null2String(Object obj, String def) {
return obj == null ? def : obj.toString();
}
public static String null2String(Object obj) {
return null2String(obj, "");
}
public static int getIntValue(Object obj, int def) {
try {
return Integer.parseInt(null2String(obj));
} catch (Exception ex) {
return def;
}
}
// public static Page getPage() {
// HttpServletRequest request = getRequest();
// String num = request.getParameter("pageNum");
// String size = request.getParameter("pageSize");
//
// Page page = new Page(ElogUtils.getIntValue(num, 1), ElogUtils.getIntValue(size, 10));
// return page;
// }
// public static void main(String[] args) {
// //System.out.println(getTableName("select", "from"));
// //DataTypeEnum columnTypeEnum = getEnumFromString(DataTypeEnum.class, "varchar");
// }
public static List switchString(List<Map> list) {
if (list != null) {
return list.stream().map(m -> {
Set<Map.Entry> en = m.entrySet();
for (Map.Entry entry : en) {
if (entry.getValue() != null) {
entry.setValue(String.valueOf(entry.getValue()));
}
}
return m;
}).collect(Collectors.toList());
} else {
return list;
}
}
public static List switchComplexString(List<Map> list) {
if (list != null) {
return list.stream().map(m -> {
Iterator<Map.Entry> iterator = m.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry next = iterator.next();
if (next.getValue() != null) {
if (next.getValue() instanceof Map && "parmas".equals(next.getKey())) {
next.setValue(String.valueOf(next.getValue()));
}
if (next.getValue() instanceof List) {
} else {
next.setValue(String.valueOf(next.getValue()));
}
}
}
return m;
}).collect(Collectors.toList());
} else {
return list;
}
}
/**
* 获取rpc信息客户端ip和来源设备
*
* @param context
*/
public static void initRpcInfo(LoggerContext context) {
User user = context.getUser();
if(user == null){
return;
}
String device = user.getLogintype();
String clientIp = user.getLoginip();
String traceId = "";
if (StringUtils.isEmpty(context.getDevice()) && StringUtils.isNotEmpty(device)) {
context.setDevice(device);
}
if (StringUtils.isEmpty(context.getFromTerminal()) && StringUtils.isNotEmpty(device)) {
context.setFromTerminal(getFromTerminal(device));
}
if (StringUtils.isEmpty(context.getClientIp()) && StringUtils.isNotEmpty(clientIp)) {
context.setClientIp(clientIp);
}
if (StringUtils.isEmpty(context.getBelongMainId()) && StringUtils.isNotEmpty(traceId)) {
context.setBelongMainId(traceId);
}
}
public static String getFromTerminal(String device) {
String setFT = "";
if (StringUtils.isNotEmpty(device)) {
if (!device.contains("wxwork") && device.contains("MicroMessenger")) {//来自微信
setFT = FromTerminalType.MICO_MSG.getCode();
} else if (device.contains("wxwork") && device.contains("MicroMessenger")) {//企业微信
setFT = FromTerminalType.WECHAT.getCode();
} else if (device.contains("iPhone") && device.contains("Mac")) {//来自 Iphone
setFT = FromTerminalType.IOS.getCode();
} else if (device.contains("Mac OS") && !device.contains("iPhone") && device.contains("weapp-pc")) {//来自 mac_client
setFT = FromTerminalType.MAC_CLIENT.getCode();//mac_client
} else if (!device.contains("wxwork") && device.contains("Mobile")) {//移动端
setFT = FromTerminalType.H5.getCode();
} else if (device.contains("Android") && !device.contains("wxwork")) {//来自安卓 包含安卓并且不包含微信
setFT = FromTerminalType.ANDROID.getCode();
} else {//pc
setFT = FromTerminalType.PC.getCode();
}
}
return setFT;
}
/**
* sql连接条件注入sql
*
* @param condition
* @return
*/
public static String checkConditionSql(String condition) {
if ("AND".equalsIgnoreCase(condition) ||
"OR".equalsIgnoreCase(condition)
) {
return condition;
}
return "AND";
}
public static String checkTypeSql(String type) {
if ("LIKE".equalsIgnoreCase(type) ||
"IN".equalsIgnoreCase(type) ||
"!<>".equalsIgnoreCase(type) ||
"!=".equalsIgnoreCase(type) ||
"BETWEEN".equalsIgnoreCase(type) ||
"IS NULL".equalsIgnoreCase(type) ||
"IS NULL".equalsIgnoreCase(type) ||
"=".equalsIgnoreCase(type) ||
"IS NOT NULL".equalsIgnoreCase(type)) {
return type;
}
return "=";
}
/**
* sql条件防止注入
*
* @param value
* @return
*/
public static String checkValSql(String value) {
Pattern p = Pattern.compile("\\s+");
Matcher m = p.matcher(value);
String val = m.replaceAll(" ");
String[] keywords = {"master", "truncate", "declare", "alert", "create", "drop", "version",
"show", "table", "index", "insert", "into", "from",
"insert", "select", "delete", "update", "chr", "mid", "master", "truncate", "char", "declare", "union"};
int count = 0;
String filterVal = "";
for (String keyddlword : keywords) {
if (val.toLowerCase().contains(keyddlword)) {
count++;
if (count == 1) {
filterVal = keyddlword;
}
}
}
if (count > 2) {
return filterVal;
}
// value = SecurityUtil.ecodeForSql(value);
return value;
}
/**
* 压缩工具类-
*
* @param str
* @return desc:version 0.0.1 基于jdk自带 GZIP 压缩。最后转成base64。
* 市面上有其他压缩像jdk 的 deflate 可以设置压缩级别,但是都是主动的,需要改业务方法,
* snappy 压缩适用于大数据压缩。大数据量比较快 hadoop首选但是压缩后比例比较大。
* xz 下的 压缩比率大,但是解压比较慢-不提倡,空间换时间了
* common下的压缩其实和jdk差不多网上说优于jdk但是相差不大。
* weaver 压缩基于jdk
*/
public static String compress(String str) {
if (str == null || str.trim().length() == 0) {
return str;
}
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out)) {
gzip.write(str.getBytes());
gzip.close();
return Base64.getEncoder().encodeToString(out.toByteArray());
} catch (Exception e) {
logger.error("压缩失败", e.getMessage());
return str;
}
}
/**
* 解压缩
*
* @param str
* @return
*/
public static String uncompress(String str) {
byte[] decode = Base64.getDecoder().decode(str);
if (str == null || str.trim().length() == 0) {
return str;
}
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(decode)) {
GZIPInputStream ungzip = new GZIPInputStream(in);
byte[] buffer = new byte[2048];
int n;
while ((n = ungzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
return new String(out.toByteArray());
} catch (Exception e) {
logger.error("解缩失败:{}", e.getMessage());
return str;
}
}
public static <T> LoggerContext<T> getEsField(LoggerContext<T> context, String field) {
switch (field.toLowerCase()) {
case "interfacename":
context.setInterfaceName("");
break;
case "operatetype":
context.setOperateType("");
break;
case "operatedesc":
context.setOperatedesc("");
break;
case "params":
context.setParamsStr("ES");
break;
case "clientip":
context.setClientIp("");
break;
case "groupnamelabel":
context.setGroupNameLabel("");
break;
case "redoservice":
context.setRedoService("");
break;
case "redocontext":
context.setRedoContextStr("");
break;
case "cancelservice":
context.setCancelService("");
break;
case "cancelcontext":
context.setCancelContextStr("");
break;
case "device":
context.setDevice("");
break;
case "groupid":
context.setGroupId("");
break;
case "belongmainid":
context.setBelongMainId("");
break;
case "requesturl":
context.setRequestUrl("");
break;
case "requesturi":
context.setRequestUri("");
break;
case "log_result":
context.setResult("");
break;
case "fromterminal":
context.setFromTerminal("");
break;
case "resultdesc":
context.setResultDesc("");
break;
case "old_content":
context.setOld_content("");
break;
case "link_type":
context.setLink_type("");
break;
}
return context;
}
public static String[] getESfields(String value) {
String[] split = value.split(",");
List<String> list = new ArrayList<>();
for (String s : split) {
switch (s.toLowerCase()) {
case "interfacename":
list.add("interfacename");
break;
case "operatetype":
list.add("operatetype");
break;
case "operatedesc":
list.add("operatedesc");
break;
case "params":
list.add("params");
break;
case "clientip":
list.add("clientip");
break;
case "groupnamelabel":
list.add("groupnamelabel");
break;
case "redoservice":
list.add("redoservice");
break;
case "redocontext":
list.add("redocontext");
break;
case "cancelservice":
list.add("cancelservice");
break;
case "cancelcontext":
list.add("cancelcontext");
break;
case "device":
list.add("device");
break;
case "groupid":
list.add("groupid");
break;
case "belongmainid":
list.add("belongmainid");
break;
case "requesturl":
list.add("requesturl");
break;
case "requesturi":
list.add("requesturi");
break;
case "log_result":
list.add("logResult");
break;
case "fromterminal":
list.add("fromterminal");
break;
case "resultdesc":
list.add("resultdesc");
break;
case "old_content":
list.add("oldContent");
break;
case "link_type":
list.add("linkType");
break;
}
}
//list转为数组
if (list.size() > 0) {
String[] strings = list.toArray(new String[list.size()]);
return strings;
}
return null;
}
public static String handleClobColumn(String value) {
// 处理超长字符串oracle插入报错ORA-01704: string literal too long
if (StringUtils.isBlank(value)){
return "";
}
StringBuilder formatValue = new StringBuilder();
String[] split = StrUtil.split(value, 1000);
for (int i = 0; i < split.length; i++) {
formatValue.append("TO_CLOB('").append(split[i]).append("')");
if (i != split.length - 1) {
formatValue.append("||");
}
}
return formatValue.toString();
}
}