这个小案例是在实际开发过程中,首先想要获取远端客户的简单方法是在Controller的参入参数中添加? HttpServletRequest request? 获取相关参数,然后根据? request.getRemoteAddr(),获取到具体的客户端IP地址。
public ResultEntity createByDdl(@RequestBody NewTableCrtParam tableCrtParam,HttpServletRequest request) throws Exception {
request.getRemoteAddr();
}
我这的需求是:请求方式 ? ?Post请求
???????????????????????? 入参: 公共字段+各日志类型字段
示例:
Web操作日志入参示例
{
????
??"OperaIP":"172.26.96.21",
??"IP":"10.142.101.82",
??"Loglevel":"Info",
??"Errorcode":"",
??"Alerting":"",
??"Loginfotype":"0100100101",
"InnerLogCode":"tydic_001_01",
"InnerLogType":"001"
"LogInfo":{
"Button":"002",
????"Operatpye":"02",
????"Operacontent":"",
????"Operaresult":"1",
????"AccessAddress":"访问地址(url)"
}
}
返参示例
{
"ReturnCode":"10000",
"ReturnMessage":"成功"
}
在LogInfo字段里存放Web操作日志、Hive操作日志等详细信息...然后需要在一个方法内同时实现Web操作日志和Hive操作日志的异步请求。
首先我面临的第一个问题是如何保存参数,方法一:使用两个Map分别存储:?公共字段+LogIngfo(web操作日志)、?公共字段+LogInfo(Hive操作日志);这样就导致公共字段存储了两次,不建议采取.....
这里需要说明Loginfo也是一个Map,方式一操作的话,一共需要创建4个Map来存储
方法二:我们将Loginfo的Web操作日志和Hive操作日志分别作为两个Map,用一个大的Map来存储这两个...这样也会产生一个问题,就是第一个Map使用了Loginfo以后,第二个Loginfo就会覆盖之前的....
方法三:我们将一些不可变的参数放入配置文件,比如访问url、模块名等等,然后通过读取配置文件的参数对日志参数进行填补,在结合方法二进行装配.....
具体实现如下:
1、application.yml文件添加:

2、 使用@ConfigurationProperties(prefix = "system-log-param")对配置文件参数进行封装:

?3、编写公共类CommonUtil,方便调用
public class CommonUtil {
private final SystemLogParam systemLogParam;
@Autowired
public CommonUtil(SystemLogParam systemLogParam) {
this.systemLogParam = systemLogParam;
}
public void SystemLog ( HttpServletRequest request, Map logInfoMap){
Map RqMap=new HashMap();
// 入参:公共字段+各日志类型字段
RqMap.put("Syscode",systemLogParam.getSysCode());
RqMap.put("Sysfunccode",systemLogParam.getSysFunCcode());
RqMap.put("Appname",systemLogParam.getAppName());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String Datetime = sdf.format(new Date());
RqMap.put("Datetime",Datetime);
RqMap.put("Operaidentification", SessionUtil.getUserAccount()); //用户账号
RqMap.put("OperaIP",request.getRemoteAddr()); //获取客户机IP
try{
RqMap.put("IP", InetAddress.getLocalHost().getHostAddress()); //获取主机IP
}catch (Exception e){
e.printStackTrace();
}
RqMap.put("Loglevel","Info");
RqMap.put("Errorcode","");
RqMap.put("Alerting","");
RqMap.put("Loginfotype","0100100101");
RqMap.put("InnerLogCode","tydic_001_01");
RqMap.put("InnerLogType","001");
RqMap.put("LogInfo",logInfoMap);
//执行请求方法
Map hRsMap = new HashMap();
try {
String url=systemLogParam.getSystemLogUrl();
hRsMap= OpenRestUtil.doPost(url, Map.class, RqMap, null);
}catch (Exception e) {
e.printStackTrace();
}
}
}
4、编写好异步实现方法:
/**
* 异步处理日志信息new(共用一个线程)
*/
private class asyncCallAisainfo implements Runnable {
private final Map<String, Object> loginfoMap;
private final HttpServletRequest request;
public asyncCallAisainfo(Map loginfoMap,HttpServletRequest request) {
this.loginfoMap = loginfoMap;
this.request = request;
}
//Runnable接口中的抽象方法
@Override
public void run() {
try {
logger.info("线程启动");
commonUtil.SystemLog(request,loginfoMap);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、封装好其他参数,调用异步方法
public List<String> saveMetaData(TableCrtParam tableCrtParam, List<MetaDataInfo> metaList,HttpServletRequest request) {
......
......
....
//Web操作日志
Map WebLogInfo=new HashMap();
WebLogInfo.put("Button","003"); //001下载、002删除、003修改、004导出
WebLogInfo.put("Operatpye","01"); //01增、02删、03查、04改
WebLogInfo.put("Operacontent",""); //操作内容
WebLogInfo.put("Operaresult",tableIdList.size()>0? 1:0); //操作结果(0失败、1 成功)
WebLogInfo.put("AccessAddress",request.getRequestURL()); // 操作者访问的地址
Thread webLogthread = new Thread(new asyncCallAisainfo(WebLogInfo,request));
webLogthread.start();
//Hive操作日志
Map HiveLogInfo=new HashMap();
HiveLogInfo.put("Operaaccount",tableCrtParam.getUserAcct());
HiveLogInfo.put("Operacom",tableCrtParam.getSql()); //操作命令
HiveLogInfo.put("Hivedb",tableCrtParam.getDbName());
HiveLogInfo.put("Hivetable",tableCrtParam.getTableCode());
HiveLogInfo.put("Hivetablestoragepath",ti.getLocationPath()); //Hive表所在的存储路径
HiveLogInfo.put("Operationtype","创建表"); //操作类型:创建表、修改表、删除表等,
HiveLogInfo.put("Operationresults",tableIdList.size()>0? 1:0); //操作结果(0失败、1 成功)
HiveLogInfo.put("Datatypeidentification","未提供相关查询接口"); //数据类型标识
Thread hiveLogthread = new Thread(new asyncCallAisainfo(HiveLogInfo,request));
hiveLogthread.start();
}
以上主要的思路就是:第一将非动态参数放入配置文件,可以对全局进行修改;第二,分别封装公共字段和各个子字段使用统一方法进行调用;最后进行异步实现。
|