首页 > 基础资料 博客日记
【JAVA】JAVA系统日志设计与实现
2025-01-13 23:30:10基础资料围观109次
一、在做系统的时候,特别是后台管理系统的时候,需要记录每一个管理员对系统的操作行为,这是合规的要求,也是方便业务出现错误操作,排查到错误的操作和相关人员。那么对于JAVA系统来说怎么手机到系统的操作日志呢。
系统日志合规要求:
系统操作日志的合规要求主要包括以下几个方面:
-
日志记录的重要性:日志记录能够记录系统的运行状态、用户操作、异常情况等信息,通过对日志的审计和分析,及时发现系统中存在的问题,加强对系统安全性的保护,便于系统运维和故障排查1。
-
合规要求:根据《网络安全法》等相关法律法规,各类网络运营者都有义务建立健全的操作日志记录制度,对系统的关键操作和安全事件进行记录和保留。因此,设计合规的操作日志记录方案对于保障系统安全、符合法规具有重要意义1。
-
日志内容规范:操作日志应当包含操作的具体内容、操作人员信息、操作时间、操作结果以及异常情况等内容,以便于对操作过程进行全面的追溯和分析。同时,需要规范各类日志记录的格式和内容,确保日志的有效性和可读性1。
-
安全性要求:在设计操作日志方案时,需要考虑日志记录的安全性,避免日志被恶意篡改或删除。可以采用加密、权限控制等手段保护日志的完整性,同时对日志进行定期备份,防止意外数据丢失1。
-
存储和备份:原始日志应在产生日志设备上保存一定时间(如14天),在磁盘空间不足的情况下,系统管理员应根据日志生成时间的先后删除较早的日志。同时,系统管理员需要将原始日志收集到日志统一存储系统进行集中管理2。
-
合规性设计:设计一个符合合规要求的日志系统时,应考虑以下几点:
- 日志内容:只记录必要的信息,避免记录敏感数据。
- 日志级别:使用合适的日志级别(如INFO, WARNING, ERROR),避免记录过多的调试信息。
- 日志存储:确保日志存储在安全的地方,采取适当的加密措施。
- 日志保留期限:设定合理的日志保留期限,并定期清理过期日志。
- 访问控制:确保只有授权用户才能访问日志文件,可以使用文件权限和访问控制列表(ACL)来限制访问。
- 加密:对敏感日志进行加密存储,使用强加密算法如AES。
- 定期审计和审查:定期审计日志文件,确保没有未经授权的访问或异常活动。
- 监控和警报:设置监控系统实时监控日志文件的变化,并在检测到异常活动时发送警报。
- 数据脱敏:在记录日志时,对敏感数据进行脱敏处理,例如隐藏部分信用卡号、社会安全号码等3。
二、下面是具体实现
首先所有的操作都是有一个个controller产生的,增删查改,入参,出参无非这就几个。只是我们想的是如何统一对数据进行收集和处理,而不是将日志收集放在每个controller里面。
1、首先我们要建一个表用来存储日志,这里暂且命名为:base_sys_operate_log
CREATE TABLE `base_sys_operate_log` (
`id` int NOT NULL AUTO_INCREMENT,
`role_type` int DEFAULT NULL,
`operator_id` int DEFAULT NULL,
`operator_name` varchar(255) DEFAULT NULL,
`package_name` varchar(255) DEFAULT NULL,
`module_name` varchar(255) DEFAULT NULL,
`action_name` varchar(255) DEFAULT NULL,
`func_id` int DEFAULT NULL,
`action_vo_type` varchar(255) DEFAULT NULL,
`action_vo_id` int DEFAULT NULL,
`action_vo_params` varchar(2000) DEFAULT NULL,
`exception` varchar(2000) DEFAULT NULL,
`status_code` int DEFAULT NULL,
`error_info` varchar(255) DEFAULT NULL,
`operat_name` varchar(1000) DEFAULT NULL,
`info` varchar(1000) DEFAULT NULL COMMENT '越权信息',
`remote_addr` varchar(128) DEFAULT NULL,
`user_name` varchar(256) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`server_ip` varchar(1000) DEFAULT NULL,
`page_name` varchar(255) DEFAULT NULL COMMENT '页面名称',
`page_url` varchar(255) DEFAULT NULL COMMENT '页面路由',
PRIMARY KEY (`id`),
KEY `create_time_index` (`create_time`),
KEY `operat_name_index` (`operat_name`(255)),
KEY `user_name_index` (`user_name`(255))
) ENGINE=InnoDB AUTO_INCREMENT=6424418 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
2、那就是实体类的编写
public class OperateLog {
private Integer operatorId; //操作员ID
private String operatorName; //操作员名称
private Date createTime; //创建时间
private String packageName; //包名
private String moduleName; //模块名
private String actionName; //action名称
private Integer funcId; //功能id
private Integer roleType; //角色类型
private String actionVoType; //actionVo类型
private Long actionVoId; //actionVoid
private String actionVoParams; //actionVo参数
private String exception; //异常
private String errorInfo; //异常信息
private Integer statusCode; //状态码 0成功 其他失败
private String operatName;
private String info; // 日志信息
private String remoteAddr;//客户端IP remoteAddr
private Integer count;
private Date dateFormat;
private String userName;
private String serverIp;
/**
* 页面名称
*/
private String pageName;
/**
* 页面地址
*/
private String pageUrl;
public final static Integer LOG_SYS_LOG=1;
public final static Integer LOG_BIZ_LOG=4;
public Integer getOperatorId() {
return operatorId;
}
public void setOperatorId(Integer operatorId) {
this.operatorId = operatorId;
}
public String getOperatorName() {
return operatorName;
}
public void setOperatorName(String operatorName) {
this.operatorName = operatorName;
}
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getPackageNameStr() {
if("system".equals(packageName)){
return packageName = "服务平台";
}else if("merchant".equals(packageName)){
return packageName = "商户平台";
}
return packageName;
}
public String getModuleName() {
return moduleName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public String getActionName() {
return actionName;
}
public void setActionName(String actionName) {
this.actionName = actionName;
}
public Integer getFuncId() {
return funcId;
}
public void setFuncId(Integer funcId) {
this.funcId = funcId;
}
public String getActionVoType() {
return actionVoType;
}
public void setActionVoType(String actionVoType) {
this.actionVoType = actionVoType;
}
public Long getActionVoId() {
return actionVoId;
}
public void setActionVoId(Long actionVoId) {
this.actionVoId = actionVoId;
}
public String getActionVoParams() {
return actionVoParams;
}
public void setActionVoParams(String actionVoParams) {
this.actionVoParams = actionVoParams;
}
public String getException() {
return exception;
}
public void setException(String exception) {
this.exception = exception;
}
public Integer getStatusCode() {
return statusCode;
}
public String getStatusCodeStr() {
return "";//Dict.getDict("SYS_EXCEPTION").getValueByKeyInt(statusCode);
}
public String getStatusCodeResult() {
if(statusCode==null||statusCode== 0){
return "成功";
}else{
return "失败";
}
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
public String getOperatName() {
return operatName;
}
public void setOperatName(String operatName) {
this.operatName = operatName;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public void setLogNameInfo(String operatName,String info) {
this.operatName = operatName;
this.info = info;
}
public void setLogNameInfo(String operatName,String info, Integer roleType) {
this.operatName = operatName;
this.info = info;
this.roleType=roleType;
}
public String getRemoteAddr() {
return remoteAddr;
}
public void setRemoteAddr(String remoteAddr) {
this.remoteAddr = remoteAddr;
}
public Integer getRoleType() {
return roleType;
}
public void setRoleType(Integer roleType) {
this.roleType = roleType;
}
public String getRoleTypeStr() {
if(roleType == null)
return "其他";
if(roleType ==4){
return "业务日志";
}else{
return "系统日志";
}
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public String getErrorInfo() {
return errorInfo;
}
public void setErrorInfo(String errorInfo) {
this.errorInfo = errorInfo;
}
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getDateFormat() {
return dateFormat;
}
public void setDateFormat(Date dateFormat) {
this.dateFormat = dateFormat;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getServerIp() {
return serverIp;
}
public void setServerIp(String serverIp) {
this.serverIp = serverIp;
}
public String getPageName() {
return pageName;
}
public void setPageName(String pageName) {
this.pageName = pageName;
}
public String getPageUrl() {
return pageUrl;
}
public void setPageUrl(String pageUrl) {
this.pageUrl = pageUrl;
}
}
抽象Controller类进行统一处理
public static void recordlog(String packageName, String nameSpace, String actionName, HttpServletRequest request,
HttpServletResponse response, BaseAction action, ResponseVo responseVo) {
try {
recordLogRun(packageName, nameSpace, actionName, request, response, action, responseVo);
} catch (Exception e) {
logger.error("记录操作日志异常:", e);
}
}
public static void recordLogRun(String packageName, String nameSpace, String actionName,
HttpServletRequest request, HttpServletResponse response, BaseAction action,
ResponseVo responseVo) {
if (actionName.startsWith("get") || actionName.startsWith("query") || actionName.startsWith("load") || (!packageName.equals("system") && !packageName.equals("merchant") && !packageName.equals("enterprise"))) {
} else if (action.getCommonException() != null && action.getCommonException().getErrorCode() == 1000) {
} else {
OperateLog operateLog = new OperateLog();
Func func = new Func();
operateLog.setPackageName(packageName);
operateLog.setModuleName(nameSpace);
BaseCustomer customer = null;
try {
customer = action.getLoginCustomer();
} catch (Exception e) {
}
if (customer != null) {
if (customer instanceof Operator) {
Operator o = (Operator) customer;
operateLog.setOperatorName(o.getRealName());
operateLog.setOperatorId(o.getId());
operateLog.setUserName(o.getUserName());
} else if (customer instanceof AppThirdAuth) {
AppThirdAuth a = (AppThirdAuth) customer;
operateLog.setOperatorName(a.getAppNo());
operateLog.setOperatorId(a.getId());
operateLog.setUserName(a.getAppName());
}
}
String referer = "";
String servletPath = request.getServletPath();
if (servletPath != null) {
referer = servletPath;
}
if (action.getResultType() != null && action.getResultType().equals("json")) {
referer = request.getHeader("Referer");
}
if (StringUtils.isNotBlank(referer)) {
if (servletPath.contains("/login/login")) {// 系统退出日志
operateLog.setOperatName("登录系统");
operateLog.setRoleType(OperateLog.LOG_SYS_LOG);// 从 func中获取roleType
} else if (servletPath.contains("/login/logout")) {// 系统退出日志
operateLog.setOperatName("退出系统");
operateLog.setRoleType(OperateLog.LOG_SYS_LOG);// 从 func中获取roleType /home/home
} else if (servletPath.contains("/home/home")) {// 系统退出日志
operateLog.setOperatName("系统home");
operateLog.setRoleType(OperateLog.LOG_SYS_LOG);// 从 func中获取roleType /home/home
} else {
String pageUrl = request.getParameter(PAGE_URL_PARAM);
func = FuncDao.getFunc(pageUrl);
if (func != null && func.getIsLoad()) {
operateLog.setFuncId(func.getId());
operateLog.setPageName(func.getFuncName());
operateLog.setPageUrl(pageUrl);
if (func.getSysRoleType() != null) {
operateLog.setRoleType(func.getSysRoleType());// 从 func中获取roleType
}
}
String operateName = getOperateNameByActionName(action, packageName, nameSpace, actionName);
if (StringUtils.isBlank(operateName)) {
operateName = "其他操作";
}
operateLog.setOperatName(operateName);
}
}
operateLog.setRemoteAddr(HostUtility.getClientIP(request));
operateLog.setActionName(actionName);
operateLog.setCreateTime(new Date());
operateLog.setServerIp(HostUtility.getlocalHostAddress());
if (action.getCommonException() != null) {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
action.getCommonException().printStackTrace(new PrintStream(bo));
bo.toString();
operateLog.setException(bo.toString().substring(0, 1000));
operateLog.setInfo(action.getCommonException().getErrorInfo());
operateLog.setStatusCode(action.getCommonException().getErrorCode());
} else {
operateLog.setStatusCode(responseVo.getStatus());
if (responseVo.getData() != null) {
String json = JSONUtility.objectToJson(responseVo.getData());
if (json.length() > 1000) {
operateLog.setInfo(json.substring(0, 1000));
} else {
operateLog.setInfo(json);
}
}
}
if (action != null && action.getModel() != null) {
operateLog.setActionVoType(action.getModel().getClass().getName());
operateLog.setActionVoId(Utility.toObject(Utility.toString(ReflectionUtils.invokeMethod(action.getModel(), "getId")), Long.class));
String json = JSONUtility.objectToJson(action.getModel());
if (json.length() > 2000) {
operateLog.setActionVoParams(json.substring(0, 2000));
} else {
operateLog.setActionVoParams(json);
}
} else {
try {
if (StringUtils.isNotBlank(referer)) {
operateLog.setActionVoParams(URLDecoder.decode(referer, "utf-8"));
}
} catch (UnsupportedEncodingException e) {
logger.error(e, e);
}
}
new CommonThread("", "operateLog") {
public void run() {
try {
operateLog.update();
} catch (Exception e) {
logger.error("记录操作日志update异常:", e);
}
}
}.start();
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: