精华内容
下载资源
问答
  • 在配置文件中配置了Mybatis的相关参数,将sql语句输入控制台上,但是在生产上我们为了排错或者查看sql的执行过程,就需要查看日志,所以Mybatis执行sql不仅要控制台打印输出,还要写入日志文件待查。...

    一 概述

    1.1 概述

    我们在本地开发,在配置文件中配置了Mybatis的相关参数,将sql语句输入到控制台上,但是在生产上我们为了排错或者查看sql的执行过程,就需要查看日志,所以Mybatis执行sql不仅要能在控制台打印输出,还要能写入日志文件待查。之前看过的好多博客只是解决了日志向控制台打印的问题。怎么将日志写到制定的文件,遇到了好了问题,无法将日志写到制定的文件中,
    麻蛋,网上一堆资料,都是瞎比咧咧,解决不了问题,自己通过专研,终于实现了将日志输入到制定的文件当中。由于Mybatis执行sql的日志级别为DEBUG,一般生产上需要的日志级别为INFO及以上。如果将DEBUG级别日志全部写入日志文件,会造成日志查问题的速度降低,难度大大提高。

    所以建议:将Mybatis执行sql的日志只能向更高日志级别的日志文件追加或单独写入一个文件。

    1.2 解决办法

    当时配置好springboot和logback,无法将mybaits的sql语句写入到制定文件的原因是,日志的输出方式没有配对

      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl     改为:log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl

    应该配置成:

    1.3 logback中onmatch与onmismatch的区别

    二 案例演示 

    2.1 项目结构

    2.2.代码说明

    2.2.1pom文件

     <!-- springBoot的启动器 -->
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
          <version>2.0.1.RELEASE</version>
        </dependency>
        <!-- web启动器 -->
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-thymeleaf</artifactId>
          <version>2.0.1.RELEASE</version>
        </dependency>
        <!-- Mybatis启动器 -->
        <dependency>
          <groupId>org.mybatis.spring.boot</groupId>
          <artifactId>mybatis-spring-boot-starter</artifactId>
          <version>1.1.1</version>
        </dependency>
        <!-- mysql数据库驱动 -->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.3</version>
        </dependency>
        <!-- druid数据库连接池 -->
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.0.9</version>
        </dependency>

    2.2.2 controller层

    package com.ljf.spring.boot.demo.persistence.controller;
    
    import com.ljf.spring.boot.demo.persistence.model.Users;
    import com.ljf.spring.boot.demo.persistence.service.UserService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import java.util.List;
    
    /**
     * @ClassName: UserController
     * @Description: TODO
     * @Author: liujianfu
     * @Date: 2020/07/29 15:45:36
     * @Version: V1.0
     **/
    @Controller
    @RequestMapping("/users")
    public class UserController {
        private static final Logger logger = LoggerFactory.getLogger(UserController.class);
        @Autowired
        private UserService usersService;
    
        /**
         * 页面跳转
         */
        @RequestMapping("/{page}")
        public String showPage(@PathVariable String page){
            System.out.println("进来了!!!"+page);
            return page;
        }
    
        /**
         * 添加用户
         */
        @RequestMapping("/addUser")
        public String addUser(Users users){
            System.out.println("users:"+users.getName());
            this.usersService.addUser(users);
            return "ok";
        }
    
        /**
         * 查询全部用户
         */
        @RequestMapping("/findUserAll")
        public String findUserAll(Model model){
            logger.info("=========================================查询全部用户信息!!!!!!!!!!!!!!!!!!!!!");
            List<Users> list = this.usersService.findUserAll();
            model.addAttribute("list", list);
            return "showUsers";
        }
        /**
         * 根据用户id查询用户
         */
        @RequestMapping("/findUserById")
        public String findUserById(Integer id,Model model){
            Users user = this.usersService.findUserById(id);
            model.addAttribute("user", user);
            System.out.println("update:"+user);
            return "updateUser";
        }
        /**
         * 更新用户
         */
        @RequestMapping("/editUser")
        public String editUser(Users users){
            this.usersService.updateUser(users);
            return "ok";
        }
        /**
         * 删除用户
         */
        @RequestMapping("/delUser")
        public String delUser(Integer id){
            this.usersService.deleteUserById(id);
            return "redirect:/users/findUserAll"; //重定向页面
        }
    
    }
    

    2.2.3 dao层

    package com.ljf.spring.boot.demo.persistence.dao;
    
    
    import com.ljf.spring.boot.demo.persistence.model.Users;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface UsersMapper {
    	
    	void insertUser(Users users);
    	List<Users> selectUsersAll();
    	Users selectUsersById(Integer id);
    	void updateUser(Users users);
    	void deleteUserById(Integer id);
    
    }
    

    2.2.4 其他层

    其他层不是这篇博客的重点不在贴出,只贴出相应的结构图

    2.3. 日志输入到不同文件

    2.3.1 .application的配置文件

    server:
      port: 8081
    spring:
      datasource:
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test_db
        username: root
        password: root
        type: com.alibaba.druid.pool.DruidDataSource
    mybatis:
      mapper-locations: classpath:mapper/*.xml
      type-aliases-package: com.ljf.spring.boot.demo.persistence.model
      configuration:
        #增加打印sql语句,将日志写入到制定的日志文件当中
        log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
         #增加打印sql语句,一般用于本地开发测试
        #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    logging:
      config: classpath:logback-spring-fen.xml

    2.3.2 logback.xml的配置

    配置自己项目的dao层路径,日志级别为info

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <property name="LOG_PATH" value="../logs"/>
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder charset="UTF-8">
                <pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
            </encoder>
        </appender>
        <!--sql日志-->
        <appender name="APP_SQL" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!--活动日志输出路径示例-->
            <file>${LOG_PATH}/sql.log</file>
            <append>true</append>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>DEBUG</level>
                <!-- onMatch:意思是当前级别以及以上要怎么处理 -->
                <onMatch>ACCEPT</onMatch>
                <!-- onMismatch:意思是当前级别(不包括当前级别)以下要怎么处理 -->
                <onMismatch>DENY</onMismatch>
            </filter>
            <!--存档日志示例-->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/sql.%i.log
                </fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <!--日志大小可自定义-->
                    <maxFileSize>100MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <!--存档天数可自定义-->
                <maxHistory>90</maxHistory>
            </rollingPolicy>
            <!--统一日志输出格式-->
            <encoder charset="UTF-8">
                <pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
            </encoder>
        </appender>
        <!--info日志-->
        <appender name="APP_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!--活动日志输出路径示例-->
            <file>${LOG_PATH}/info.log</file>
            <append>true</append>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>INFO</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
            <!--存档日志示例-->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/info.%i.log
                </fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <!--日志大小可自定义-->
                    <maxFileSize>100MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <!--存档天数可自定义-->
                <maxHistory>90</maxHistory>
            </rollingPolicy>
            <!--统一日志输出格式-->
            <encoder charset="UTF-8">
                <pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
            </encoder>
        </appender>
        <!--ERROR日志-->
        <appender name="APP_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${LOG_PATH}/error.log</file>
            <append>true</append>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>ERROR</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/error.%i.log
                </fileNamePattern>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>100MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
                <maxHistory>90</maxHistory>
            </rollingPolicy>
    
            <encoder charset="UTF-8">
                <pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
            </encoder>
        </appender>
        <!--<appender name="CatAppender" class="com.baojia.bike.config.CatLogbackAppender"></appender>-->
        <logger name="com.ljf.spring.boot.demo.persistence.dao" level="DEBUG">
            <appender-ref ref="APP_SQL"/>
        </logger>
        <!--调试模式下可以改为debug-->
        <root level="INFO">
            <!--<appender-ref ref="CatAppender" />-->
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="APP_ERROR"/>
            <appender-ref ref="APP_INFO"/>
        </root>
    </configuration>

    2.3.3 执行访问,产生日志

    看看日志目录:

    logs和工程是平级的,进入logs文件夹后,可以看到产生了error,info,sql三种信息的日志文件

    查看sql文件:

    2.4  将日志输入到相同文件

    2.4.1 application的配置文件

    server:
      port: 8081
    spring:
      datasource:
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test_db
        username: root
        password: root
        type: com.alibaba.druid.pool.DruidDataSource
    mybatis:
      mapper-locations: classpath:mapper/*.xml
      type-aliases-package: com.ljf.spring.boot.demo.persistence.model
      configuration:
        #增加打印sql语句,将日志写入到制定的日志文件当中
        log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
         #增加打印sql语句,一般用于本地开发测试
        #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    logging:
      3config: classpath:logback-spring-fen.xml
      config: classpath:logback-spring-he.xml

    2.4.2 logback配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="60 seconds" debug="false">
        <property name="LOG_PATH" value="D:/spt-logback-demo-logs"/>
         <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> 
        <property name="LOG_STDOUT_PATTERN" 
        value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
        <property name="LOG_FILE_PATTERN" 
        value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
    
        <!-- 输出到控制台 -->
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <!-- 输出的格式 -->
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${LOG_STDOUT_PATTERN}</pattern>
            </encoder>
        </appender>
    
        <!-- 生成日志文件 -->
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 日志名称 -->
            <file>${LOG_PATH}/spt-logback.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern>${LOG_PATH}/14-spt.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <!-- 日志最大 50MB -->
                <maxFileSize>50MB</maxFileSize>
                <!-- 保存 30 天 -->
                <maxHistory>30</maxHistory>
                <!--            <totalSizeCap>10GB</totalSizeCap>  &lt;!&ndash; 总日志大小 &ndash;&gt;-->
            </rollingPolicy>
    
            <encoder>
                <pattern>${LOG_FILE_PATTERN}</pattern>
            </encoder>
        </appender>
        <!--
        <logger name="org.influxdb" level="INFO"/> -->
        <logger name="com.ljf.spring.boot.demo.persistence.dao" level="debug"/>
    
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
        </root>
    
    </configuration>

    2..4.3 页面访问,产生日志

    查看日志的目录: 

     

    查看日志:

    2021-03-24 17:48:10.870 [main] INFO  c.l.spring.boot.demo.persistence.App - Starting App on LAPTOP-VC53HCIP with PID 33028 (E:\springboot-project\spring-boot-demo\04-spt-tx-persistence-crud\target\classes started by jurfl in E:\springboot-project\spring-boot-demo)
    2021-03-24 17:48:10.873 [main] INFO  c.l.spring.boot.demo.persistence.App - No active profile set, falling back to default profiles: default
    2021-03-24 17:48:10.933 [main] INFO  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@43bc63a3: startup date [Wed Mar 24 17:48:10 CST 2021]; root of context hierarchy
    2021-03-24 17:48:12.146 [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8081 (http)
    2021-03-24 17:48:12.161 [main] INFO  o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8081"]
    2021-03-24 17:48:12.169 [main] INFO  o.a.catalina.core.StandardService - Starting service [Tomcat]
    2021-03-24 17:48:12.170 [main] INFO  o.a.catalina.core.StandardEngine - Starting Servlet Engine: Apache Tomcat/8.5.29
    2021-03-24 17:48:12.174 [localhost-startStop-1] INFO  o.a.c.core.AprLifecycleListener - The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_181\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;d:\app\as\product\12.1.0\dbhome_1\bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Java\jdk1.8.0_181\bin;D:\apache-maven-3.6.0\bin;D:\apache-tomcat-8.5.6\bin;C:\Program Files\TortoiseSVN\bin;D:\mysql-5.7.21-winx64\bin;C:\Program Files\Git\bin;D:\xshell-manager\Xmanager 7\;D:\xshell-manager\Xshell 7\;D:\xshell-manager\Xftp 7\;D:\xshell-manager\Xlpd 7\;C:\Users\jurfl\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\bin;;.]
    2021-03-24 17:48:12.325 [localhost-startStop-1] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
    2021-03-24 17:48:12.325 [localhost-startStop-1] INFO  o.s.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 1392 ms
    2021-03-24 17:48:12.502 [localhost-startStop-1] INFO  o.s.b.w.s.ServletRegistrationBean - Servlet dispatcherServlet mapped to [/]
    2021-03-24 17:48:12.506 [localhost-startStop-1] INFO  o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*]
    2021-03-24 17:48:12.507 [localhost-startStop-1] INFO  o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
    2021-03-24 17:48:12.507 [localhost-startStop-1] INFO  o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*]
    2021-03-24 17:48:12.507 [localhost-startStop-1] INFO  o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*]
    2021-03-24 17:48:12.866 [main] INFO  o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
    2021-03-24 17:48:13.042 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@43bc63a3: startup date [Wed Mar 24 17:48:10 CST 2021]; root of context hierarchy
    2021-03-24 17:48:13.146 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/addUser]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.addUser(com.ljf.spring.boot.demo.persistence.model.Users)
    2021-03-24 17:48:13.147 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/findUserAll]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.findUserAll(org.springframework.ui.Model)
    2021-03-24 17:48:13.147 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/{page}]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.showPage(java.lang.String)
    2021-03-24 17:48:13.148 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/findUserById]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.findUserById(java.lang.Integer,org.springframework.ui.Model)
    2021-03-24 17:48:13.148 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/editUser]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.editUser(com.ljf.spring.boot.demo.persistence.model.Users)
    2021-03-24 17:48:13.148 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/delUser]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.delUser(java.lang.Integer)
    2021-03-24 17:48:13.151 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
    2021-03-24 17:48:13.152 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
    2021-03-24 17:48:13.174 [main] INFO  o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
    2021-03-24 17:48:13.175 [main] INFO  o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
    2021-03-24 17:48:13.453 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
    2021-03-24 17:48:13.454 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Bean with name 'dataSource' has been autodetected for JMX exposure
    2021-03-24 17:48:13.461 [main] INFO  o.s.j.e.a.AnnotationMBeanExporter - Located MBean 'dataSource': registering with JMX server as MBean [com.alibaba.druid.pool:name=dataSource,type=DruidDataSource]
    2021-03-24 17:48:13.473 [main] INFO  o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8081"]
    2021-03-24 17:48:13.486 [main] INFO  o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
    2021-03-24 17:48:13.502 [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8081 (http) with context path ''
    2021-03-24 17:48:13.506 [main] INFO  c.l.spring.boot.demo.persistence.App - Started App in 3.085 seconds (JVM running for 5.95)
    2021-03-24 17:48:22.617 [http-nio-8081-exec-1] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
    2021-03-24 17:48:22.618 [http-nio-8081-exec-1] INFO  o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
    2021-03-24 17:48:22.647 [http-nio-8081-exec-1] INFO  o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 29 ms
    2021-03-24 17:48:22.673 [http-nio-8081-exec-1] INFO  c.l.s.b.d.p.c.UserController - =========================================查询全部用户信息!!!!!!!!!!!!!!!!!!!!!
    2021-03-24 17:48:22.701 [http-nio-8081-exec-1] INFO  c.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited
    2021-03-24 17:48:22.837 [http-nio-8081-exec-1] DEBUG c.l.s.b.d.p.d.U.selectUsersAll - ==>  Preparing: select id,name,age from tb_users 
    2021-03-24 17:48:22.849 [http-nio-8081-exec-1] DEBUG c.l.s.b.d.p.d.U.selectUsersAll - ==> Parameters: 
    2021-03-24 17:48:22.861 [http-nio-8081-exec-1] DEBUG c.l.s.b.d.p.d.U.selectUsersAll - <==      Total: 7
    2021-03-24 17:48:30.972 [http-nio-8081-exec-3] DEBUG c.l.s.b.d.p.d.U.selectUsersById - ==>  Preparing: select id,name,age from tb_users where id = ? 
    2021-03-24 17:48:30.972 [http-nio-8081-exec-3] DEBUG c.l.s.b.d.p.d.U.selectUsersById - ==> Parameters: 1(Integer)
    2021-03-24 17:48:30.973 [http-nio-8081-exec-3] DEBUG c.l.s.b.d.p.d.U.selectUsersById - <==      Total: 1
    

     

    展开全文
  • CONSOLE将日志信息输出到控制上,为方便开发测试使用 --> <!-- 日志记录器,日期滚动记录 --> <!-- 正在记录的日志文件的路径及文件名 --> ${LOG_PATH}/error_statisticserver.log <!-- 日志记录器的...
  • 说明:很遗憾,IDEA中无法实现日志分类查看,比如只能显示INFO级别的,但是...直接使用IDEA导入输出的日志文件,就可以实现比如logback配置了不向上传递导致控制台能输出日志的查看。 参考: http://blog.csd...

    说明:很遗憾,IDEA中无法实现日志分类查看,比如只能显示INFO级别的,但是可以有搜索功能【Ctrl】+【F】。好像找不到好用的插件,Andorid Studio好像有一个插件可以。

    解决方式:

    直接使用IDEA导入输出的日志文件,就可以实现比如logback配置了不向上传递导致控制台不能输出日志的查看。

     

    参考:

    http://blog.csdn.net/yang292292/article/details/53353774

    https://www.jetbrains.com/help/idea/2016.2/run-debug-configurations.html

    https://www.jetbrains.com/help/idea/2016.2/setting-log-options.html

    ==>如有问题,请联系我:easonjim#163.com,或者下方发表评论。<==
    展开全文
  • 如果不在启动目录(默认为 %systemroot%System32)中找到该文件,将试着在 Windows 安装 CD 中找到它。如果有多引导系统的计算机,必须保证是在包含 Windows 的驱动器上使用该命令。 Diskpart  创建和删除硬盘...
  • Unity 自定义Log系统

    千次阅读 2018-08-14 20:36:43
    原因 1.测试跑IOS的时候,游戏卡死,但是无法查看日志,因为必须将手机插在mac机器上,用xcode才能实时看日志。...1.让日志可以输出到3个地方:(1)控制台(2)界面 (3)文件 2.能输出游戏指定模块的日志 ...

    原因

    1.测试跑IOS的时候,游戏卡死,但是却无法查看日志,因为必须将手机插在mac机器上,用xcode才能实时看日志。

    2.Android虽然卡死后,可以再插上电脑,通过AndroidStudio查看已经输出的日志,但是也会遇到看不到日志,或者手机插上无法被ADB侦测的问题。

     

    目标

    1.让日志可以输出到3个地方:(1)控制台(2)界面 (3)文件

    2.能输出游戏指定模块的日志

    3.能输出特定级别的日志,如error,warning等

     

    代码

    注:UI组件YYUIWrapContent未贴上,如果需要使用,你们可以不使用输入到ui的功能。

    using System.Collections.Generic;
    using System.IO;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class DebugLog
    {
        public enum OutputModule
        {
            eNone,
            ePve = 1,
            eWonderland = 2,
            eTrial = 3,
            eMainScene = 4,
            eUI = 5,
            eOther = 6,
            ePveBase = 7,
            eMiniGame = 8,
            eGM = 9,
            eProxy = 10,
            eLoader = 11,
            eBattle = 12,
            eResLoad = 13,
            eNetWork = 14,
            eStory = 15,
            ePlatform = 16,
        }
    
        public enum OutputTarget
        {
            eNone,
            eConsole = 1,
            eUI = 2,
            eFile = 3,
        }
    
        public enum OutputLevel
        {
            eNone,
            eLog = 1,
            eLogWaning = 2,
            eLogError = 3,
        }
    
        //全局控制是否开启日志
        public static bool isOpenLog;
        //控制输出的模块
        private static int outputModule;
        //控制输出的目标
        private static int outputTarget;
        //控制输出的等级
        private static int outputLevel;
        //文件路径
        private static string filePath;
        //ui显示最大缓存的日志数量
        private const int MAX_LOG_NUM = 1000;
        private static List<string> logList = new List<string>();
        //ui组件,实现循环滚动
        private static YYUIWarpContent wrapContent;
    
        public static void Init(YYUIWarpContent uiContent)
        {
            Application.logMessageReceived += LogCallback;
    
            //获取文件路径
            filePath = GetPath("LJSLogFile.txt");
            //删除已存在的文件
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
            //获取ui组件
            wrapContent = uiContent;
            //是否要输出日志
            isOpenLog = true;
    
            //指定要输出哪些模块
            SwitchModule(OutputModule.ePve, true);
            SwitchModule(OutputModule.eWonderland, true);
            SwitchModule(OutputModule.eTrial, true);
            SwitchModule(OutputModule.eMainScene, true);
            SwitchModule(OutputModule.eUI, true);
            SwitchModule(OutputModule.eOther, true);
            SwitchModule(OutputModule.ePveBase, true);
            SwitchModule(OutputModule.eMiniGame, true);
            SwitchModule(OutputModule.eGM, true);
            SwitchModule(OutputModule.eProxy, true);
            SwitchModule(OutputModule.eLoader, true);
            SwitchModule(OutputModule.eBattle, true);
            SwitchModule(OutputModule.eResLoad, true);
            SwitchModule(OutputModule.eNetWork, true);
            SwitchModule(OutputModule.eStory, true);
            SwitchModule(OutputModule.ePlatform, true);
    
            //指定要输出的目标
            SwitchTarget(OutputTarget.eConsole, true);
            SwitchTarget(OutputTarget.eUI, true);
            //SwitchTarget(OutputTarget.eFile, true);
    
            //指定输出的级别
            SwitchLevel(OutputLevel.eLog, true);
            SwitchLevel(OutputLevel.eLogWaning, true);
            SwitchLevel(OutputLevel.eLogError, true);
    
        }
    
        public static void LogCallback(string condition, string stackTrace, LogType type)
        {
            string result = "";
            if (type == LogType.Error || type == LogType.Log || type == LogType.Warning)
            {
                result = condition;
            }
            else
            {
                result = string.Format("{0}\n{1}", condition, stackTrace);
            }
    
            OutputUI(result);
            OutputFile(result);
        }
    
        public static void Log(OutputModule type, string message)
        {
            if (!IsOuputLog(type, OutputLevel.eLog))
            {
                return;
            }
    
            message = ModifyLog(message, 0);
            OutputConsole(message, 0);
        }
    
        public static void LogWarning(OutputModule type, string message)
        {
            if (!IsOuputLog(type, OutputLevel.eLogWaning))
            {
                return;
            }
     
            message = ModifyLog(message, 1);
            OutputConsole(message, 1);
        }
    
        public static void LogError(OutputModule type, string message)
        {
            if (!IsOuputLog(type, OutputLevel.eLogError))
            {
                return;
            }
    
            message = ModifyLog(message, 2);
            OutputConsole(message, 2);
        }
    
        private static void OutputConsole(string message, int type)
        {
            if(!IsOutputTarget(OutputTarget.eConsole))
            {
                return;
            }
    
            if (type == 0)
            {
                Debug.Log(message);
            }
            else if (type == 1)
            {
                Debug.LogWarning(message);
            }
            else if (type == 2)
            {
                Debug.LogError(message);
            }
        }
    
        private static void OutputFile(string message)
        {
            if (!IsOutputTarget(OutputTarget.eFile))
            {
                return;
            }
    
            FileStream fs = File.Open(filePath, FileMode.Append, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(message);
            sw.Close();
            fs.Close();
        }
    
        private static void OutputUI(string message)
        {
            if (!IsOutputTarget(OutputTarget.eUI))
            {
                return;
            }
    
            if(logList.Count >= MAX_LOG_NUM)
            {
                logList.Clear();
            }
            logList.Add(message);
            wrapContent.Init(logList.Count, (obj, index) =>
            {
                Text text = obj.GetComponent<Text>();
                text.text = logList[index];
            }, null, false);
        }
    
        private static bool IsOuputLog(OutputModule type, OutputLevel level)
        {
            bool result = false;
            bool rule1 = (outputModule & (1 << (int)type)) > 0 ? true : false;
            bool rule2 = isOpenLog;
            bool rule3 = (outputLevel & (1 << (int)level)) > 0 ? true : false;
            if (rule1 && rule2 && rule3)
            {
                result = true;
            }
    
            return result;
        }
    
        private static bool IsOutputTarget(OutputTarget target)
        {
            bool result = false;
            result = (outputTarget & (1 << (int)target)) > 0 ? true : false;
            return result;
        }
    
        private static string ModifyLog(string message, int type)
        {
            string result = "";
            switch (type)
            {
                case 0:
                    {
                        result += "common : ";
                    }
                    break;
                case 1:
                    {
                        result += "warning : ";
                    }
                    break;
                case 2:
                    {
                        result += "error : ";
                    }
                    break;
            }
            result += message;
            return result;
        }
    
        private static string GetPath(string name)
        {
            string path = "";
            switch (Application.platform)
            {
                case RuntimePlatform.Android:
                case RuntimePlatform.IPhonePlayer:
                    {
                        path = Application.persistentDataPath + "/" + name;
                    }
                    break;
                case RuntimePlatform.OSXEditor:
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.WindowsPlayer:
                    {
                        path = Application.dataPath + "/../" + name;
                    }
                    break;
            }
    
            return path;
        }
    
        public static void SwitchModule(OutputModule module, bool isOpen)
        {
            if (isOpen)
            {
                outputModule = outputModule | (1 << (int)module);
            }
            else
            {
                outputModule = outputModule & (~(1 << (int)module));
            }
        }
    
        public static void SwitchTarget(OutputTarget target, bool isOpen)
        {
            if(isOpen)
            {
                outputTarget = outputTarget | (1 << (int)target);
            }
            else
            {
                outputTarget = outputTarget & (~(1 << (int)target));
            }
        }
    
        public static void SwitchLevel(OutputLevel level, bool isOpen)
        {
            if (isOpen)
            {
                outputLevel = outputLevel | (1 << (int)level);
            }
            else
            {
                outputLevel = outputLevel & (~(1 << (int)level));
            }
        }
    }
    
    

     

    展开全文
  • 虽然C++一直在强调尽量少用宏,但是宏确实是个好东西,会使代码很简洁,使人欲罢不能。 近期出现一个无法理解的异常,找了很长时间,结果发现是调用的别人的宏导致的,差点...而开发环境下,直接打印到控制台更方便查

    虽然C++一直在强调尽量少用宏,但是宏确实是个好东西,会使代码很简洁,使人欲罢不能。

    近期出现一个无法理解的异常,找了很长时间,结果发现是调用的别人的宏导致的,差点吐血。

    实际工作中,日志是定位程序错误的常用手段之一。不同等级的日志输出,代表不同的错误级别,有一些仅仅是警告,对程序运行无任何影响,则只需要打印出来即可;但有一些是严重的错误,会对后续程序的运行影响很大,除了打印信息外,最好还能直接断言,提示开发人员。

    程序实际运行时,一般错误日志都是写到日志文件中;而开发环境下,直接打印到控制台更方便查看。想要实现这个功能,用宏来控制再方便不过。

    开发环境visual studio 2013, 代码如下:

    #include <iostream>
    #include <assert.h>
    #ifdef _DEBUG
    	#define LOG_I(x) std::cout << "警告:" << x << std::endl
    	#define LOG_E(x) std::cout << "错误:" << x << std::endl; assert(false)
    #else
    	//有关文件的操作省略
    #endif
    int _tmain(int argc, _TCHAR* argv[])
    {
    	LOG_I("有瑕疵");
    	LOG_E("有错误");
    
    
    	system("pause");
    	return 0;
    }

    这里很简单,如果定义了_DEBUG宏,即开发调试环境,则将日志打印到控制台;否则,将日志写到对应文件中(简单起见,此处省略)。注意,宏定义最后面是没有分号的。

    编译运行,结果如下:

    LOG_E宏除了打印错误日志外,还会触发断言,这里这样使用没任何问题。

    但是,日志的打印,一般都会有条件判断,即某错误条件成立后,才打印日志。代码调整如下:

    #include <iostream>
    #include <assert.h>
    #ifdef _DEBUG
    	#define LOG_I(x) std::cout << "警告:" << x << std::endl
    	#define LOG_E(x) std::cout << "错误:" << x << std::endl; assert(false) 
    #else
    	//有关文件的操作省略
    #endif
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int iValue;
    	std::cout << "请输入一个偶数:";
    	std::cin >> iValue;
    	if (iValue % 2 == 0)
    		LOG_I("数据正确");
    	else
    		LOG_E("数据错误");
    
    
    	system("pause");
    	return 0;
    }

    运行,输入1,结果如下:

    和预想的一致,似乎没什么问题。但是如果输入的2,什么情况呢?

    纳尼?发生了什么?

    仔细看代码,用具体代码替换掉宏,if语句的代码就是如下:

    问题就出在LOG_E宏上,里面有多条语句。展开后,只有第一条语句在else作用域内,第二条则一定会指定。

    想要解决该怎么办?有两种方式:

    1、在条件判断语句后面加上{}

    调整后的代码如下:

    #include <iostream>
    #include <assert.h>
    #ifdef _DEBUG
    	#define LOG_I(x) std::cout << "警告:" << x << std::endl
    	#define LOG_E(x) std::cout << "错误:" << x << std::endl; assert(false) 
    #else
    	//有关文件的操作省略
    #endif
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int iValue;
    	std::cout << "请输入一个偶数:";
    	std::cin >> iValue;
    	if (iValue % 2 == 0)
    	{
    		LOG_I("数据正确");
    	}		
    	else
    	{
    		LOG_E("数据错误");
    	}
    
    	system("pause");
    	return 0;
    }

    运行后结果如下:

    结果正确!

    但如果你是宏的设计者,则需要为你设计的宏负责,用下面的方式更合适。

    2、多条语句的宏,用{}将多条语句括起来

    修改代码如下:

    #include <iostream>
    #include <assert.h>
    #ifdef _DEBUG
    	#define LOG_I(x) std::cout << "警告:" << x << std::endl
    #define LOG_E(x) { std::cout << "错误:" << x << std::endl; assert(false); }
    #else
    	//有关文件的操作省略
    #endif
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int iValue;
    	std::cout << "请输入一个偶数:";
    	std::cin >> iValue;
    	if (iValue % 2 == 0)
    		LOG_I("数据正确");
    	else
    		LOG_E("数据错误");
    
    	system("pause");
    	return 0;
    }

    执行结果如下:

    没问题!

    有关宏的使用,一定要谨慎,特别是和条件判断语句搭配使用。

    宏后面是否有";"也需要注意,和条件语句一起,也可能产生意想不到的问题。

     

     

    展开全文
  • rar压缩软件.rar

    2016-02-13 10:52:44
    等写到日志文件中。读取开关 -ilog 描述获得更多信息。 固实压缩的文件列表 - rarfiles.lst ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rarfiles.lst 包含一个用户定义的文件列表,告诉 RAR 添加文件到固实压缩文件...
  • WinRAR_4.0.exe

    2011-02-04 11:34:33
    等写到日志文件中。读取开关 -ilog 描述获得更多信息。 固实压缩的文件列表 - rarfiles.lst rarfiles.lst 包含一个用户定义的文件列表,告诉 RAR 添加文件到固实压缩文件时的顺 序。它可以包含文件名通配符...
  • 当你需要发送一个文件到标准输出设备时,这也许很重要。 r 修复压缩文件。压缩文件修复是在两阶段中完成的。首先,在损坏的压缩 文件中查找恢复记录(参照'rr'命令)。如果压缩文件包含恢复记录,并且 损坏...
  • WINRAR5.0正式注册版

    2013-10-10 10:14:03
    文件名日志文件中正确存储。WinRAR 会自动删除非 Unicode 格式的旧 rar.log 文件来避免同一日志文件中混合不同的编码。控制台 RAR 的情况下,你需要手动删除 旧的 rar.log,否则 RAR 会在现有的 rar.log 后...
  • 可能是一个包含注册表数据文件的结构已损坏,也可能内存中该文件的系统映像已损坏,或者因为备份副本(或日志)不存在(或损坏)导致无法恢复该文件。  1016 由注册表引起的 I/O 操作发生了不可恢复的错误。...
  • McAfee 8.0 简体中文

    热门讨论 2006-02-16 11:06:30
    - 日志文件格式 - Lotus Notes - 镜像任务 - 扫描 - 有害程序策略 - 文档 - 参与 McAfee 测试程序的测试 - 联系信息 - 版权和商标归属 - 许可和专利信息 _________________________________...
  • 电脑蓝屏对照码

    2019-05-05 14:16:40
    有时保卫科可以顺利的查是哪个生产小组的问题, 会在第一部分明确报告是哪个文件犯的错, 但常常它也只能查个大概范围, 而无法明确指明问题所在. 由于工厂全面被迫停止, 只有重新整顿开工, 有时, 那个生产小组会意识...
  • winrar3.7 Beta8

    2007-07-07 00:17:02
    <br> 到处的设置文件 settings.reg 默认也被保存 %APPDATA%\WinRAR 文件夹中, 但是 也可以在“保存 WinRAR 设置”和 “加载 WinRAR 设置” 对话框中选择其他的文件 夹。 <br> WinRAR 在它的 ...
  • WIN XP蓝屏代码大全

    2013-08-08 12:29:21
    有时保卫科可以顺利的查是哪个生产小组的问题, 会在第一部分明确报告是哪个文件犯的错, 但常常它也只能查个大概范围, 而无法明确指明问题所在. 由于工厂全面被迫停止, 只有重新整顿开工, 有时, 那个生产小组会意识...
  • 电脑问题大搜捕

    2011-11-01 10:01:37
    协调器) 相关的文件, 分布式事务协调器可用于控制不同程序或进程间的的事务输出 和 消息传递. 可以删除) 24)mui(包含了多国语言用户界面的相关文件.可以删除) 25)npp(包含了一些用于在网络监视服务器上...
  • 如果你不会配置表单组默认选项配置,请先配置好user信息之后本地执行generate.py,根据提示信息手动输入,然后将分割线下的内容复制配置文件中对应位置 如果问题中有省市县三级联动的位置,按xx省/xx市/xx县这个...
  • 在命令行输入,gradlew compileDebugSources,可以查看打印报错的信息,这句话可以控制台输出代码报错的日志。 IOException: CreateProcess error=2, 系统找不指定的文件。 具体报错日志如下所示 ...
  • <3> mount /dev/lvinformix /opt/informix //将设备mount到文件系统上 <4> chfs -A yes /dev/lvinformix //-A yes|no 修改所建文件系统的自动安装属性(Auto-Mount) ***********************************************...
  • 尤其是,当这本书在我预想的时间内没有完成的时候,当我遇到困难迟迟不解决的时候,你总在一旁给我鼓励,在你那里,我从来都感觉一种温暖,我深知,如果没有你的支持,我无法坚持下来将书写完。谢谢你,这本书...
  • 尤其是,当这本书在我预想的时间内没有完成的时候,当我遇到困难迟迟不解决的时候,你总在一旁给我鼓励,在你那里,我从来都感觉一种温暖,我深知,如果没有你的支持,我无法坚持下来将书写完。谢谢你,这本书...
  • 说明:将sql*plus屏幕中的内容输出到指定的文件 用法:开始印刷->spool 文件名 结束印刷->spool off 列子: 文件内容 9. 显示宽度 (linesize) 说明:设置显示行的宽度,默认是80个字符 用法:set linesize 120 ...
  • 配置成 /*,可以请求 controller中,但是跳转jsp时会被拦截,不渲染jsp视图,不使用,一般用于filter 3、配置SpringMVC核心配置文件 springmvc-servlet.xml 所以springmvc-servlet.xml <?xml version=...
  • C#编程经验技巧宝典

    热门讨论 2008-06-01 08:59:33
    111 <br>0184 如何在ASP.NET中获取文件的扩展名 111 <br>0185 如何在ASP.NET中用URL在页面之间传值 112 <br>0186 如何使用IsPostBack实现ASP.NET页面加载 112 <br>0187 如何利用输出缓存技术缓存...

空空如也

空空如也

1 2
收藏数 32
精华内容 12
关键字:

日志能输出到控制台但是无法输出到文件