Commit ea245913781d6abcaab5195f0d447ceb89e7e885
1 parent
2987450f
操作日志
Showing
15 changed files
with
618 additions
and
131 deletions
src/main/java/com/bsth/Application.java
| ... | ... | @@ -16,7 +16,7 @@ import org.springframework.context.annotation.Primary; |
| 16 | 16 | @SpringBootApplication |
| 17 | 17 | public class Application extends SpringBootServletInitializer { |
| 18 | 18 | |
| 19 | - public static ScheduledExecutorService mainServices = Executors.newScheduledThreadPool(11); | |
| 19 | + public static ScheduledExecutorService mainServices = Executors.newScheduledThreadPool(12); | |
| 20 | 20 | |
| 21 | 21 | @Override |
| 22 | 22 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { | ... | ... |
src/main/java/com/bsth/ServiceStateTest.java
| ... | ... | @@ -3,8 +3,8 @@ package com.bsth; |
| 3 | 3 | public class ServiceStateTest { |
| 4 | 4 | |
| 5 | 5 | public static void main(String[] args) { |
| 6 | - System.out.println("运营状态:" + getService(603979776)); | |
| 7 | - System.out.println("上下行:" + getUpOrDown(603979776)); | |
| 6 | + System.out.println("运营状态:" + getService(268435456)); | |
| 7 | + System.out.println("上下行:" + getUpOrDown(268435456)); | |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | /** | ... | ... |
src/main/java/com/bsth/StartCommand.java
| ... | ... | @@ -23,37 +23,6 @@ public class StartCommand implements CommandLineRunner{ |
| 23 | 23 | @Autowired |
| 24 | 24 | SecurityMetadataSourceService invocationSecurityMetadataSourceService; |
| 25 | 25 | |
| 26 | - //public static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(8); | |
| 27 | - | |
| 28 | - /*@Autowired | |
| 29 | - GpsRealDataRefreshThread gpsRefreshThread; | |
| 30 | - @Autowired | |
| 31 | - GetSchedulePlanThread getSchedulePlanThread; | |
| 32 | - @Autowired | |
| 33 | - CommonRefreshThread commonRefreshThread; | |
| 34 | - @Autowired | |
| 35 | - DirectivePersistenceThread directivePersistenceThread; | |
| 36 | - @Autowired | |
| 37 | - SchedulePersistenceThread SchedulePersistenceThread; | |
| 38 | - @Autowired | |
| 39 | - ArrivalThread gpsArrivalStationThread; | |
| 40 | - @Autowired | |
| 41 | - FirstScheduleIssuedThread firstScheduleIssuedThread; | |
| 42 | - | |
| 43 | - @Autowired | |
| 44 | - DirectiveService directiveService; | |
| 45 | - @Autowired | |
| 46 | - DirectiveBuffer directiveBuffer; | |
| 47 | - @Autowired | |
| 48 | - CarConfigInfoRepository carConfigInfoRepository; | |
| 49 | - | |
| 50 | - @Autowired | |
| 51 | - GpsOfflineMonitorThread gpsOfflineMonitorThread;*/ | |
| 52 | - | |
| 53 | - /*final static Long HOUR_TIME = 1000 * 60 * 60L; | |
| 54 | - | |
| 55 | - final static int HOUR_SECOND = 60 * 60;*/ | |
| 56 | - | |
| 57 | 26 | @Override |
| 58 | 27 | public void run(String... arg0){ |
| 59 | 28 | |
| ... | ... | @@ -61,91 +30,6 @@ public class StartCommand implements CommandLineRunner{ |
| 61 | 30 | //启动时加载所有资源 |
| 62 | 31 | invocationSecurityMetadataSourceService.loadResourceDefine(); |
| 63 | 32 | |
| 64 | - /** | |
| 65 | - * 车辆,设备,公司等常用的映射数据,每两小时刷新一次 | |
| 66 | - *//* | |
| 67 | - commonRefreshThread.start(); | |
| 68 | - scheduler.scheduleWithFixedDelay(commonRefreshThread, HOUR_SECOND * 2 , HOUR_SECOND * 2, TimeUnit.SECONDS); | |
| 69 | - //等映射数据加载完......睡一会吧 | |
| 70 | - Thread.sleep(4000); | |
| 71 | - | |
| 72 | - *//** | |
| 73 | - * GPS实时数据更新 线程 | |
| 74 | - * 每8秒和网关HTTP接口同步一次 | |
| 75 | - *//* | |
| 76 | - scheduler.scheduleWithFixedDelay(gpsRefreshThread, 0, 8, TimeUnit.SECONDS); | |
| 77 | - | |
| 78 | - *//** | |
| 79 | - * GPS 监控设备掉线行为 | |
| 80 | - * 每分钟检测一次 | |
| 81 | - *//* | |
| 82 | - scheduler.scheduleWithFixedDelay(gpsOfflineMonitorThread, 60, 60, TimeUnit.SECONDS); | |
| 83 | - | |
| 84 | - | |
| 85 | - *//** | |
| 86 | - * 每天 凌晨 2 点 抓取当天实际排班 | |
| 87 | - *//* | |
| 88 | - //启动时先run一次 | |
| 89 | - getSchedulePlanThread.start(); | |
| 90 | - scheduler.scheduleAtFixedRate(getSchedulePlanThread | |
| 91 | - , ((DateUtils.getTimesnight2() + HOUR_TIME * 2) - System.currentTimeMillis()) / 1000 | |
| 92 | - , 60 * 60 * 24, TimeUnit.SECONDS); | |
| 93 | - | |
| 94 | - *//** | |
| 95 | - * 调度指令两分钟入库一次 | |
| 96 | - * 指令会缓存在内存,直到收到所有响应再入库 | |
| 97 | - *//* | |
| 98 | - //从数据库恢复初始数据 | |
| 99 | - directiveBuffer.recovery(); | |
| 100 | - scheduler.scheduleWithFixedDelay(directivePersistenceThread, 20, 60 * 2, TimeUnit.SECONDS); | |
| 101 | - | |
| 102 | - *//** | |
| 103 | - * 每分钟将有变更的班次入库(不包括子任务) | |
| 104 | - * 单纯为了提高 线调操作 的响应速度 | |
| 105 | - *//* | |
| 106 | - scheduler.scheduleWithFixedDelay(SchedulePersistenceThread, 60 * 1, 60 * 1, TimeUnit.SECONDS); | |
| 107 | - | |
| 108 | - *//** | |
| 109 | - * 每15秒从数据库抓取到离站信息和班次匹配 | |
| 110 | - * (网关生成的到离站数据也是延迟批量入库,所以缩短该线程执行周期并不会提高 “实际到离站” 的实时性) | |
| 111 | - *//* | |
| 112 | - scheduler.scheduleWithFixedDelay(gpsArrivalStationThread, 35, 15, TimeUnit.SECONDS); | |
| 113 | - | |
| 114 | - *//** | |
| 115 | - * 首个调度指令下发(2分钟运行一次) | |
| 116 | - * 每辆车的第一个调度指令由该线程下发 | |
| 117 | - * 后续班次由 “实际终点到达” 事件触发指令下发 | |
| 118 | - *//* | |
| 119 | - scheduler.scheduleWithFixedDelay(firstScheduleIssuedThread, 60 , 60 * 2, TimeUnit.SECONDS); | |
| 120 | - */ | |
| 121 | - | |
| 122 | -/* new Timer().schedule(new TimerTask() { | |
| 123 | - | |
| 124 | - @Override | |
| 125 | - public void run() { | |
| 126 | - List<CarConfigInfo> ccis = carConfigInfoRepository.findAll(); | |
| 127 | - Cars car; | |
| 128 | - Line line; | |
| 129 | - String lineCode; | |
| 130 | - System.out.println("ccis size: " + ccis.size()); | |
| 131 | - for(CarConfigInfo cci : ccis){ | |
| 132 | - car = cci.getCl(); | |
| 133 | - line = cci.getXl(); | |
| 134 | - lineCode = line.getLineCode(); | |
| 135 | - | |
| 136 | - String data = directiveService.createDeviceRefreshData(CommonMapped.vehicDeviceBiMap.inverse().get(car.getInsideCode()) | |
| 137 | - , Integer.parseInt(lineCode)); | |
| 138 | - System.out.println(data); | |
| 139 | - int code = HttpUtils.postJson(data); | |
| 140 | - System.out.println("车辆:" + car.getInsideCode() + "刷新线路:" + line.getLineCode()); | |
| 141 | - code = directiveService.lineChange(car.getInsideCode(), Integer.parseInt(lineCode)); | |
| 142 | - //directiveService.send60Phrase(car.getInsideCode(), ""); | |
| 143 | - System.out.println("返回值:" + code); | |
| 144 | - } | |
| 145 | - | |
| 146 | - } | |
| 147 | - }, 1000 * 10);*/ | |
| 148 | - | |
| 149 | 33 | } catch (Exception e) { |
| 150 | 34 | e.printStackTrace(); |
| 151 | 35 | } | ... | ... |
src/main/java/com/bsth/WebAppConfiguration.java
| ... | ... | @@ -2,18 +2,21 @@ package com.bsth; |
| 2 | 2 | |
| 3 | 3 | import javax.servlet.Filter; |
| 4 | 4 | |
| 5 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 5 | 6 | import org.springframework.boot.context.embedded.FilterRegistrationBean; |
| 6 | 7 | import org.springframework.context.annotation.Bean; |
| 7 | 8 | import org.springframework.context.annotation.ComponentScan; |
| 8 | 9 | import org.springframework.context.annotation.Configuration; |
| 9 | 10 | import org.springframework.web.filter.CharacterEncodingFilter; |
| 10 | 11 | import org.springframework.web.filter.HttpPutFormContentFilter; |
| 12 | +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | |
| 11 | 13 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; |
| 12 | 14 | import org.springframework.web.socket.config.annotation.EnableWebSocket; |
| 13 | 15 | import org.springframework.web.socket.config.annotation.WebSocketConfigurer; |
| 14 | 16 | import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; |
| 15 | 17 | |
| 16 | 18 | import com.bsth.filter.ResourceFilter; |
| 19 | +import com.bsth.oplog.http.HttpOpLogInterceptor; | |
| 17 | 20 | import com.bsth.websocket.WebSocketHandshakeInterceptor; |
| 18 | 21 | import com.bsth.websocket.handler.RealControlSocketHandler; |
| 19 | 22 | |
| ... | ... | @@ -22,12 +25,12 @@ import com.bsth.websocket.handler.RealControlSocketHandler; |
| 22 | 25 | @ComponentScan |
| 23 | 26 | public class WebAppConfiguration extends WebMvcConfigurerAdapter implements WebSocketConfigurer{ |
| 24 | 27 | |
| 28 | + @Autowired | |
| 29 | + HttpOpLogInterceptor httpOpLogInterceptor; | |
| 30 | + | |
| 25 | 31 | /** |
| 26 | - * | |
| 27 | 32 | * @Title: httpPutFormContentFilter |
| 28 | 33 | * @Description: TODO(弥补浏览器不支持PUT/DELETE,对携带 _method 参数的请求进行转换) |
| 29 | - * @return Filter 返回类型 | |
| 30 | - * @throws | |
| 31 | 34 | */ |
| 32 | 35 | @Bean |
| 33 | 36 | public Filter httpPutFormContentFilter() { |
| ... | ... | @@ -35,11 +38,8 @@ public class WebAppConfiguration extends WebMvcConfigurerAdapter implements WebS |
| 35 | 38 | } |
| 36 | 39 | |
| 37 | 40 | /** |
| 38 | - * | |
| 39 | 41 | * @Title: characterEncodingFilter |
| 40 | 42 | * @Description: TODO(编码过滤器) |
| 41 | - * @return Filter 返回类型 | |
| 42 | - * @throws | |
| 43 | 43 | */ |
| 44 | 44 | @Bean |
| 45 | 45 | public Filter characterEncodingFilter(){ |
| ... | ... | @@ -50,8 +50,6 @@ public class WebAppConfiguration extends WebMvcConfigurerAdapter implements WebS |
| 50 | 50 | * |
| 51 | 51 | * @Title: resourceFilterRegistration |
| 52 | 52 | * @Description: TODO(静态资源过滤器, 只处理 /pages 目录下的片段请求 ) |
| 53 | - * @return FilterRegistrationBean 返回类型 | |
| 54 | - * @throws | |
| 55 | 53 | */ |
| 56 | 54 | @Bean |
| 57 | 55 | public FilterRegistrationBean resourceFilterRegistration(){ |
| ... | ... | @@ -59,8 +57,18 @@ public class WebAppConfiguration extends WebMvcConfigurerAdapter implements WebS |
| 59 | 57 | registration.setFilter(new ResourceFilter()); |
| 60 | 58 | registration.addUrlPatterns("/pages/*"); |
| 61 | 59 | return registration; |
| 62 | - } | |
| 63 | - | |
| 60 | + } | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * | |
| 64 | + * @Title: addInterceptors | |
| 65 | + * @Description: TODO(HTTP结构化访问日志记录 ) | |
| 66 | + | |
| 67 | + @Override | |
| 68 | + public void addInterceptors(InterceptorRegistry registry) { | |
| 69 | + registry.addInterceptor(httpOpLogInterceptor); | |
| 70 | + }*/ | |
| 71 | + | |
| 64 | 72 | @Override |
| 65 | 73 | public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { |
| 66 | 74 | //线调webSocket | ... | ... |
src/main/java/com/bsth/data/BasicData.java
| ... | ... | @@ -20,6 +20,7 @@ import com.bsth.entity.Line; |
| 20 | 20 | import com.bsth.entity.Station; |
| 21 | 21 | import com.bsth.entity.StationRoute; |
| 22 | 22 | import com.bsth.entity.schedule.CarConfigInfo; |
| 23 | +import com.bsth.oplog.normal.OpLogger; | |
| 23 | 24 | import com.bsth.repository.CarParkRepository; |
| 24 | 25 | import com.bsth.repository.CarsRepository; |
| 25 | 26 | import com.bsth.repository.LineRepository; |
| ... | ... | @@ -100,6 +101,8 @@ public class BasicData implements CommandLineRunner{ |
| 100 | 101 | @Autowired |
| 101 | 102 | StationRouteRepository stationRouteRepository; |
| 102 | 103 | |
| 104 | + @Autowired | |
| 105 | + OpLogger opLog; | |
| 103 | 106 | |
| 104 | 107 | @Override |
| 105 | 108 | public void run() { |
| ... | ... | @@ -119,6 +122,8 @@ public class BasicData implements CommandLineRunner{ |
| 119 | 122 | |
| 120 | 123 | loadStationRouteInfo(); |
| 121 | 124 | logger.info("加载基础数据成功!," ); |
| 125 | + | |
| 126 | + opLog.info("load_basic"); | |
| 122 | 127 | }catch(Exception e){ |
| 123 | 128 | logger.error("加载基础数据时出现异常," , e); |
| 124 | 129 | } | ... | ... |
src/main/java/com/bsth/oplog/Level.java
0 → 100644
src/main/java/com/bsth/oplog/Log.java
0 → 100644
| 1 | +package com.bsth.oplog; | |
| 2 | + | |
| 3 | +import java.util.Date; | |
| 4 | + | |
| 5 | +public class Log { | |
| 6 | + | |
| 7 | + private String userName; | |
| 8 | + | |
| 9 | + private Long timestamp; | |
| 10 | + | |
| 11 | + private String type; | |
| 12 | + | |
| 13 | + private String level; | |
| 14 | + | |
| 15 | + private String path; | |
| 16 | + | |
| 17 | + private String serverIp; | |
| 18 | + | |
| 19 | + private String clientIp; | |
| 20 | + | |
| 21 | + private String httpData; | |
| 22 | + | |
| 23 | + private Date month; | |
| 24 | + | |
| 25 | + private String callerClass; | |
| 26 | + | |
| 27 | + private String callerMethod; | |
| 28 | + | |
| 29 | + private Integer lineNumber; | |
| 30 | + | |
| 31 | + public String getPath() { | |
| 32 | + return path; | |
| 33 | + } | |
| 34 | + | |
| 35 | + public void setPath(String path) { | |
| 36 | + this.path = path; | |
| 37 | + } | |
| 38 | + | |
| 39 | + public String getServerIp() { | |
| 40 | + return serverIp; | |
| 41 | + } | |
| 42 | + | |
| 43 | + public void setServerIp(String serverIp) { | |
| 44 | + this.serverIp = serverIp; | |
| 45 | + } | |
| 46 | + | |
| 47 | + public String getHttpData() { | |
| 48 | + return httpData; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public void setHttpData(String httpData) { | |
| 52 | + this.httpData = httpData; | |
| 53 | + } | |
| 54 | + | |
| 55 | + public Date getMonth() { | |
| 56 | + return month; | |
| 57 | + } | |
| 58 | + | |
| 59 | + public void setMonth(Date month) { | |
| 60 | + this.month = month; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public String getType() { | |
| 64 | + return type; | |
| 65 | + } | |
| 66 | + | |
| 67 | + public void setType(String type) { | |
| 68 | + this.type = type; | |
| 69 | + } | |
| 70 | + | |
| 71 | + public String getLevel() { | |
| 72 | + return level; | |
| 73 | + } | |
| 74 | + | |
| 75 | + public void setLevel(String level) { | |
| 76 | + this.level = level; | |
| 77 | + } | |
| 78 | + | |
| 79 | + public String getCallerClass() { | |
| 80 | + return callerClass; | |
| 81 | + } | |
| 82 | + | |
| 83 | + public void setCallerClass(String callerClass) { | |
| 84 | + this.callerClass = callerClass; | |
| 85 | + } | |
| 86 | + | |
| 87 | + public String getCallerMethod() { | |
| 88 | + return callerMethod; | |
| 89 | + } | |
| 90 | + | |
| 91 | + public void setCallerMethod(String callerMethod) { | |
| 92 | + this.callerMethod = callerMethod; | |
| 93 | + } | |
| 94 | + | |
| 95 | + public String getClientIp() { | |
| 96 | + return clientIp; | |
| 97 | + } | |
| 98 | + | |
| 99 | + public void setClientIp(String clientIp) { | |
| 100 | + this.clientIp = clientIp; | |
| 101 | + } | |
| 102 | + | |
| 103 | + public String getUserName() { | |
| 104 | + return userName; | |
| 105 | + } | |
| 106 | + | |
| 107 | + public void setUserName(String userName) { | |
| 108 | + this.userName = userName; | |
| 109 | + } | |
| 110 | + | |
| 111 | + public Long getTimestamp() { | |
| 112 | + return timestamp; | |
| 113 | + } | |
| 114 | + | |
| 115 | + public void setTimestamp(Long timestamp) { | |
| 116 | + this.timestamp = timestamp; | |
| 117 | + } | |
| 118 | + | |
| 119 | + public Integer getLineNumber() { | |
| 120 | + return lineNumber; | |
| 121 | + } | |
| 122 | + | |
| 123 | + public void setLineNumber(Integer lineNumber) { | |
| 124 | + this.lineNumber = lineNumber; | |
| 125 | + } | |
| 126 | +} | ... | ... |
src/main/java/com/bsth/oplog/Type.java
0 → 100644
src/main/java/com/bsth/oplog/db/DBHelper.java
0 → 100644
| 1 | +package com.bsth.oplog.db; | |
| 2 | + | |
| 3 | +import java.util.LinkedList; | |
| 4 | +import java.util.concurrent.TimeUnit; | |
| 5 | + | |
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 7 | +import org.springframework.boot.CommandLineRunner; | |
| 8 | +import org.springframework.stereotype.Component; | |
| 9 | + | |
| 10 | +import com.bsth.Application; | |
| 11 | +import com.bsth.oplog.Log; | |
| 12 | +import com.bsth.oplog.db.mysql.DBPersistence; | |
| 13 | + | |
| 14 | +//@Component | |
| 15 | +public class DBHelper implements CommandLineRunner{ | |
| 16 | + | |
| 17 | + private final static int maxBufSize = 1000; | |
| 18 | + private final static int fixedMinute = 1; | |
| 19 | + | |
| 20 | + private static LinkedList<Log> buffer = new LinkedList<>(); | |
| 21 | + | |
| 22 | + @Autowired | |
| 23 | + private FixedTimePersistenceThread fixedTimeThread; | |
| 24 | + | |
| 25 | + public void save(Log log){ | |
| 26 | + buffer.add(log); | |
| 27 | + | |
| 28 | + if(buffer.size() >= maxBufSize) | |
| 29 | + fixedTimeThread.start(); | |
| 30 | + } | |
| 31 | + | |
| 32 | + @Component | |
| 33 | + public static class FixedTimePersistenceThread extends Thread{ | |
| 34 | + | |
| 35 | + @Autowired | |
| 36 | + DBPersistence persistence; | |
| 37 | + | |
| 38 | + @Override | |
| 39 | + public void run() { | |
| 40 | + persistence.batchSave(buffer); | |
| 41 | + } | |
| 42 | + } | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + public void run(String... arg0) throws Exception { | |
| 46 | + Application.mainServices.scheduleWithFixedDelay(fixedTimeThread, fixedMinute, fixedMinute, TimeUnit.MINUTES); | |
| 47 | + } | |
| 48 | +} | ... | ... |
src/main/java/com/bsth/oplog/db/mysql/DBPersistence.java
0 → 100644
| 1 | +package com.bsth.oplog.db.mysql; | |
| 2 | + | |
| 3 | +import java.sql.Date; | |
| 4 | +import java.sql.PreparedStatement; | |
| 5 | +import java.sql.SQLException; | |
| 6 | +import java.util.ArrayList; | |
| 7 | +import java.util.LinkedList; | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +import org.slf4j.Logger; | |
| 11 | +import org.slf4j.LoggerFactory; | |
| 12 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 13 | +import org.springframework.jdbc.core.BatchPreparedStatementSetter; | |
| 14 | +import org.springframework.jdbc.core.JdbcTemplate; | |
| 15 | +import org.springframework.stereotype.Component; | |
| 16 | + | |
| 17 | +import com.bsth.oplog.Log; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * | |
| 21 | + * @ClassName: DBPersistence | |
| 22 | + * @Description: TODO(mysql 批量入库) | |
| 23 | + * @author PanZhao | |
| 24 | + * @date 2016年10月20日 上午9:44:00 | |
| 25 | + * | |
| 26 | + */ | |
| 27 | +@Component | |
| 28 | +public class DBPersistence { | |
| 29 | + | |
| 30 | + @Autowired | |
| 31 | + JdbcTemplate jdbcTemplate; | |
| 32 | + | |
| 33 | + Logger logger = LoggerFactory.getLogger(DBPersistence.class); | |
| 34 | + | |
| 35 | + public void batchSave(LinkedList<Log> list){ | |
| 36 | + String sql = "insert into bsth_c_sys_op_log" | |
| 37 | + + "(timestamp, path, type,level, caller_class, caller_method, user_name, client_ip, server_ip, month, http_data, line_number)" | |
| 38 | + + " values(?,?,?,?,?,?,?,?,?,?,?,?)"; | |
| 39 | + | |
| 40 | + | |
| 41 | + List<Log> saveList = new ArrayList<>(list.size()); | |
| 42 | + Log log; | |
| 43 | + while(true){ | |
| 44 | + log = list.poll(); | |
| 45 | + if(log != null) | |
| 46 | + saveList.add(log); | |
| 47 | + else | |
| 48 | + break; | |
| 49 | + } | |
| 50 | + | |
| 51 | + Date month = new Date(System.currentTimeMillis()); | |
| 52 | + | |
| 53 | + try { | |
| 54 | + jdbcTemplate.batchUpdate(sql, new LogBatchPreparedStatementSetter(saveList, month)); | |
| 55 | + } catch (Exception e) { | |
| 56 | + logger.error("操作日志入库失败", e); | |
| 57 | + } | |
| 58 | + } | |
| 59 | + | |
| 60 | + private class LogBatchPreparedStatementSetter implements BatchPreparedStatementSetter{ | |
| 61 | + | |
| 62 | + List<Log> temList; | |
| 63 | + Date month; | |
| 64 | + | |
| 65 | + public LogBatchPreparedStatementSetter(final List<Log> list, Date month){ | |
| 66 | + this.temList = list; | |
| 67 | + this.month = month; | |
| 68 | + } | |
| 69 | + | |
| 70 | + @Override | |
| 71 | + public void setValues(PreparedStatement ps, int i) throws SQLException { | |
| 72 | + Log log = temList.get(i); | |
| 73 | + ps.setLong(1, log.getTimestamp()); | |
| 74 | + ps.setString(2, log.getPath()); | |
| 75 | + ps.setString(3, log.getType()); | |
| 76 | + ps.setString(4, log.getLevel()); | |
| 77 | + ps.setString(5, log.getCallerClass()); | |
| 78 | + ps.setString(6, log.getCallerMethod()); | |
| 79 | + ps.setString(7, log.getUserName()); | |
| 80 | + ps.setString(8, log.getClientIp()); | |
| 81 | + ps.setString(9, log.getServerIp()); | |
| 82 | + ps.setDate(10, month); | |
| 83 | + ps.setString(11, log.getHttpData()); | |
| 84 | + ps.setObject(12, log.getLineNumber()); | |
| 85 | + } | |
| 86 | + | |
| 87 | + @Override | |
| 88 | + public int getBatchSize() { | |
| 89 | + return temList.size(); | |
| 90 | + } | |
| 91 | + } | |
| 92 | +} | ... | ... |
src/main/java/com/bsth/oplog/db/mysql/db.sql
0 → 100644
| 1 | +CREATE TABLE `bsth_c_sys_op_log` ( | |
| 2 | +`timestamp` bigint(20) NOT NULL , | |
| 3 | +`user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , | |
| 4 | +`caller_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , | |
| 5 | +`caller_method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , | |
| 6 | +`client_ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , | |
| 7 | +`http_data` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL , | |
| 8 | +`level` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , | |
| 9 | +`month` date NOT NULL , | |
| 10 | +`path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , | |
| 11 | +`server_ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , | |
| 12 | +`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, | |
| 13 | +`line_number` int(11) NULL DEFAULT NULL | |
| 14 | +) | |
| 15 | +ENGINE=InnoDB | |
| 16 | +DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci | |
| 17 | +ROW_FORMAT=DYNAMIC | |
| 18 | + | |
| 19 | +PARTITION BY RANGE(TO_DAYS (month)) | |
| 20 | +( | |
| 21 | +PARTITION p201610 VALUES LESS THAN (TO_DAYS('2016-11-01')), | |
| 22 | +PARTITION p201611 VALUES LESS THAN (TO_DAYS('2016-12-01')), | |
| 23 | +PARTITION p201612 VALUES LESS THAN (TO_DAYS('2017-01-01')), | |
| 24 | + | |
| 25 | +PARTITION p201701 VALUES LESS THAN (TO_DAYS('2017-02-01')), | |
| 26 | +PARTITION p201702 VALUES LESS THAN (TO_DAYS('2017-03-01')), | |
| 27 | +PARTITION p201703 VALUES LESS THAN (TO_DAYS('2017-04-01')), | |
| 28 | +PARTITION p201704 VALUES LESS THAN (TO_DAYS('2017-05-01')), | |
| 29 | +PARTITION p201705 VALUES LESS THAN (TO_DAYS('2017-06-01')), | |
| 30 | +PARTITION p201706 VALUES LESS THAN (TO_DAYS('2017-07-01')), | |
| 31 | +PARTITION p201707 VALUES LESS THAN (TO_DAYS('2017-08-01')), | |
| 32 | +PARTITION p201708 VALUES LESS THAN (TO_DAYS('2017-09-01')), | |
| 33 | +PARTITION p201709 VALUES LESS THAN (TO_DAYS('2017-10-01')), | |
| 34 | +PARTITION p201710 VALUES LESS THAN (TO_DAYS('2017-11-01')), | |
| 35 | +PARTITION p201711 VALUES LESS THAN (TO_DAYS('2017-12-01')), | |
| 36 | +PARTITION p201712 VALUES LESS THAN (TO_DAYS('2018-01-01')), | |
| 37 | + | |
| 38 | + | |
| 39 | +PARTITION p201801 VALUES LESS THAN (TO_DAYS('2018-02-01')), | |
| 40 | +PARTITION p201802 VALUES LESS THAN (TO_DAYS('2018-03-01')), | |
| 41 | +PARTITION p201803 VALUES LESS THAN (TO_DAYS('2018-04-01')), | |
| 42 | +PARTITION p201804 VALUES LESS THAN (TO_DAYS('2018-05-01')), | |
| 43 | +PARTITION p201805 VALUES LESS THAN (TO_DAYS('2018-06-01')), | |
| 44 | +PARTITION p201806 VALUES LESS THAN (TO_DAYS('2018-07-01')), | |
| 45 | +PARTITION p201807 VALUES LESS THAN (TO_DAYS('2018-08-01')), | |
| 46 | +PARTITION p201808 VALUES LESS THAN (TO_DAYS('2018-09-01')), | |
| 47 | +PARTITION p201809 VALUES LESS THAN (TO_DAYS('2018-10-01')), | |
| 48 | +PARTITION p201810 VALUES LESS THAN (TO_DAYS('2018-11-01')), | |
| 49 | +PARTITION p201811 VALUES LESS THAN (TO_DAYS('2018-12-01')), | |
| 50 | +PARTITION p201812 VALUES LESS THAN (TO_DAYS('2019-01-01')), | |
| 51 | + | |
| 52 | +PARTITION p201901 VALUES LESS THAN (TO_DAYS('2019-02-01')), | |
| 53 | +PARTITION p201902 VALUES LESS THAN (TO_DAYS('2019-03-01')), | |
| 54 | +PARTITION p201903 VALUES LESS THAN (TO_DAYS('2019-04-01')), | |
| 55 | +PARTITION p201904 VALUES LESS THAN (TO_DAYS('2019-05-01')), | |
| 56 | +PARTITION p201905 VALUES LESS THAN (TO_DAYS('2019-06-01')), | |
| 57 | +PARTITION p201906 VALUES LESS THAN (TO_DAYS('2019-07-01')), | |
| 58 | +PARTITION p201907 VALUES LESS THAN (TO_DAYS('2019-08-01')), | |
| 59 | +PARTITION p201908 VALUES LESS THAN (TO_DAYS('2019-09-01')), | |
| 60 | +PARTITION p201909 VALUES LESS THAN (TO_DAYS('2019-10-01')), | |
| 61 | +PARTITION p201910 VALUES LESS THAN (TO_DAYS('2019-11-01')), | |
| 62 | +PARTITION p201911 VALUES LESS THAN (TO_DAYS('2019-12-01')), | |
| 63 | +PARTITION p201912 VALUES LESS THAN (TO_DAYS('2020-01-01')) | |
| 64 | + | |
| 65 | + | |
| 66 | +); | |
| 67 | + | ... | ... |
src/main/java/com/bsth/oplog/http/HttpOpLogInterceptor.java
0 → 100644
| 1 | +package com.bsth.oplog.http; | |
| 2 | + | |
| 3 | +import javax.servlet.http.HttpServletRequest; | |
| 4 | +import javax.servlet.http.HttpServletResponse; | |
| 5 | + | |
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 7 | +import org.springframework.stereotype.Component; | |
| 8 | +import org.springframework.util.AntPathMatcher; | |
| 9 | +import org.springframework.util.PathMatcher; | |
| 10 | +import org.springframework.web.method.HandlerMethod; | |
| 11 | +import org.springframework.web.servlet.HandlerInterceptor; | |
| 12 | +import org.springframework.web.servlet.ModelAndView; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * | |
| 16 | + * @ClassName: HttpOpLogger | |
| 17 | + * @Description: TODO(HTTP 接口日志拦截器) | |
| 18 | + * @author PanZhao | |
| 19 | + * @date 2016年10月20日 上午12:03:11 | |
| 20 | + * | |
| 21 | + */ | |
| 22 | +@Component | |
| 23 | +public class HttpOpLogInterceptor implements HandlerInterceptor { | |
| 24 | + | |
| 25 | + private final PathMatcher pathMatcher = new AntPathMatcher(); | |
| 26 | + | |
| 27 | + // GET 白名单 | |
| 28 | + private String[] httpGetWhiteList = { "/user/login/**", "/user/currentUser", "/dictionary/**", "/module/findByCurrentUser" }; | |
| 29 | + | |
| 30 | + // POST 白名单 | |
| 31 | + private String[] httpPostWhiteList = { | |
| 32 | + | |
| 33 | + }; | |
| 34 | + | |
| 35 | + @Autowired | |
| 36 | + HttpRecorder httpRecorder; | |
| 37 | + | |
| 38 | + @Override | |
| 39 | + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) | |
| 40 | + throws Exception { | |
| 41 | + | |
| 42 | + } | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3) | |
| 46 | + throws Exception { | |
| 47 | + | |
| 48 | + String method = request.getMethod(), path = request.getRequestURI(); | |
| 49 | + // white list | |
| 50 | + String[] whiteList = method == "GET" ? httpGetWhiteList : httpPostWhiteList; | |
| 51 | + | |
| 52 | + if (!isWhiteURL(whiteList, path)) | |
| 53 | + httpRecorder.record(request, (HandlerMethod)arg2); | |
| 54 | + } | |
| 55 | + | |
| 56 | + @Override | |
| 57 | + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { | |
| 58 | + | |
| 59 | + return true; | |
| 60 | + } | |
| 61 | + | |
| 62 | + private boolean isWhiteURL(String[] whiteList, String currentURL) { | |
| 63 | + for (String whiteURL : whiteList) { | |
| 64 | + if (pathMatcher.match(whiteURL, currentURL)) { | |
| 65 | + return true; | |
| 66 | + } | |
| 67 | + } | |
| 68 | + return false; | |
| 69 | + } | |
| 70 | +} | ... | ... |
src/main/java/com/bsth/oplog/http/HttpRecorder.java
0 → 100644
| 1 | +package com.bsth.oplog.http; | |
| 2 | + | |
| 3 | +import java.lang.reflect.Method; | |
| 4 | +import java.net.InetAddress; | |
| 5 | +import java.net.UnknownHostException; | |
| 6 | + | |
| 7 | +import javax.servlet.http.HttpServletRequest; | |
| 8 | + | |
| 9 | +import org.slf4j.Logger; | |
| 10 | +import org.slf4j.LoggerFactory; | |
| 11 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 12 | +import org.springframework.stereotype.Component; | |
| 13 | +import org.springframework.web.method.HandlerMethod; | |
| 14 | + | |
| 15 | +import com.alibaba.fastjson.JSON; | |
| 16 | +import com.bsth.entity.sys.SysUser; | |
| 17 | +import com.bsth.oplog.Level; | |
| 18 | +import com.bsth.oplog.Log; | |
| 19 | +import com.bsth.oplog.Type; | |
| 20 | +import com.bsth.oplog.db.DBHelper; | |
| 21 | +import com.bsth.security.util.SecurityUtils; | |
| 22 | +import com.bsth.util.IpUtils; | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * | |
| 26 | + * @ClassName: HttpRecorder | |
| 27 | + * @Description: TODO(HTTP 日志记录器) | |
| 28 | + * @author PanZhao | |
| 29 | + * @date 2016年10月20日 下午12:56:56 | |
| 30 | + * | |
| 31 | + */ | |
| 32 | +@Component | |
| 33 | +public class HttpRecorder { | |
| 34 | + | |
| 35 | + Logger logger = LoggerFactory.getLogger(HttpRecorder.class); | |
| 36 | + | |
| 37 | + private final static int httpDataMaxLen = 500; | |
| 38 | + | |
| 39 | + @Autowired | |
| 40 | + DBHelper persistenceBuff; | |
| 41 | + | |
| 42 | + public void record(HttpServletRequest request, HandlerMethod method){ | |
| 43 | + Log log = new Log(); | |
| 44 | + | |
| 45 | + Type type = null; | |
| 46 | + switch (request.getMethod()) { | |
| 47 | + case "GET": | |
| 48 | + type = Type.HTTP_GET; | |
| 49 | + break; | |
| 50 | + case "POST": | |
| 51 | + type = Type.HTTP_POST; | |
| 52 | + break; | |
| 53 | + case "DELETE": | |
| 54 | + type = Type.HTTP_DELETE; | |
| 55 | + break; | |
| 56 | + case "PUT": | |
| 57 | + type = Type.HTTP_PUT; | |
| 58 | + break; | |
| 59 | + } | |
| 60 | + log.setType(type.toString()); | |
| 61 | + log.setLevel(Level.INFO.toString()); | |
| 62 | + try { | |
| 63 | + log.setServerIp(InetAddress.getLocalHost().getHostAddress()); | |
| 64 | + } catch (UnknownHostException e) { | |
| 65 | + e.printStackTrace(); | |
| 66 | + } | |
| 67 | + | |
| 68 | + log.setPath(request.getRequestURI()); | |
| 69 | + //Caller | |
| 70 | + Method refMethod = method.getMethod(); | |
| 71 | + log.setCallerClass(refMethod.getDeclaringClass().getName()); | |
| 72 | + log.setCallerMethod(refMethod.getName()); | |
| 73 | + | |
| 74 | + //Primary Key | |
| 75 | + log.setTimestamp(System.currentTimeMillis()); | |
| 76 | + | |
| 77 | + SysUser user = SecurityUtils.getCurrentUser(); | |
| 78 | + if(user != null) | |
| 79 | + log.setUserName(user.getUserName()); | |
| 80 | + //request | |
| 81 | + log.setClientIp(IpUtils.getIpAddr(request)); | |
| 82 | + log.setHttpData(httpData(request)); | |
| 83 | + | |
| 84 | + //save | |
| 85 | + persistenceBuff.save(log); | |
| 86 | + } | |
| 87 | + | |
| 88 | + private String httpData(HttpServletRequest request){ | |
| 89 | + String rs = JSON.toJSONString(request.getParameterMap()); | |
| 90 | + | |
| 91 | + if(rs.length() > httpDataMaxLen) | |
| 92 | + rs = rs.substring(0, httpDataMaxLen); | |
| 93 | + | |
| 94 | + return rs.replaceAll("\"", "‘"); | |
| 95 | + } | |
| 96 | +} | ... | ... |
src/main/java/com/bsth/oplog/normal/OpLogger.java
0 → 100644
| 1 | +package com.bsth.oplog.normal; | |
| 2 | + | |
| 3 | +import java.net.InetAddress; | |
| 4 | +import java.net.UnknownHostException; | |
| 5 | + | |
| 6 | +import javax.servlet.http.HttpServletRequest; | |
| 7 | + | |
| 8 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 9 | +import org.springframework.stereotype.Component; | |
| 10 | + | |
| 11 | +import com.bsth.entity.sys.SysUser; | |
| 12 | +import com.bsth.oplog.Log; | |
| 13 | +import com.bsth.oplog.Type; | |
| 14 | +import com.bsth.oplog.db.DBHelper; | |
| 15 | +import com.bsth.security.util.SecurityUtils; | |
| 16 | +import com.bsth.util.IpUtils; | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * | |
| 20 | + * @ClassName: OpLogger | |
| 21 | + * @Description: TODO(常规的操作日志记录器) | |
| 22 | + * @author PanZhao | |
| 23 | + * @date 2016年10月21日 上午12:52:30 | |
| 24 | + * | |
| 25 | + */ | |
| 26 | +@Component | |
| 27 | +public class OpLogger { | |
| 28 | + | |
| 29 | + @Autowired | |
| 30 | + DBHelper dbHelper; | |
| 31 | + | |
| 32 | + public void info(String path){ | |
| 33 | + save(getInitLog(path)); | |
| 34 | + } | |
| 35 | + | |
| 36 | + public void info(String path, HttpServletRequest request){ | |
| 37 | + Log log = getInitLog(path); | |
| 38 | + | |
| 39 | + if(request != null){ | |
| 40 | + SysUser user = SecurityUtils.getCurrentUser(); | |
| 41 | + if(user != null) | |
| 42 | + log.setUserName(user.getUserName()); | |
| 43 | + | |
| 44 | + log.setClientIp(IpUtils.getIpAddr(request)); | |
| 45 | + } | |
| 46 | + | |
| 47 | + save(log); | |
| 48 | + } | |
| 49 | + | |
| 50 | + public void info(String path, HttpServletRequest request, String description){ | |
| 51 | + | |
| 52 | + } | |
| 53 | + | |
| 54 | + public static Log getInitLog(String path){ | |
| 55 | + Log log = new Log(); | |
| 56 | + log.setTimestamp(System.currentTimeMillis()); | |
| 57 | + log.setPath(path); | |
| 58 | + log.setType(Type.NORMAL.toString()); | |
| 59 | + | |
| 60 | + //get caller | |
| 61 | + StackTraceElement[] stack = (new Throwable()).getStackTrace(); | |
| 62 | + //注意调用链的顺序,此时2为实际调用者 | |
| 63 | + StackTraceElement caller = stack[2]; | |
| 64 | + | |
| 65 | + log.setCallerClass(caller.getClassName()); | |
| 66 | + log.setCallerMethod(caller.getMethodName()); | |
| 67 | + log.setLineNumber(caller.getLineNumber()); | |
| 68 | + | |
| 69 | + try { | |
| 70 | + log.setServerIp(InetAddress.getLocalHost().getHostAddress()); | |
| 71 | + } catch (UnknownHostException e) { | |
| 72 | + e.printStackTrace(); | |
| 73 | + } | |
| 74 | + | |
| 75 | + return log; | |
| 76 | + } | |
| 77 | + | |
| 78 | + public void save(Log log){ | |
| 79 | + dbHelper.save(log); | |
| 80 | + } | |
| 81 | +} | ... | ... |
src/main/java/com/bsth/security/SecurityMetadataSourceService.java
| ... | ... | @@ -66,8 +66,6 @@ public class SecurityMetadataSourceService implements |
| 66 | 66 | String method = invocation.getRequest().getMethod(); |
| 67 | 67 | String url = method.toLowerCase() + "#" + invocation.getRequestUrl(); |
| 68 | 68 | |
| 69 | - System.out.println(url); | |
| 70 | - | |
| 71 | 69 | int symIndex = url.indexOf("?"); |
| 72 | 70 | if(symIndex != -1){ |
| 73 | 71 | url = url.substring(0, symIndex); | ... | ... |