日志统一处理与异常统一处理插件,可运用在通用埋点框架。

作用

可应用于埋点、日志处理、异常处理的通用需求。日志生成json格式,可通过ELK、EFK等框架采集日志,进行用户行为相关分析,对异常日志进行压缩,根据异常代码等方式,进行异常级别定义,分类告警等。研发人员毋须关注业务日志,兼备日志需关注的request入参与出参,也可对特定业务进行自定义日志打印。灵活度很高。

日志处理logback

1.目前针对日志可动态修改logback级别,日志等级可根据需要修改,便于定位和查找问题。
2.可动态修改整个xml,以文件形式装载。如修改日志个数,清空周期等。

异常统一处理

1.异常分类处理,针对数据库异常,返回数据库代码及解释,便于定位问题。
2.针对内部其他异常,可根据异常类型,进行相应提示。
3.提示内容根据用户自定义,可进行相应配置。

demo

demo地址:
链接:https://pan.baidu.com/s/1rdtrF0l5-DIMaRiYQlheCA
提取码:sd68

因未提交到中央库,settings需添加:

<repository>
    <id>snapshots</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>

pom.xml添加

<dependency>
     <groupId>com.github.ywm130.itg</groupId>
     <artifactId>ywm-itg-core</artifactId>
    <version>0.0.2-SNAPSHOT</version>
</dependency>

代码示例:

package com.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("com.demo")
@ComponentScan("com.github.ywm.itg.core.*")
public class SpringBootdemoApplication {
 
	public static void main(String[] args) {
	    SpringApplication.run(SpringBootdemoApplication.class, args);
	}
} 
package com.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.github.ywm.itg.core.annotation.OperLog;
import com.github.ywm.itg.core.log.service.LogConfigService;

/**
 * @Author: ywm
 * @Date: 2021/1/1 
 */
@RequestMapping("/log")
@RestController
public class LogController {

	@Autowired
	LogConfigService logConfigService;
	
	@RequestMapping("/changeLevel")
	@OperLog(operModul = "日志模块", operType = "更改日志级别", operDesc = "添加日志", operLevel = "info")
	public String changeLevel(String name, String level) throws Exception {
		logConfigService.changeLevel(name, level);
		return "success";
	}
	
	
//	@ParamValidate
	@RequestMapping("/updateLogByXml")
	@OperLog(operModul = "日志模块", operType = "日志配置", operDesc = "更新日志配置", operLevel = "info")
	public String updateLogByXml(@RequestBody() @PathVariable("file") MultipartFile file) throws Exception {
		if (file.isEmpty()) {
            return "{msg:文件不存在!请重新上传}";
        }
		logConfigService.updateLogByXml(file);
		return "success";
	}
}

package com.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.ywm.itg.core.annotation.OperLog;

@Controller
@RequestMapping("/app")
public class TestController {

    @RequestMapping("/test")
    @ResponseBody
    @OperLog(operModul = "测试模块", operType = "测试日志", operDesc = "添加日志", operLevel = "info")
    public String testDemo() {
        return "Hello World!";
    }
    
    @RequestMapping("/test1")
    @ResponseBody
    public String test1() {
    	try {
			int i = 1 / 0;
		} catch (Exception e) {
			throw e;
		}
        return "Hello World!";
    }
}

新建logback.xml在resource目录

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">

    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_HOME" value="/home" />

    <!--控制台日志, 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--文件日志, 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>./TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>-->
            <pattern>%msg%n</pattern>
            <charset>UTF-8</charset> 
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!-- show parameters for hibernate sql 专为 Hibernate 定制 
    <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
    <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
    <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
     -->
    <!--myibatis log configure
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    -->
    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE"/>
    </root>
</configuration>

最后在resouce目录,添加两个配置文件。
errorCode.properties

PARAMETER_ERROR=400,参数错误
NEED_LOGIN_ERROR=401,未登录,无权操作
URI_NOT_EXIST_ERROR=404,资源不存在
SERVER_ERROR=500,系统内部错误
CLASS_CAST_ERROR=10009, 系统发生转型异常!
METHOD_ARGUMENT_NOTVALID_ERROR=10010, 访问方法参数不正确!
NO_VALUE_SPECIFIED_FOR_DATE=10012, 复制JavaBean的时候Date对象没有值!
LOGIN_VERIFICATION_CODE_IS_WRONG=3001,验证码错误
LOGIN_LOGIN_NAME_OR_PASSWORD_IS_WRONG=3002,用户名或密码错误
LOGIN_LOGIN_TIME_IS_TOO_MUCH=3003,登录失败次数过多,请稍后再试
LOGIN_ACCOUNT_IS_LOCKED=3004,账号已被锁定
LOGIN_ACCOUNT_IS_DISABLED=3005,账号已被禁用
LOGIN_ACCOUNT_IS_EXPIRED=3006,账号已过期
FILE_TOO_LARGE=4001,文件太大
FILETYPE_ERROR=4002,文件类型错误
NO_HAVE_FILE=4003,文件不存在

sqlErrorCode.properties 该实例只包含mysql,其他数据库错误代码自行添加。

1005=创建表失败!
1006=创建数据库失败!
1007=数据库已存在,创建数据库失败!
1008=数据库不存在,删除数据库失败!
1009=不能删除数据库文件导致删除数据库失败!
1010=不能删除数据目录导致删除数据库失败!
1011=删除数据库文件失败!
1012=不能读取系统表中的记录!
1016=文件无法打开,使用后台修复或者联系管理员进行修复。!
1020=记录已被其他用户修改!
1021=硬盘剩余空间不足,请加大硬盘可用空间!
1022=关键字重复,更改记录失败!
1023=关闭时发生错误!
1024=读文件错误!
1025=更改名字时发生错误!
1026=写文件错误!
1032=记录不存在!
1036=数据表是只读的,不能对它进行修改!
1037=系统内存不足,请重启数据库或重启服务器!
1038=用于排序的内存不足,请增大排序缓冲区!
1040=已到达数据库的最大连接数,请加大数据库可用连接数!
1041=系统内存不足!
1042=无效的主机名!
1043=无效连接!
1044=当前用户没有访问数据库的权限!
1045=不能连接数据库,用户名或密码错误!
1048=字段不能为空!
1049=数据库不存在!
1050=数据表已存在!
1051=数据表不存在!
1054=字段不存在!
1064=数据库SQL语法出现错误!
1065=无效的SQL语句,SQL语句为空!
1081=不能建立Socket连接!
1114=数据表已满,不能容纳任何记录!
1116=打开的数据表太多!
1129=数据库出现异常,请重启数据库!
1130=连接数据库失败,没有连接数据库的权限!
1133=数据库用户不存在!
1141=当前用户无权访问数据库!
1142=当前用户无权访问数据表!
1143=当前用户无权访问数据表中的字段!
1146=数据表不存在!
1147=未定义用户对数据表的访问权限!
1149=SQL语句语法错误!
1158=网络错误,出现读错误,请检查网络连接状况!
1159=网络错误,读超时,请检查网络连接状况!
1160=网络错误,出现写错误,请检查网络连接状况!
1161=网络错误,写超时,请检查网络连接状况!
1062=字段值重复,入库失败!
1169=字段值重复,更新记录失败!
1177=打开数据表失败!
1180=提交事务失败!
1181=回滚事务失败!
1203=当前用户和数据库建立的连接已到达数据库的最大连接数,请增大可用的数据库连接数或重启数据库!
1205=加锁超时!
1211=当前用户没有创建用户的权限!
1216=外键约束检查失败,更新子表记录失败!
1217=外键约束检查失败,删除或修改主表记录失败!
1226=当前用户使用的资源已超过所允许的资源,请重启数据库或重启服务器!
1227=权限不足,您无权进行此操作!
1235=MySQL版本过低,不具有本功能!
1406=您输入的值过长!

注意:1.在springboot启动类,需添加注解@ComponentScan(“com.github.ywm.itg.core.*”)
2.logcontroller是简单的对日志动态修改的rest接口。
3.testcontroller测试日志与异常的测试类。

可应用postman进行测试。
生成日志格式日下:

{"excId":"141215799367696384","excRequParam":"{}","excName":"java.lang.ArithmeticException","excMessage":"java.lang.ArithmeticException:/ by zero\n\tcom.demo.controller.TestController.test1(TestController.java:24)\ncom.demo.controller.TestController$$FastClassBySpringCGLIB$$5b73dc42.invoke(<generated>)\norg.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)\norg.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)\norg.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\norg.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)\norg.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)\norg.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)\ncom.demo.controller.TestController$$EnhancerBySpringCGLIB$$80192328.test1(<generated>)\nsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\njava.lang.reflect.Method.invoke(Method.java:498)\norg.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)\norg.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)\norg.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)\norg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)\norg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)\norg.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\norg.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)\norg.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)\n","operUri":"/app/test1","operIp":"127.0.0.1","operVer":"2.0","operCreateTime":"2021-02-24 16:21:05.107"}
{"operId":"141215809996062720","operModul":"测试模块","operType":"测试日志","operDesc":"添加日志","operMethod":"com.demo.controller.TestController.testDemo","operRequParam":"{}","operRespParam":"\"Hello World!\"","operIp":"127.0.0.1","operUri":"/app/test","operCreateTime":"2021-02-24 16:21:11.741","operVer":"2.0","sessionid":"95A4E40FB646FCD4AD36A3A07AE5AAFA"}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值