1.直接存储日志到指定文件夹
package com.example.demo.log.util;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class logUtil {
private static String log_path = getBasePath("card");
private static String log_name = "card";
private static boolean console_out = true;
private static String update_hz = "yyyy-MM-dd-HH";
private static long max_log_size = 1024 * 1024 * 10;
public static void info(String msg) {
runWrite(msg, log_path, log_name + "_info");
}
public static void debug(String msg) {
runWrite(msg, log_path, log_name + "_debug");
}
public static void error(String msg) {
runWrite(msg, log_path, log_name + "_error");
}
public static void exception(Exception e) {
String errorMessage = e.getMessage() + "";
StackTraceElement[] eArray = e.getCause().getStackTrace();
for (int i = 0; i < eArray.length; i++) {
String className = e.getCause().getStackTrace()[i].getClassName();
String MethodName = e.getCause().getStackTrace()[i].getMethodName();
int LineNumber = e.getCause().getStackTrace()[i].getLineNumber();
errorMessage = errorMessage + "\n\t---" + className + "." + MethodName + ",\tline:" + LineNumber;
}
logResult(errorMessage, log_path, log_name + "_exception");
}
public static String getBasePath(String type) {
String fPath = "/Users/yz/data/BILogs" + File.separator + type + File.separator;
return fPath;
}
public static void logResult(String sWord) {
runWrite(sWord, log_path, log_name);
}
public static void logResult(String sWord, String logPath, String logName) {
FileWriter writer = null;
try {
File dir = new File(logPath);
if (!dir.exists()) {
dir.mkdirs();
}
String dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
File f = new File(logPath + logName + "_" + new SimpleDateFormat(update_hz).format(new Date()) + ".txt");
if (!f.exists()) {
f.createNewFile();
sWord = "AllMing 日志\r\n" + "[" + dt + "]\t" + sWord;
} else {
long logSize = f.length();
if (logSize >= max_log_size) {
String backLogName = logPath + logName
+ new SimpleDateFormat("_yyyy-MM-dd.HHmmss.SSS").format(new Date()) + ".txt";
f.renameTo(new File(backLogName));
}
}
writer = new FileWriter(f, true);
writer.write("[" + dt + "]\t" + sWord + "\r\n");
if (console_out) {
System.out.println("[" + dt + "]\t" + sWord);
}
} catch (Exception e) {
System.out.println("记录日志异常:" + e.toString());
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void runWrite(final String sWord,final String logPath,final String logName) {
new Thread() {
public void run() {
logResult(sWord, logPath, logName);
}
}.start();;
}
public static void main(String[] args) {
for (int i = 0; i <1000; i++) {
info("demo"+i);
}
}
public static void judeDirExists(File file) {
if (file.exists()) {
if (file.isDirectory()) {
System.out.println("dir exists");
} else {
System.out.println("the same name file exists, can not create dir");
}
} else {
System.out.println("dir not exists, create it ...");
file.mkdir();
}
}
}
2.利用切面获取日志并存储到指定位置
package com.aig.payout.log.aspect;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BiOperationLog {
private String ip;
private String url;
private String httpMethod;
private Object requestParams;
private Object result;
private Long timeCost;
private String eventType;
private Object contentInfo;
}
package com.aig.payout.log.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BiOperationLogFlag {
String eventName() default "" ;
}
package com.aig.payout.log.aspect;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import com.aig.payout.common.enums.CardEventEnum;
import com.aig.payout.common.utils.BiLogUtil;
import com.aig.payout.common.utils.BiLogVo;
import com.aig.payout.common.utils.IPUtil;
import com.aig.payout.log.annotation.BiOperationLogFlag;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
@Aspect
@Component
@Slf4j
public class BiOperationLogAspect {
private static final String UNKNOWN = "unknown";
@Pointcut("@annotation(com.aig.payout.log.annotation.BiOperationLogFlag)")
public void biLog() {
}
@Autowired
private BiLogUtil biLogUtil;
@Around("biLog()")
public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
String ip = IPUtil.getIpAdd();
long startTime = System.currentTimeMillis();
Object result = point.proceed();
final BiOperationLog operationLog = BiOperationLog.builder()
.ip(ip)
.url(request.getRequestURL().toString())
.httpMethod(request.getMethod())
.requestParams(getNameAndValue(point))
.result(result)
.eventType(getControllerMethodEvent(point))
.contentInfo(result)
.timeCost(System.currentTimeMillis() - startTime)
.build();
setBiLog(operationLog);
log.info("Request Log Info : {}", JSONUtil.toJsonStr(operationLog));
return result;
}
private void setBiLog(BiOperationLog operationLog) {
log.info("打印BI日志响应内容是:{}",operationLog);
BiLogVo biLogVo = new BiLogVo();
biLogVo.setClientIp(operationLog.getIp());
biLogVo.setEventType(CardEventEnum.getEventByMethod(operationLog.getEventType()));
biLogVo.setContent(operationLog.getContentInfo());
biLogUtil.info(biLogVo, "card");
}
private Map<String, Object> getNameAndValue(ProceedingJoinPoint joinPoint) {
final Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
final String[] names = methodSignature.getParameterNames();
final Object[] args = joinPoint.getArgs();
if (ArrayUtil.isEmpty(names) || ArrayUtil.isEmpty(args)) {
return Collections.emptyMap();
}
if (names.length != args.length) {
log.warn("{}方法参数名和参数值数量不一致", methodSignature.getName());
return Collections.emptyMap();
}
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < names.length; i++) {
map.put(names[i], args[i]);
}
return map;
}
public static String getIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
String comma = ",";
String localhost = "127.0.0.1";
if (ip.contains(comma)) {
ip = ip.split(",")[0];
}
if (localhost.equals(ip)) {
try {
ip = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
log.error(e.getMessage(), e);
}
}
return ip;
}
public static String getControllerMethodEvent(JoinPoint point) throws Exception {
String targetName = point.getTarget().getClass().getName();
String methodName = point.getSignature().getName();
Object[] args = point.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String eventName = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == args.length) {
eventName = method.getAnnotation(BiOperationLogFlag.class).eventName();
break;
}
}
}
return eventName;
}
}