1. 程式人生 > >SpringBoot整合+logback日誌配置

SpringBoot整合+logback日誌配置

本次演示的程式碼結構如下,基於maven整合SpringBoot、Spring、Mybaits的SSM框架。同時測試logback日誌框架的使用及配置。

1.建立maven工程,修改pom.xml檔案

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>yan.li</groupId>
	<artifactId>spring-boot-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	
	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
    	<!-- 使用UTF-8編碼  -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!-- 使用jdk1.8版本  -->
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <!--整合mybatis所需的jar -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--熱啟動:每自修改後, 程式自動啟動spring Application上下文。 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- 阿里json -->
         <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
</project>
2.建立com.liyan.model包,同時建立兩個PO類

(1)User.java類

package com.liyan.model;

import java.io.Serializable;

/**
 * 員工實體類
 * <p>Title: User</p>  
 * @author  Liyan  
 * @date    2018年1月11日 上午10:45:20
 */
public class User implements Serializable{

	private static final long serialVersionUID = 1L;
	
	/** 自增主鍵  */
	private Integer id;
	
	/** 員工工號  */
	private String userId;
	
	/** 員工姓名 */
	private String userName;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
	
}
2)ResponseResult.java類
package com.liyan.model;

/**
 * 返回值實體類
 * <p>Title: ResponseResult</p>  
 * @author  Liyan  
 * @date    2018年1月11日 下午5:23:41
 */
public class ResponseResult {
	
	private Integer code;
	
	private String msg;
	
	private Object data;

	public Integer getCode() {
		return code;
	}

	public void setCode(Integer code) {
		this.code = code;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public ResponseResult(Integer code, String msg, Object data) {
		super();
		this.code = code;
		this.msg = msg;
		this.data = data;
	}
	
}
3.在com.liyan.mapper包下建立UserMapper.java介面
package com.liyan.mapper;
import org.apache.ibatis.annotations.ResultType;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

import com.liyan.model.User;
//這裡可以使用@Mapper註解,但是每個mapper都加註解比較麻煩,所以統一配置@MapperScan在掃描路徑在application類中
//@Mapper //宣告是一個Mapper,與springbootApplication中的@MapperScan二選一寫上即可
@Repository
public interface UserMapper {
    @Select("SELECT id, user_id userId, user_name userName FROM user_tab WHERE user_id = #{userId}")
    @ResultType(User.class)
    User selectUser(String userId);
}
4.在com.liyan.service包下建立UserService.java介面
package com.liyan.service;

import com.liyan.model.User;

public interface UserService {

	/**
	 * 根據員工工號,查詢員工
	 * <p>Title: selectUser</p>  
	 * @author Liyan  
	 * @date   2018年1月11日 上午10:50:34  
	 * @param userId 員工工號
	 * @return  List<User>
	 */
    public User selectUser(String userId);
}
5.在com.liyan.service.impl包下建立UserServiceImpl.java類
package com.liyan.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.liyan.mapper.UserMapper;
import com.liyan.model.User;
import com.liyan.service.UserService;

@Service
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserMapper userMapper;

	@Override
	public User selectUser(String userId) {
		return userMapper.selectUser(userId);
	}
}
6.在com.liyan.exception包下建立三個自定義異常相關的類

(1)ExceptionEnum.java類

package com.liyan.exception;
/**
 * 異常列舉類
 * <p>Title: ExceptionEnum</p>  
 * @author  Liyan  
 * @date    2018年1月11日 下午3:54:48
 */
public enum ExceptionEnum {
	
	ERROR_NOFOUND("無法找到相應的資料");
	
	private String value;

	public String getValue() {
		return value;
	}

	ExceptionEnum(String value){
		this.value = value;
	}
	
	public String toString() {
		return value;
	}
}
(2)NoFoundExcepiton.java類
package com.liyan.exception;
/**
 * 自定義No Found異常
 * <p>Title: NoFoundExcepiton</p>  
 * @author  Liyan  
 * @date    2018年1月11日 下午3:36:13
 */
public class NoFoundExcepiton extends Exception {

	private static final long serialVersionUID = -5955607821816077172L;
	
	public NoFoundExcepiton(String errorInfo) {
		super(errorInfo);
	}
}
(3)GlobalExceptionHandler.java全域性異常類
package com.liyan.exception;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.liyan.model.ResponseResult;

@CrossOrigin
@RestControllerAdvice
public class GlobalExceptionHandler {

	private static Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
	
	@ExceptionHandler
	public ResponseResult processException(Exception ex, HttpServletRequest request, HttpServletResponse response){
		ex.printStackTrace();
		
		if(ex instanceof MissingServletRequestParameterException){
			return new ResponseResult(400, ex.getMessage(), null);
		}
		if(ex instanceof NoFoundExcepiton){
		        
	        LOGGER.error("======="+ex.getMessage()+"=======");
			return new ResponseResult(401, "無法找到相應資料!", null);
			
		}
		
		return new ResponseResult(500, ex.getMessage(), null);
		
	}
}
7.在com.liyan.controller包下建立

(1)建立UserController.java類

package com.liyan.controller;

import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.liyan.exception.ExceptionEnum;
import com.liyan.exception.NoFoundExcepiton;
import com.liyan.model.User;
import com.liyan.service.UserService;

@RestController
@EnableAutoConfiguration
@ComponentScan(basePackages={"com.liyan.model"})//新增的註解
public class UserController {
	
	@Autowired
	private UserService userService;
	
	/**
	 * 引入日誌,注意都是"org.slf4j"包下
	 */
	private final static Logger logger = LoggerFactory.getLogger(UserController.class);
	
	/**
	 * 根據員工工號,查詢員工
	 * <p>Title: selectUser</p>  
	 * @author Liyan  
	 * @date   2018年1月11日 上午11:37:46  
	 * @param userId 員工工號
	 * @param httpServletResponse
	 * @return  User
	 * @throws Exception 
	 */
	@RequestMapping(value = "selectUser/{userId}",method = RequestMethod.GET)
    public  User selectUser(@PathVariable String userId, HttpServletResponse httpServletResponse) throws Exception {
        User user = userService.selectUser(userId);
        logger.info("訪問selectUser/{userId}介面,引數userId = " + "userId");
		if (user == null) {
			logger.error("根據員工工號,查詢員工異常:e=" + ExceptionEnum.ERROR_NOFOUND.getValue());
			throw new NoFoundExcepiton(ExceptionEnum.ERROR_NOFOUND.getValue());
		}
		return user;
    }
	
}
(2)建立UserController.java啟動類
package com.liyan.controller;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * 啟動類
 * <p>Title: SpringbootApplication</p>  
 * @author  Liyan  
 * @date    2018年1月11日 上午11:36:48
 */
@SpringBootApplication(scanBasePackages = {"com.liyan"})  
@MapperScan("com.liyan.mapper")
@EnableTransactionManagement//開啟事務管理
public class SpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }
}
8.配置檔案相關

(1)application.properties

#============ 資料庫配置#======================================
spring.datasource.url=jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
#使用者名稱和密碼
spring.datasource.username=記得換成自己的
spring.datasource.password=記得換成自己的
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database=記得換成自己的

#============ tomcat配置#====================================
server.port=80

#============ mybatis配置 ====================================
#起別名。可省略寫mybatis的xml中的resultType的全路徑
mybatis.type-aliases-package=com.liyan.model
#Mybatis掃描(配置xml模式使用)
mybatis.mapper-locations=classpath*:mapper/*.xml

#=========== 日誌配置·簡易(spring boot已經整合logback日誌)=========
#controller層日誌 WARN級別輸出
#logging.level.com.liyan.controller=WARN
#mapper層 sql日誌 DEBUG級別輸出
#logging.level.com.liyan.mapper=DEBUG
#logging.file=logs/spring-boot-logging.log
#logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n
#logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
#列印執行時sql語句到控制檯
#spring.jpa.show-sql=true

#==================== 日誌配合·標準  ============================
logging.config=classpath:logback-boot.xml
(2)logback-boot.xml 日誌配置檔案(重點)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>    
    <!-- %m輸出的資訊,%p日誌級別,%t執行緒名,%d日期,%c類的全名,%i索引【從數字0開始遞增】,,, -->    
    <!-- appender是configuration的子節點,是負責寫日誌的元件。 -->
    <!-- ConsoleAppender:把日誌輸出到控制檯 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">    
        <encoder>    
            <pattern>%d %p (%file:%line\)- %m%n</pattern>  
            <!-- 控制檯也要使用UTF-8,不要使用GBK,否則會中文亂碼 -->
            <charset>UTF-8</charset>   
        </encoder>    
    </appender>    
    <!-- RollingFileAppender:滾動記錄檔案,先將日誌記錄到指定檔案,當符合某個條件時,將日誌記錄到其他檔案 -->
    <!-- 以下的大概意思是:1.先按日期存日誌,日期變了,將前一天的日誌檔名重新命名為XXX%日期%索引,新的日誌仍然是demo.log -->
    <!--             2.如果日期沒有發生變化,但是當前日誌的檔案大小超過1KB時,對當前日誌進行分割 重新命名-->
    <appender name="demolog" class="ch.qos.logback.core.rolling.RollingFileAppender">    
        <File>log/demo.log</File>    
        <!-- rollingPolicy:當發生滾動時,決定 RollingFileAppender 的行為,涉及檔案移動和重新命名。 -->
        <!-- TimeBasedRollingPolicy: 最常用的滾動策略,它根據時間來制定滾動策略,既負責滾動也負責出發滾動 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">    
            <!-- 活動檔案的名字會根據fileNamePattern的值,每隔一段時間改變一次 -->
            <!-- 檔名:log/demo.2017-12-05.0.log -->
            <fileNamePattern>log/demo.%d.%i.log</fileNamePattern> 
            <!-- 每產生一個日誌檔案,該日誌檔案的儲存期限為30天 --> 
            <maxHistory>30</maxHistory>   
            <timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">    
                <!-- maxFileSize:這是活動檔案的大小,預設值是10MB,測試時可改成1KB看效果 -->  
                <maxFileSize>1KB</maxFileSize>    
            </timeBasedFileNamingAndTriggeringPolicy>    
        </rollingPolicy>    
        <encoder>    
            <!-- pattern節點,用來設定日誌的輸入格式 -->
            <pattern>    
                %d %p (%file:%line\)- %m%n  
            </pattern>    
            <!-- 記錄日誌的編碼:此處設定字符集 - -->
            <charset>UTF-8</charset>
        </encoder>    
    </appender>    
    <!-- 控制檯輸出日誌級別 -->
    <root level="info">    
        <appender-ref ref="STDOUT" />    
    </root>    
    <!-- 指定專案中某個包,當有日誌操作行為時的日誌記錄級別 -->
    <!-- com.liyan為根包,也就是隻要是發生在這個根包下面的所有日誌操作行為的許可權都是DEBUG -->
    <!-- 級別依次為【從高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE  -->
    <logger name="com.liyan" level="DEBUG">    
        <appender-ref ref="demolog" />    
    </logger>    
</configuration>  
9.建立資料庫表結構,建表語句如下,資料自己隨便加吧
CREATE TABLE `user_tab` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `user_id` VARCHAR(10) NOT NULL,
  `user_name` VARCHAR(20) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_id` (`user_id`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8

10.啟動


11.訪問:http://localhost/selectUser/G353 (多重新整理幾次,看日誌效果)如下:

demo.log一旦大於剛剛配置的1kb,立即會被分割成按日期命名的各個小日誌