spring文档查看日志
日志查看方法
日志查看方法在计算机领域,日志是一种记录系统运行情况和事件发生的记录。
无论是服务器、应用程序还是操作系统,都会生成日志文件。
通过查看日志文件,我们可以了解到系统的运行状态,分析问题的原因以及追踪事件的发生过程。
本文将介绍一些常用的日志查看方法,帮助读者快速准确地查看和分析日志。
一、Windows系统下的日志查看方法在Windows系统中,我们可以使用“事件查看器”来查看系统日志、安全日志和应用程序日志等。
以下是详细的操作步骤:1. 打开“事件查看器”在Windows操作系统中,点击“开始”按钮,然后在搜索栏中输入“事件查看器”,并打开该程序。
2. 选择日志类型在事件查看器中,左侧窗口将显示各种日志类型,包括应用程序、安全性、安全性汇总、系统等等。
根据需要,选择相应的日志类型进行查看。
3. 过滤和检索日志右侧窗口将显示所选日志的详细信息。
可以使用筛选器来过滤显示的日志内容,也可以使用关键词搜索来检索特定的日志。
二、Linux系统下的日志查看方法在Linux系统中,日志通常存储在/var/log目录下,并按照不同的服务和应用程序分为多个文件。
以下是一些常用的Linux日志查看命令:1. 检查系统日志使用命令“tail /var/log/syslog”可以查看系统的日志文件。
可以通过加入“-n”参数来指定显示的行数,例如“tail -n 100 /var/log/syslog”将显示最后100行的系统日志。
2. 检查应用程序日志应用程序的日志通常存储在/var/log目录下特定的文件中。
以Apache服务器为例,可以使用命令“tail /var/log/apache2/error.log”来查看Apache服务器的错误日志。
三、使用日志分析工具除了直接查看日志文件,我们还可以使用各种日志分析工具来帮助我们更加高效地分析和查看日志。
以下是一些常用的工具:1. ELK StackELK Stack是一套开源的日志分析平台,包括Elasticsearch、Logstash和Kibana三个工具。
服务器日志文件管理如何查看服务器运行记录
服务器日志文件管理如何查看服务器运行记录服务器日志文件是记录服务器运行状态和活动的重要文件,通过查看服务器日志文件可以了解服务器的运行情况、故障排查、性能优化等。
在服务器管理中,查看服务器日志文件是一项必不可少的工作。
本文将介绍如何管理服务器日志文件以及如何查看服务器的运行记录。
一、服务器日志文件管理1. 日志文件的作用服务器日志文件是记录服务器活动的文件,包括系统日志、应用程序日志、安全日志等。
通过分析日志文件可以及时发现问题、排查故障、优化性能,保证服务器的正常运行。
2. 日志文件的种类常见的服务器日志文件包括系统日志、应用程序日志、访问日志、安全日志等。
不同类型的日志文件记录了不同方面的信息,管理员需要根据需要查看相应的日志文件。
3. 日志文件的存储位置在Linux系统中,日志文件通常存储在/var/log目录下,不同的日志文件有不同的存储路径。
管理员可以通过查看配置文件或者查看系统日志配置来了解日志文件的存储位置。
4. 日志文件的轮转为了避免日志文件过大占用过多磁盘空间,通常会对日志文件进行轮转。
日志文件轮转可以按照时间、大小等条件进行,管理员可以根据需要配置日志文件的轮转规则。
5. 日志文件的清理定期清理日志文件是服务器管理的重要工作之一。
过多的日志文件不仅会占用磁盘空间,还会影响服务器性能。
管理员可以编写脚本定期清理过期的日志文件,保持服务器的良好状态。
二、查看服务器运行记录1. 查看系统日志系统日志是记录系统运行状态和事件的重要日志文件,可以通过查看系统日志了解服务器的运行情况。
在Linux系统中,可以使用命令如cat、tail、grep等来查看系统日志文件,如/var/log/messages、/var/log/syslog等。
2. 查看应用程序日志除了系统日志,应用程序日志也是了解服务器运行情况的重要依据。
不同的应用程序会生成不同的日志文件,管理员可以查看相应的应用程序日志来了解应用程序的运行状态。
SpringBoot使用SpringAOP实现日志审计等功能
SpringBoot使⽤SpringAOP实现⽇志审计等功能项⽬当中需要对⽤户操作菜单的⾏为记录⽇志,⽤SpringAOP写了个⼤概实现,切点是采⽤注解的⽅式,⽤包名的⽅式虽然也可以达到相同的效果,但是不如注解⽅式灵活⽅便。
不多说,直接上代码,此处只是简单写写实现原理。
⼯程⽬录:pom.xml引⼊以下依赖:<!-- 热部署模块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional><!-- 这个需要为 true 热部署才有效 --></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- spring-boot aop依赖配置引⼊ --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>注解:@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface Action {String description() default "no description";}Controller类:/*** @auther: gaopeng*/@RestControllerpublic class AspectController {/*** ⾛切⾯* @return*/@GetMapping("/test")@Action(description = "执⾏了test操作菜单")public String test(){return "method return";}/*** 不⾛切⾯*/@GetMapping("/test1")private void test1(){}/*** ⾛切⾯,抛异常*/@GetMapping("/throws")@Action(description = "执⾏了throws菜单但是抛了异常")public void throwsException(){throw new RuntimeException();}}切⾯类:/*** @auther: gaopeng*/@Aspect@Componentpublic class TestAspect {/*** 切⼊点*/// 此处的切点是注解的⽅式,也可以⽤包名的⽅式达到相同的效果//@Pointcut("execution(public * com.gaopeng.springboot.mytest.controller.*.*(..))")@Pointcut("@annotation(com.gaopeng.springboot.mytest.annotation.Action)")public void execute(){}/*** 前置通知* @param joinPoint*/@Before(value ="execute()")public void Before(JoinPoint joinPoint) {System.out.println("执⾏⽅法之前");}/*** 环绕通知* @param proceedingJoinPoint* @return*/@Around(value ="execute()")public Object around(ProceedingJoinPoint proceedingJoinPoint) {System.out.println("环绕通知开始");try {System.out.println("执⾏⽅法:" + proceedingJoinPoint.getSignature().getName()); MethodSignature signature =(MethodSignature) proceedingJoinPoint.getSignature(); Action action = signature.getMethod().getAnnotation(Action.class);System.out.println("菜单="+action.description());Object object = proceedingJoinPoint.proceed();System.out.println("环绕通知结束,⽅法返回:" + object);return object;} catch (Throwable e) {System.out.println("执⾏⽅法异常:" + e.getClass().getName());return null;}}/*** 后置通知* @param joinPoint*/@After(value ="execute()")public void After(JoinPoint joinPoint) {System.out.println("执⾏⽅法之后");}/*** 后置通知,带返回值* @param obj*/@AfterReturning(pointcut = "execute()",returning = "obj")public void AfterReturning(Object obj) {System.out.println("执⾏⽅法之后获取返回值:"+obj);}/*** 后置通知,异常时执⾏* @param e*/@AfterThrowing(throwing = "e",pointcut = "execute()")public void doAfterThrowing(Exception e) {System.out.println("执⾏⽅法异常:"+e.getClass().getName());}}运⾏结果:。
查看日志的几种方法
查看日志的几种方法《查看日志的几种方法》方法一:通过文本编辑器查看朋友们,咱们平时查看日志,一个简单直接的办法就是用文本编辑器。
像大家熟悉的记事本、Notepad++ 这些,都能派上用场。
比如说,你把要查看的日志文件直接拖到记事本里,它就会打开啦。
然后,你就能一行一行地看里面的内容。
这就好比你在翻一本记录着各种事情的小本子,每一行字都可能藏着重要的信息。
不过,用这种方法的时候,要是日志文件特别大,可能打开就会有点慢。
但别着急,咱们耐心等等,总能看到我们想看的东西。
还有哦,有些日志的格式可能不太规整,看起来会有点费劲。
但只要咱们仔细点,多瞅瞅,总能从那些密密麻麻的字里找到有用的线索。
用文本编辑器查看日志,简单又方便,适合大多数情况。
方法二:使用专门的日志查看工具咱来说说另一种查看日志的办法,就是用专门的日志查看工具。
现在网上有不少这样的工具,比如说 LogViewer、ELK 等等。
这些工具可厉害了,它们能让查看日志变得更轻松、更高效。
这些工具一般都有一些很实用的功能。
比如说,可以按照时间顺序排列日志,这样你就能很清楚地看到事情发生的先后顺序。
还能根据关键词搜索,一下就找到你关心的那些内容,省得你在一堆文字里慢慢找。
而且,有的工具还能把不同来源的日志整合在一起,让你一次性看个清楚,不用来回切换。
这就好比把散落的珍珠串成了一条漂亮的项链,方便又好看。
使用专门的工具查看日志,虽然可能需要花点时间去熟悉怎么操作,但一旦掌握了,那可真是如虎添翼,能帮咱们更快更好地解决问题。
《查看日志的几种方法》方法一:在操作系统的日志查看器中查看朋友们,咱电脑系统里其实自带了日志查看器,用它来看日志挺方便的。
就拿 Windows 系统来说吧,在“控制面板”里找到“管理工具”,然后就能看到“事件查看器”。
打开它,你会发现各种分类的日志,像系统日志、应用程序日志等等。
这里面的日志信息都整理得挺清楚的,每一条都告诉你是什么时候发生的,严重程度咋样。
SpringBoot应用启动并查看日志的Shell脚本
SpringBoot应⽤启动并查看⽇志的Shell脚本#!/bin/bash############################################################# ⽇期:2020-02-10# 作者:何鹏举# 说明:根据传⼊参数的jar包名称,重启SpringBoot应⽤并查看⽇志############################################################if [[ -z $1 ]]; thenecho"Usage: ./restartApp.sh jarName [jenkins]"echo" 第⼆个参数⽤于jenkins⾃动打包时, 不⾃动查看⽇志"exit 1fi# 变量名字scriptName=$0jarName=$1appName=${jarName%.*}logFile=$HOME/app/log/$appName/$appName.logecho"查看⽇志命令: tail -f "$logFile# 找到进程号并关闭应⽤, 注意需要去掉grep命令和脚本本⾝命令的进程pid=`ps -ef | grep $jarName | grep -v grep | grep -v $scriptName | awk'{print $2}'`if [[ -n $pid ]]; thenecho"找到应⽤"$appName"的进程号:"$pid",尝试正常停⽌应⽤"kill $pidsleep5fipid=`ps -ef | grep $jarName | grep -v grep | grep -v $scriptName | awk'{print $2}'`if [[ -n $pid ]]; thenecho"5秒内没有正常停⽌应⽤:"$appName", 进程号:"$pid",下⾯进⾏强制停⽌"kill -9 $pidfi# 启动应⽤nohup java -jar -Xms256M -Xmx512M $jarName --eureka.instance.ip-address=101.132.97.183 >> /dev/null 2>&1 & echo"正在启动应⽤..."# jenkins启动的时候不查看⽇志(简单判断, 第⼆个参数不为空则是jenkins启动的)if [[ -n $2 ]]; thenecho"jenkins启动, 不⾃动查看⽇志"exit 0fi# 查看⽇志(⽇志⽂件不存在(⾸次启动),则休息下再tail)if [[ ! -f $logFile ]]; thensleep2fitail -f $logFile。
springAOP实现操作日志记录,并记录请求参数与编辑前后字段的具体改变
springAOP实现操作⽇志记录,并记录请求参数与编辑前后字段的具体改变本⽂为博主原创,未经允许不得转载: 在项⽬开发已经完成多半的情况下,需要开发进⾏操作⽇志功能的开发,由于操作的重要性,需要记录下操作前的参数和请求时的参数,在⽹上找了很多,没找到可⾏的⽅法.由于操作⽇志⽤注解⽅式的AOP记录操作⽇志⽐较便捷,所以想到了在注解中定义操作前查询数据详情的bean,查询⽅法及参数,参数类型,在aop进⾏⽅法执⾏前,对指定的bean,⽅法,参数进⾏调⽤,获得修改前的参数,并进⾏保存.此处需要注意:1.在前⾯中调⽤指定bean的⽅法时,不可⽤反射进⾏调⽤,反射不能加载spring容器,⽆法获取指定的spring bean,下⾯⽅法中封装的获取spring bean的 ⼯具类也需要配置为bean,⽽且被spring加载,才可以;2.@Aspect注解的类⼀定要配置成bean,⽽且被spring加载,才可以,即同时配置@Component和@Aspect,或在spring的配置⽂件进⾏bean的配置3.如果配置了bean,要检索component-scan扫描范围是否包括Aspect类;⼀.定义切⾯执⾏的注解(该注解可根据⾃⼰实现的内容进⾏⾃定义)1 import ng.annotation.Documented;2 import ng.annotation.Retention;3 import ng.annotation.Target;45 import ng.annotation.ElementType;6 import ng.annotation.RetentionPolicy;78 @Target({ElementType.PARAMETER, ElementType.METHOD})9 @Retention(RetentionPolicy.RUNTIME)10 @Documented11 public @interface SystemControllerLog {1213 /**查询模块*/14 String module() default "";1516 /**查询模块名称*/17 String methods() default "";1819 /**查询的bean名称*/20 String serviceClass() default "";2122 /**查询单个详情的bean的⽅法*/23 String queryMethod() default "";2425 /**查询详情的参数类型*/26 String parameterType() default "";2728 /**从页⾯参数中解析出要查询的id,29 * 如域名修改中要从参数中获取customerDomainId的值进⾏查询30 */31 String parameterKey() default "";3233 /**是否为批量类型操作*/34 boolean paramIsArray() default false;3536 }⼆.切⾯执⾏的⽅法12import ng.reflect.Method;3import java.text.SimpleDateFormat;4import java.util.Date;56import javax.servlet.http.HttpServletRequest;7import javax.servlet.http.HttpSession;89import ng3.StringUtils;10import ng.ProceedingJoinPoint;11import ng.Signature;12import ng.annotation.Around;13import ng.annotation.Aspect;14import ng.annotation.Pointcut;15import ng.reflect.MethodSignature;16import org.slf4j.Logger;17import org.slf4j.LoggerFactory;18import org.springframework.beans.factory.annotation.Autowired;19import ponent;20import org.springframework.util.ReflectionUtils;21import org.springframework.web.context.request.RequestContextHolder;22import org.springframework.web.context.request.ServletRequestAttributes;2324import com.alibaba.fastjson.JSON;25import com.alibaba.fastjson.JSONArray;26import com.alibaba.fastjson.JSONObject;27import mon.RequestResult;28import mon.enums.FucdnStrConstant;29import com.suning.fucdn.entity.log.SystemControllerLogInfo;30import com.suning.fucdn.impl.service.log.LogServiceImpl;31import com.suning.fucdn.vo.AdminUserVO;3233/**34 *35 * 〈⼀句话功能简述:操作⽇志切⾯记录操作〉<br>36 * 〈功能详细描述〉37 *38 * @author xiang39 * @see [相关类/⽅法](可选)40 * @since [产品/模块版本] (可选)41*/42 @Component43 @Aspect44public class ControllerLogAopAspect {4546private static final Logger LOGGER = LoggerFactory.getLogger(ControllerLogAopAspect.class);4748//注⼊service,⽤来将⽇志信息保存在数据库49 @Autowired50private LogServiceImpl logservice;5152//配置接⼊点,如果不知道怎么配置,可以百度⼀下规则 //指定controller的类进⾏切⾯ @Pointcut("execution(* com.controller..CustomerController.*(..))||execution(* com.controller.ManageController.*(..))")53 @Pointcut("execution(* com.controller..*.*(..))")54private void controllerAspect(){55 System.out.println("point cut start");56 }//定义⼀个切⼊点5758 @SuppressWarnings({ "rawtypes", "unused" })59 @Around("controllerAspect()")60public Object around(ProceedingJoinPoint pjp) throws Throwable {61//常见⽇志实体对象62 SystemControllerLogInfo log = new SystemControllerLogInfo();63//获取登录⽤户账户64 HttpServletRequest httpRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();6566//⽅法通知前获取时间,为什么要记录这个时间呢?当然是⽤来计算模块执⾏时间的67//获取系统时间68 String time = new SimpleDateFormat(FucdnStrConstant.YEAR_MONTH_DAY_HOUR_MINUTE_SECOND.getConstant()).format(new Date());69 log.setStartTime(time);7071//获取系统ip,这⾥⽤的是我⾃⼰的⼯具类,可⾃⾏⽹上查询获取ip⽅法72//String ip = GetLocalIp.localIp();73//log.setIP(ip);7475// 拦截的实体类,就是当前正在执⾏的controller76 Object target = pjp.getTarget();77// 拦截的⽅法名称。
获取服务器日志的方法
获取服务器日志的方法有很多种,以下是一些常见的方法:
1. 通过事件查看器查看日志:大多数服务器都自带事件查看器,可以通过它来查看服务器的运行日志。
打开事件查看器后,可以看到系统日志、应用程序日志、安全日志等多个分类,根据需要选择相应的日志进行查看。
2. 使用命令行工具查看日志:可以使用一些命令行工具来查看服务器的日志。
例如,在Linux系统中,可以使用tail、grep等命令来查看日志文件。
在Windows系统中,可以使用PowerShell等命令来查看日志文件。
3. 使用第三方工具查看日志:还有一些第三方工具可以帮助我们查看服务器的日志。
例如,Logstash可以帮助我们将日志集中管理,并提供搜索、分析和可视化等功能。
Graylog也是一个开源的日志管理平台,可以帮助我们管理和分析大量的日志数据。
4. 远程访问服务器查看日志:如果无法直接连接到服务器,可以通过远程访问的方式查看服务器的日志。
例如,使用SSH协议可以远程连接到Linux服务器,并使用命令行工具查看日志文件。
使用远程桌面协议可以远程连接到Windows服务器,并使用事件查看器查看日志文件。
需要注意的是,在获取服务器日志时,需要遵守相关的法律法规和隐私保护规定,确保不会侵犯他人的合法权益。
同时,为了确保日志的安全性和完整性,建议定期备份和加密传输服务器日志。
查看SQL数据库操作日志方法
查看SQL数据库操作日志方法在SQL数据库中,可以通过各种方法查看操作日志。
下面将介绍几种常用的方法:1.使用数据库自带的日志功能大多数SQL数据库都会记录操作日志,用于跟踪和审计数据库的活动。
可以通过查询数据库的系统视图或系统表来查看操作日志。
不同数据库有不同的实现方法,下面以MySQL为例进行说明:-使用`SHOWBINARYLOGS`语句可以查看二进制日志文件的列表。
-使用`SHOWMASTERSTATUS`语句可以查看主日志文件和当前写入位置。
-使用`SHOWSLAVESTATUS`语句可以查看备用服务器的复制状态。
2.使用数据库监控工具许多数据库监控工具提供了查看操作日志的功能,这些工具通常能够以图表形式显示数据库的活动情况。
一些著名的数据库监控工具如Nagios、Datadog、Prometheus等都支持查看SQL数据库的操作日志。
3. 使用SQL Profiler工具SQL Profiler是微软提供的一个用于监视和分析SQL Server数据库活动的工具。
通过SQL Profiler,可以实时查看数据库的操作日志,并根据需要进行过滤和分析。
SQL Server Management Studio(SSMS)中集成了SQL Profiler,可以方便地使用。
4.使用第三方工具除了数据库厂商提供的工具外,还有一些第三方工具也提供了查看数据库操作日志的功能。
这些工具通常具有更加强大和灵活的功能,可以对数据库活动进行更深入的分析和监控。
比较常用的第三方工具有Percona Toolkit、Mytop、SQLSentry等。
5.使用日志解析工具SQL数据库的日志文件通常是二进制格式的,难以直接阅读。
为了方便查看和分析日志,可以使用一些日志解析工具。
这些工具能够将日志文件转换为易于阅读和分析的文本格式。
比较常用的日志解析工具有MySQL binlog reader、Oracle logminer等。
SpringBoot全局统一记录日志
SpringBoot全局统⼀记录⽇志1.记录⽇志使⽤aop来记录controller中的请求返回⽇志pom.xml引⼊:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>在完成了引⼊AOP依赖包后,⼀般来说并不需要去做其他配置。
也许在Spring中使⽤过注解配置⽅式的⼈会问是否需要在程序主类中增加@EnableAspectJAutoProxy来启⽤,实际并不需要。
可以看下⾯关于AOP的默认配置属性,其中spring.aop.auto属性默认是开启的,也就是说只要引⼊了AOP依赖后,默认已经增加了@EnableAspectJAutoProxy。
# AOPspring.aop.auto=true # Add @EnableAspectJAutoProxy.spring.aop.proxy-target-class=false # Whether subclass-based (CGLIB) proxies are to be created (true) as opposed to standard Java interface-based proxies (false).1.使⽤Around@Aspect@Componentpublic class ControllerAspect {private Logger logger = LoggerFactory.getLogger(getClass());/*** Controller aspect.*/@Pointcut("execution(* com.shitou.huishi.service..*.*(..))")public void controllerAspect() {}/*** Around ⼿动控制调⽤核⼼业务逻辑,以及调⽤前和调⽤后的处理,* <p>* 注意:当核⼼业务抛异常后,⽴即退出,转向AfterAdvice 执⾏完AfterAdvice,再转到ThrowingAdvice** @param pjp* the pjp* @return object* @throws Throwable* the throwable*/@Around(value = "controllerAspect()")public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {RequestAttributes ra = RequestContextHolder.getRequestAttributes();ServletRequestAttributes sra = (ServletRequestAttributes) ra;HttpServletRequest request = sra.getRequest();("URL : " + request.getRequestURL().toString());("HTTP_METHOD : " + request.getMethod());("IP : " + request.getRemoteAddr());("CLASS_METHOD : " + pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName());("REQUEST ARGS : " + JSON.toJSONString(pjp.getArgs()));long startTime = System.currentTimeMillis();try {Object response = pjp.proceed();// 2.打印出参,返回结果long endTime = System.currentTimeMillis();// 3.出参打印("RESPONSE:{}", response != null ? JSON.toJSONString(response) : "");("SPEND TIME : {}ms", (endTime - startTime));return response;} catch (AuthException e) {("RESPONSE ERROR:{}", e.getMsg());throw e;} catch (HuishiApiException e) {("RESPONSE ERROR:{}", e.getMsg());throw e;} catch (MethodArgumentNotValidException e) {("RESPONSE ERROR:{}", e.getMessage());throw e;} catch (Throwable e) {logger.error("RESPONSE ERROR:{}", Arrays.toString(e.getStackTrace()));throw e;} finally {long endTime = System.currentTimeMillis();logger.error("SPEND TIME : {}ms", (endTime - startTime));}}}2.使⽤Before,AfterReturning处理:import java.util.Arrays;import javax.servlet.http.HttpServletRequest;import ng.JoinPoint;import ng.annotation.AfterReturning;import ng.annotation.Aspect;import ng.annotation.Before;import ng.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import ponent;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;/*** Created by qhong on 2018/5/28 14:25**/@Aspect@Componentpublic class LogAspect {private Logger logger = LoggerFactory.getLogger(getClass());ThreadLocal<Long> startTime = new ThreadLocal<>();@Pointcut("execution(public * com.shitou.huishi.service.*.*(..))")public void logAspect(){}@Before("logAspect()")public void doBefore(JoinPoint joinPoint) throws Throwable {startTime.set(System.currentTimeMillis());// 接收到请求,记录请求内容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();// 记录下请求内容("URL : " + request.getRequestURL().toString());("HTTP_METHOD : " + request.getMethod());("IP : " + request.getRemoteAddr());("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); ("ARGS : " + Arrays.toString(joinPoint.getArgs()));}@AfterReturning(returning = "ret", pointcut = "logAspect()")public void doAfterReturning(Object ret) throws Throwable {// 处理完请求,返回内容("RESPONSE : " + ret);("SPEND TIME : " + (System.currentTimeMillis() - startTime.get()));}}两种⽅式计算出来的时间,参数,返回体是⼀样的。
SpringBoot-日志的配置和使用详解(SLF4j、Logback)
SpringBoot-⽇志的配置和使⽤详解(SLF4j、Logback)1,基本介绍(1)市⾯上常见的⽇志框架有很多。
通常情况下,⽇志是由⼀个抽象层+实现层的组合来搭建的,⽽⽤户通常来说不应该直接使⽤具体的⽇志实现类,应该使⽤⽇志的抽象层。
抽象层:JCL(Jakarta Commons Logging)、SLF4j(Simple Logging Facade for Java)、jboss-logging 实现层:Log4j 、JUL(java.util.logging)、Log4j2、Logback(2)SpringBoot 默认选择的是 SLF4J + Logback 的组合,如果不需要更改为其他⽇志系统(如 Log4j2 等),则⽆需多余的配置,LogBack 默认会将⽇志打印到控制台上。
由于新建的 Spring Boot 项⽬⼀般都会引⽤ spring-boot-starter 或者 spring-boot-starter-web,⽽这两个起步依赖中都已经包含了对于 spring-boot-starter-logging 的依赖,所以,我们⽆需额外添加依赖。
2,基本⽤法(1)这⾥我们打印出 5 种不同级别的⽇志,可以看到控制台会输出相关⽇志信息:12 3 4 5 6 7 8 9 10 11 12 13 14@RestControllerpublic class HelloController {Logger logger = LoggerFactory.getLogger(getClass()); @GetMapping("/test")public void test(){logger.trace("Trace ⽇志...");logger.debug("Debug ⽇志...");("Info ⽇志...");logger.warn("Warn ⽇志...");logger.error("Error ⽇志...");}}(2)如果项⽬有使⽤ Lombok 的话,直接使⽤ @Slf4j 注解可以省去从⽇志⼯⼚⽣成⽇志对象这⼀步,直接进⾏⽇志记录。
restartedmain 日志格式
restartedmain 日志格式
"restartedMain"日志格式是SpringBoot默认的日志格式,它的主要组成部分包括:
- 时间戳:精确到毫秒,例如:2021-11-13 14:35:20.298。
- 日志级别:可选项有TRACE、DEBUG、INFO、WARN、ERROR和FATAL,其中INFO是默认等级。
- 进程ID。
- 分割符:默认是"---"。
- 线程名称:通常为"[ restartedMain]",如果出现"restartedMain"则代表已经生效。
如果你在使用SpringBoot并且遇到修改后不能生效的情况,可以尝试重试重启项目。
同时,要注意的是,修改配置文件后需要重新启动应用以使新的配置生效。
该日志格式可以通过在pom.xml文件中进行配置。
另外,还可以使用
@Slf4j注解来简化日志记录的使用。
springboot中用来进行查看错误日志的logback文件
springboot中⽤来进⾏查看错误⽇志的logback⽂件<?xml version="1.0" encoding="UTF-8"?><!-- 从⾼到地低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL --><!-- ⽇志输出规则根据当前ROOT 级别,⽇志输出时,级别⾼于root默认的级别时会输出 --><!-- 以下每个配置的 filter 是过滤掉输出⽂件⾥⾯,会出现⾼级别⽂件,依然出现低级别的⽇志信息,通过filter 过滤只记录本级别的⽇志--><!-- 属性描述 scan:性设置为true时,配置⽂件如果发⽣改变,将会被重新加载,默认值为true scanPeriod:设置监测配置⽂件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
当scan为true时,此属性⽣效。
默认的时间间隔为1分钟 debug:当此属性设置为true时,将打印出logback内部⽇志信息,实时查看logback运⾏状态。
默认值为false。
--><configuration scan="true" scanPeriod="60 seconds" debug="false"><springProperty scope="context" name="logLevel" source="log.level"/><property name="logPath" value="G:/idjavacode/industry3/doc"></property><!-- 定义⽇志⽂件输⼊位置 --><property name="log_dir" value="${logPath}/vegetable-shop-api" /><!--<property name="log_dir" value="./logs/order-admin-api" />--><!-- ⽇志最⼤的历史 30天 --><property name="maxHistory" value="365"/><!-- ConsoleAppender 控制台输出⽇志 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><!-- 对⽇志进⾏格式化 --><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level- %caller{1} -%msg%n</pattern><charset>UTF-8</charset></encoder></appender><!-- ERROR级别⽇志 --><!-- 滚动记录⽂件,先将⽇志记录到指定⽂件,当符合某个条件时,将⽇志记录到其他⽂件 RollingFileAppender--><appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 过滤器,只记录WARN级别的⽇志 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>DEBUG</level></filter><!-- 最常⽤的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责出发滚动 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!--⽇志输出位置可相对、和绝对路径 --><fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/logback_vegetable-shop-api_info-log-%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>10MB</maxFileSize><maxHistory>360</maxHistory><totalSizeCap>20GB</totalSizeCap></rollingPolicy><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level-%caller{1} - %msg%n</pattern><charset>GBK</charset></encoder></appender><appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level-%caller{1} - %msg%n</pattern><charset>GBK</charset></encoder> <!--滚动策略--><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--路径--><fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/vegetable-shop-api_error-log-%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>10MB</maxFileSize><maxHistory>360</maxHistory><totalSizeCap>20GB</totalSizeCap></rollingPolicy></appender><logger name="java.sql.PreparedStatement" level="DEBUG" /><logger name="java.sql.Connection" level="DEBUG" /><logger name="java.sql.Statement" level="DEBUG" /><logger name="com.ibatis" level="INFO" /><logger name="mon.jdbc.SimpleDataSource" level="INFO" /><logger name="mon.jdbc.ScriptRunner" level="INFO"/><logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="DEBUG" /><logger name="org.springframework" level="INFO" /><!-- root级别 DEBUG --><root level="${logLevel}"><!-- 控制台输出 --><appender-ref ref="STDOUT" /><!-- ⽂件输出 --><appender-ref ref="INFO" /><appender-ref ref="ERROR" /></root></configuration>这⼀份logback描述的并不是太完整在yml⽂件中进⾏配置的⽂件是:# logbacklog:path:level: INFO。
springbootTomcat访问日志
springbootTomcat访问⽇志1.Tomcat设置访问⽇志1 <Host name="localhost" appBase="webapps"2 unpackWARs="true" autoDeploy="true">3 <!--4 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"5 prefix="localhost_access_log." suffix=".txt"6 pattern="%h %l %u %t "%r" %s %b" />7 -->8 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"9 prefix="localhost_access_log." suffix=".txt"10 pattern="%h,%l,%u,%t,%T,"%r",%s,%b,%{Referer}i,"%{User-Agent}i",%{X-Requested-With}i"11 fileDateFormat="yyyy-MM-dd.HH"12 />1314 </Host>2.springboot设置访问⽇志,在properties配置⽂件中添加tomcat⽇志配置1 #内嵌tomcat⽇志2 server.tomcat.accesslog.buffered=true3 server.tomcat.accesslog.directory=/usr/microStorage/tomcatLog4 server.tomcat.accesslog.enabled=true5 #每天保存⼀个6 server.tomcat.accesslog.file-date-format=yyyy-MM-dd7 server.tomcat.accesslog.pattern=%h %l %T %t %r %s %b %{Referer}i %{User-Agent}i8 server.tomcat.accesslog.prefix=access_log9 server.tomcat.accesslog.rename-on-rotate=false10 server.tomcat.accesslog.request-attributes-enabled=false11 server.tomcat.accesslog.rotate=true12 server.tomcat.accesslog.suffix=.log3.⽇志分析,通过正在表达式,将需要分析的信息进⾏正则捕获提取,然后根据需要进⾏相关数据的统计及可视化展⽰ 1public static void parse() throws Exception{2 String path = "D:/logs/localhost_access_log.2018-09-30.11.txt";3 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));4 String line = null;5 String reg = "^(.+?),(.+?),(.+?),(.+?),(.+?),(\\\".+?\\\"),(.+?),(.+?),(.+?),(\\\".+?\\\"),(.+?),(.+?)$";6 Pattern pattern = pile(reg);7while((line=br.readLine())!=null) {8 System.out.println(line);9 Matcher matcher = pattern.matcher(line);10 matcher.matches();11// pattern="%h,%l,%u,%t,%T,"%r",%s,%b,%{Referer}i,"%{User-Agent}i",%{X-Requested-With}i,%{passport}c"12 System.out.println("ip="+matcher.group(1));13 System.out.println("date="+matcher.group(4));14 System.out.println("cost="+matcher.group(5));15 System.out.println("request="+matcher.group(6));16 System.out.println("status="+matcher.group(7));17 System.out.println("bytes="+matcher.group(8));18 System.out.println("Referer="+matcher.group(9));19 System.out.println("User-Agent="+matcher.group(10));20 System.out.println("X-Requested-With="+matcher.group(11));21 System.out.println("passport="+matcher.group(12));22 System.out.println("------------------------------------");23 }24 br.close();25 }。
SpringBoot日志配置方法(超详细)
SpringBoot⽇志配置⽅法(超详细)默认⽇志 Logback :默认情况下,Spring Boot会⽤Logback来记录⽇志,并⽤INFO级别输出到控制台。
在运⾏应⽤程序和其他例⼦时,你应该已经看到很多INFO级别的⽇志了。
从上图可以看到,⽇志输出内容元素具体如下:时间⽇期:精确到毫秒⽇志级别:ERROR, WARN, INFO, DEBUG or TRACE进程ID分隔符:— 标识实际⽇志的开始线程名:⽅括号括起来(可能会截断控制台输出)Logger名:通常使⽤源代码的类名⽇志内容添加⽇志依赖假如maven依赖中添加了 spring-boot-starter-logging :1 2 3 4<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId> </dependency>但是呢,实际开发中我们不需要直接添加该依赖。
你会发现 spring-boot-starter 其中包含了 spring-boot-starter-logging ,该依赖内容就是 Spring Boot 默认的⽇志框架 logback 。
⼯程中有⽤到了 Thymeleaf ,⽽ Thymeleaf 依赖包含了 spring-boot-starter ,最终我只要引⼊ Thymeleaf 即可。
1 2 3 4<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>控制台输出⽇志级别从低到⾼分为:1TRACE < DEBUG < INFO < WARN < ERROR < FATAL 。
springboot项目添加lombok日志输出控制台和log文件
springboot项⽬添加lombok⽇志输出控制台和log⽂件这个配置我也是在⽹上查找的,但是找不到出处了。
⾸先,在resources下⾯建⽴logback-spring.xml⽂件,这个logback-spring是默认springboot可以扫描到的,不⽤在yml中配置。
也可以⾃⼰起名字,要在application.yml中进⾏配置把logback-spring.xml这个名字替换。
然后复制下⾯代码到logback-spring.xml⽂件来<?xml version="1.0" encoding="UTF-8"?><!-- ⽇志级别从低到⾼分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --><!-- scan:当此属性设置为true时,配置⽂档如果发⽣改变,将会被重新加载,默认值为true --><!-- scanPeriod:设置监测配置⽂档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
当scan为true时,此属性⽣效。
默认的时间间隔为1分钟。
--><!-- debug:当此属性设置为true时,将打印出logback内部⽇志信息,实时查看logback运⾏状态。
默认值为false。
--><configuration scan="true" scanPeriod="10 seconds"><contextName>logback-spring</contextName><!-- name的值是变量的名称,value的值时变量定义的值。
通过定义的值会被插⼊到logger上下⽂中。
nacos动态读取logback-spring.xml日志配置
nacos动态读取logback-spring.xml⽇志配置⼀。
nacos的使⽤启动nacos服务端,可以下载jar启动或者⾃⼰下载源码打包。
浏览器访问,账号密码:nacos/nacosnacos远程的common-service-dev.yml⽂件spring:application:name: common-servicedatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://xxxxxx:3306/smartpower_xny?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=UTCusername: xxxpassword: xx@123456type: com.zaxxer.hikari.HikariDataSourcehikari:minimum-idle: 5maximum-pool-size: 15auto-commit: trueidle-timeout: 30000pool-name: SmartpowerHikariCPmax-lifetime: 1800000connection-timeout: 30000connection-test-query: SELECT 1redis:host: xxxxport: 6379database: 0timeout: 1800000# jpa:# show-sql: false# hibernate:# ddl-auto: update# database-platform: org.hibernate.dialect.MySQL5InnoDBDialect# database: mysqlserver:port: 9002servlet:context-path: /management:endpoints:web:exposure:include: "*"logging:#file:# name: logs/${}.logconfig: http://${spring.cloud.nacos.config.server-addr}/nacos/v1/cs/configs?group=DEFAULT_GROUP&tenant=${space}&dataId=logback-spring.xml level:mon.repository.dao: debugmybatis-plus:mapper-locations: classpath*:/mapper/*.xml#实体扫描,多个package⽤逗号或者分号分隔typeAliasesPackage: mon.repository.modelconfiguration:#是否开启⾃动驼峰命名规则map-underscore-to-camel-case: true#MyBatis ⾃动映射策略,通过该配置可指定 MyBatis 是否并且如何来⾃动映射数据表字段与对象的属性,auto-mapping-behavior: full#打印SQL#log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:#数据库配置db-config:#主键 auto:⾃增id-type: auto#枚举类型当作基础类型mapper:enumAsSimpleType: truepagehelper:helper-dialect: mysql#true时,如果pageNum<1会查询第⼀页,如果pageNum>pages会查询最后⼀页#false时,如果pageNum<1或pageNum>pages会返回空数据reasonable: falsesupport-methods-arguments: trueparams: count=countsqlchint:swagger:enabled: truetitle: common中⼼description: common接⼝⽂档version: 1.0base-package: mon.controllernacos远程的 logback-spring.xml⽂件<?xml version="1.0" encoding="UTF-8" ?><configuration><!-- 在yaml配置添加logging.path: 配置⽂件路径--><!-- 属性⽂件:在properties⽂件中找到对应的配置项 --><springProperty scope="context" name="logging.path" source="logging.path" defaultValue="./logs" /><!-- nacos名字不要改动,不然会造成启动报警告,Failed to rename context Context has been already given a name nacos原因:项⽬框架集成logback 与nacos ⾃带的logback 冲突, nacos的logback 已经先于项⽬启动--><contextName>nacos</contextName><property name="FILE_NAME" value="common-data" /><appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出(配⾊):%d表⽰⽇期,%thread表⽰线程名,%-5level:级别从左显⽰5个字符宽度%msg:⽇志消息,%n是换⾏符--><pattern>%yellow(%d{yyyy-MM-dd HH:mm:ss}) %red([%thread]) %highlight(%-5level) %cyan(%logger{50}) - %magenta(%msg) %n</pattern><!--user:%X{userId} :添加⽤户信息,⽅便链路追踪可以在aop拦截时MDC.put("userId", 1);--><!--<pattern>%yellow(%d{yyyy-MM-dd HH:mm:ss}) %red([%thread]) %highlight(%-5level) user:%X{userId} %cyan(%logger{50}) - %magenta(%msg) %n</pattern>--><charset>UTF-8</charset></encoder></appender><!--根据⽇志级别分离⽇志,分别输出到不同的⽂件--><appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"><filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 设置拦截的对象为INFO级别⽇志 --><level>INFO</level><!-- 当匹配到了INFO级别时,启⽤该段配置 --><onMatch>ACCEPT</onMatch><!-- 没有匹配到INFO级别⽇志时,屏蔽该段配置 --><onMismatch>DENY</onMismatch></filter><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern> %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n </pattern><!--user:%X{userId} :添加⽤户信息,⽅便链路追踪可以在aop拦截时MDC.put("userId", 1);--><!--<pattern> %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level user:%X{userId} %logger{50} - %msg%n </pattern>--><charset>UTF-8</charset></encoder><!--滚动策略--><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!--按时间保存⽇志修改格式可以按⼩时、按天、⽉来保存--><fileNamePattern>${logging.path}/${FILE_NAME}.info.%d{yyyy-MM-dd}.%i.log</fileNamePattern><!--单个⽂件⼤⼩注意:除了 %d 之外还有 %i。
服务器日志查询代码
服务器⽇志查询代码参考⽹址:1、服务器⽇志:应⽤程序⽇志、系统⽇志、安全⽇志。
如下图2、查询⽇志代码:EventLogSearch.cs1public class EventLogClass:IDisposable2 {3public string EntryType4 {5get;6set;7 }8public string GeneratedDate9 {10get;11set;12 }13public string GeneratedTime14 {15get;16set;17 }18public string Source19 {20get;21set;22 }23public string Category24 {25get;26set;27 }28public string InstanceId29 {30get;31set;32 }33public string UserName34 {35get;36set;37 }38public string MachineName39 {40get;41set;42 }4344public void Dispose()45 {46 }47 }484950public class EventLogSearch:IDisposable51 {52public static readonly string[] LogTypes = new[] { "Application", "Security", "System", "Internet Explorer" };5354public List<EventLogClass> GetData(string logType, DateTime time, bool IsAfter, EventLogEntryType[] eventEntryTypeEFilters) 55 {56if (!LogTypes.Contains(logType))57 {58throw new Exception("参数logType⽆效!");59 }6061 ArrayList entries = null;62 List<EventLogClass> list = null;63object[] obj = null;6465try66 {67if (IsAfter)68 {69 entries = this.FindAferTime(logType, time, eventEntryTypeEFilters);70 }71else72 {73 entries = this.FindBeforeTime(logType, time, eventEntryTypeEFilters);74 }7576if (entries != null && entries.Count > 0)77 {78 list = new List<EventLogClass>();79foreach (EventLogEntry i in entries)80 {81 list.Add(82new EventLogClass {83 EntryType = i.EntryType.ToString(),84 GeneratedDate = i.TimeGenerated.ToString("yyyy/MM/dd"),85 GeneratedTime = i.TimeGenerated.ToString("HH/mm/ss"),86 Source = i.Source.ToString(),87 Category = i.Category.ToString(),88 InstanceId = i.InstanceId.ToString(),89 UserName = erName,90 MachineName = i.MachineName91 }92 );93 }94 }95 }96catch (Exception ex)97 {98throw ex;99 }100finally101 {102 entries = null;103 obj = null;104 }105106return list;107 }108109public ArrayList FindBeforeTime(string logType, DateTime time, EventLogEntryType[] eventEntryTypeEFilters) 110 {111if (!LogTypes.Contains(logType))112 {113throw new Exception("参数logType⽆效!");114 }115116 ArrayList entries = null;117 ArrayList entriesArray = null;118 EventLog log = null;119 EventLogEntryCollection logEntries = null;120121try122 {123 log = new EventLog(logType);124 logEntries = log.Entries;125126if (logEntries != null && logEntries.Count > 0)127 {128 entries = new ArrayList();129130foreach (EventLogEntry logEntry in logEntries)131 {132if (logEntry.TimeGenerated <= time)133 {134if (eventEntryTypeEFilters != null && eventEntryTypeEFilters.Length > 0)135 {136if (eventEntryTypeEFilters.Contains(logEntry.EntryType))137 {138 entries.Add(logEntry);139 }140 }141else142 {143 entries.Add(logEntry);144 }145 }146 }147 }148149 entriesArray = entries.Clone() as ArrayList;150 }151catch (Exception ex)152 {153throw ex;154 }155finally156 {157 log.Dispose();158 logEntries = null;159 entries = null;160 }161162return entriesArray;163 }164165public ArrayList FindAferTime(string logType, DateTime time, EventLogEntryType[] eventEntryTypeEFilters) 166 {167if (!LogTypes.Contains(logType))168 {169throw new Exception("参数logType⽆效!");170 }171172 ArrayList entries = null;173 ArrayList entriesArray = null;174 EventLog log = null;175 EventLogEntryCollection logEntries = null;176177try178 {179 log = new EventLog(logType);180 logEntries = log.Entries;181182if (logEntries != null && logEntries.Count > 0)183 {184 entries = new ArrayList();185186foreach (EventLogEntry logEntry in logEntries)187 {188if (logEntry.TimeGenerated >= time)189 {190if (eventEntryTypeEFilters != null && eventEntryTypeEFilters.Length > 0)191 {192if (eventEntryTypeEFilters.Contains(logEntry.EntryType))193 {194 entries.Add(logEntry);195 }196 }197else198 {199 entries.Add(logEntry);200 }201 }202 }203 }204205 entriesArray = entries.Clone() as ArrayList;206 }207catch (Exception ex)208 {209throw ex;210 }211finally212 {213 log.Dispose();214 logEntries = null;215 entries = null;216 }217218return entriesArray;219 }220221222public void Dispose()223 {224225 }226 }3、页⾯调⽤代码:Test01.aspx.csView Code1public partial class test01 : System.Web.UI.Page2 {3protected void Page_Load(object sender, EventArgs e)4 {56 }78protected void btnAction_Click(object sender, EventArgs e)9 {10 List<object[]> data = null;11 EventLogSearch eventSearch = null;12 EventLogEntryType[] eventEntryTypeEFilters = null;1314try15 {16 eventEntryTypeEFilters = new EventLogEntryType[] {EventLogEntryType.Error};17 eventSearch = new EventLogSearch();181920 gvShow.AllowPaging = true;21 gvShow.PageSize = 10;22 gvShow.DataSource = eventSearch.GetData(ddlType.SelectedValue, DateTime.Now.AddMonths(-2), true, eventEntryTypeEFilters);23 gvShow.DataBind();24 }25catch (Exception ex)26 {27throw ex;28 }29finally30 {31 data = null;32 eventSearch = null;33 }34 }35 }4、效果图:。
查看日志常用命令
查看日志常用命令
查看日志是系统管理员工作中经常需要进行的操作,以下是一些常用的命令:
1. tail:查看日志文件的最后几行。
例如:tail -f
/var/log/messages 可以实时查看 messages 日志文件的更新情况。
2. cat:查看整个日志文件。
例如:cat /var/log/messages 可以查看 messages 日志文件的全部内容。
3. less:分页查看日志文件,可以向前或向后翻页。
例如:less /var/log/messages 可以查看 messages 日志文件的内容,并且可以使用 PageUp、PageDown、/、? 等键进行翻页。
4. grep:查找日志文件中包含指定关键字的行。
例如:grep
'error' /var/log/messages 可以查找 messages 日志文件中所有
包含 error 关键字的行。
5. sed:使用正则表达式替换日志文件中的内容。
例如:sed
's/error/warning/g' /var/log/messages 可以将 messages 日志
文件中所有的 error 替换成 warning。
6. awk:对日志文件进行统计和分析。
例如:awk '{print $1}' /var/log/messages 可以查看 messages 日志文件中的第一列(通常是时间)。
以上是一些常用的查看日志的命令,系统管理员可以根据实际情况选择合适的命令进行操作。
- 1 -。
Spring Boot框架中的应用监控与日志管理
Spring Boot框架中的应用监控与日志管理Spring Boot框架是一款基于Spring框架的微服务构建工具,它简化了Spring应用程序的开发过程,并集成了许多常用的功能模块。
其中,应用监控与日志管理是Spring Boot框架中非常重要的功能之一,它能够帮助开发人员实时监控应用的运行状态,及时发现和解决问题,并记录应用的运行日志以便后续分析和排查问题。
本文将深入探讨Spring Boot框架中应用监控与日志管理的相关内容,包括具体功能、实现原理以及最佳实践。
应用监控是保证应用高可用性和高性能的关键手段之一。
Spring Boot框架提供了丰富的监控功能,包括健康检查、性能指标、HTTP追踪等。
其中,健康检查是最为基础和重要的监控功能,通过访问/actuator/health端点,可以获取当前应用的健康状态。
Spring Boot框架默认集成了很多自动配置的健康检查项,包括数据库连接、磁盘空间、线程池状态等。
除此之外,开发人员还可以扩展自定义的健康检查项,比如检查外部服务的可用性。
性能指标是另一个重要的监控功能,Spring Boot框架通过Micrometer库提供了丰富的性能指标支持,包括内存使用、CPU负载、请求处理时间等。
借助这些性能指标,开发人员可以实时监控应用的性能表现,并做出相应的调优优化。
日志管理是应用监控的重要组成部分,它记录了应用运行过程中产生的各种信息,包括调试信息、错误信息、警告信息等。
Spring Boot框架提供了强大的日志管理功能,基于Logback库实现了灵活的日志配置和强大的日志输出。
开发人员可以通过application.properties或application.yml文件,配置日志级别、日志输出目标、日志格式等参数,满足不同环境下的日志记录需求。
同时,Spring Boot框架还提供了统一的日志输出接口,开发人员可以通过Log接口进行日志输出,而无需关心具体的日志实现。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.AOP及其相关概念
1)AOP 面向切面(方面)编程
主要解决共通处理问题.可以将共通处理部分单独用一个
组件封装起来,然后利用SpringAOP机制作用到某一批目标对象
上面.从而降低共通处理对象和目标对象之间关联.
AOP与OOP关系,OOP面向对象编程,侧重于对象的封装. AOP面向切面编程是以OOP为基础,侧重于对共通处理的操作.
改善程序结构,提高灵活性.
2)切面(方面)Aspect
指的是共通处理部分的代码.也称为关注点的实现.
3)连接点Joinpoint
指的是作用在目标对象上的位置.例如方法调用,异常发生后等 4)切入点Pointcut
指的是连接点的集合,对应一个切入点表达式.
5)目标对象Target Object
指的是使用切面功能的对象.需要在Spring容器中.
6)通知 Advice
指的是连接点作用的时机.例如方法调用前,方法调用后
执行切面功能等.
7)动态代理AutoProxy
采用AOP之后,Spring会为每一个目标对象创建一个代理对象,该代理对象相当于切面和目标对象功能的结合体. Spring采用两种方式:
a.JDK Proxy方式
适用于目标对象有接口.
b.CGLIB方式
适用于目标对象没有接口.
2.AOP使用示例
1)示例步骤
a.引入jar包
aspectjweaver.jar
aspectjrt.jar
cglib-nodep-2.1_3.jar
commons-logging.jar
spring.jar
b.寻找关注点,采用切面组件封装.
c.在spring配置中添加AOP配置
添加aop命名空间
指定切面<aop:aspect/>
定义切入点<aop:pointcut/>
指定切入点采用哪种类型的通知<aop:before/>
3.通知类型
1)前置通知<aop:before/>
目标对象方法调用前执行.
2)后置通知<aop:after-returning/>
目标对象方法成功调用之后执行.
3)最终通知<aop:after/>
目标对象方法调用之后执行,不论是成功还是失败.
4)环绕通知<aop:around/>
目标对象方法调用之前和之后执行.
5)异常通知<aop:after-throwing/>
目标对象方法调用出现异常后执行.
try{
前置通知
环绕通知1
目标对象方法
环绕通知1
后置通知
}catch(){
异常通知
}finally{
最终通知
}
4.切入点表达式
*1)方法限定execution
示例1:任意公共方法的执行
execution (public * *(..))
示例2:任何一个名字以“set”开始的方法的执行
execution (* set*(..))
示例3:AccountService中定义的任意方法的执行
execution (* service.AccountService.*(..)) 示例4:在service包中定义的任意方法的执行
execution (* service.*.*(..))
示例5:在service包或其子包中定义的任意方法的执行
execution (* service..*.*(..))
*2)类型限定within
示例1:AccountService中定义的任意方法的执行
within (service.AccountService)
示例2:在service包中定义的任意类型的任意方法
within (service.*)
示例3:在service包或其子包中定义的任意类型的任意方法 within (service..*)
*3)Bean对象名限定bean
示例:匹配所有的id或name名字以Service结束的组件
bean(*Service)
4)特定类型限定this或target
this指的是限定特定的代理类型
target指的是限定特定的目标对象类型
示例1:实现了AccountService的代理对象
this (service.AccountService)
示例2:实现了AccountService的目标对象
target (service.AccountService)
5)方法参数限定args
示例:匹配方法有一个String参数的
args (ng.String)
5.AOP示例
1)异常日志的记录 (异常通知类型)
2)操作日志的记录 (环绕通知类型)
王明河 2011-11-2。