feat:新增对接S3协议

style:调整日志框架
docs:调整了文档
This commit is contained in:
hello-hao
2023-03-15 17:35:04 +08:00
parent cc05712906
commit 6f6166275a
13 changed files with 328 additions and 217 deletions
+2 -2
View File
@@ -188,8 +188,8 @@ Core版:`本地`,`阿里OSS`,`又拍USS`,`七牛KODO`,`腾讯COS`,`网易NOS`,
### 反馈交流
**如果你遇到BUG欢迎反馈**
欢迎加入Hellohao开发者交流群,群聊号码:**864800972**
- 前往论坛发帖反馈、求助:[Hellohao开发者交流论坛](http://bbs.hellohao.cn)
- 也可加QQ群探讨(目前已满):864800972
### 捐赠开发者
+10 -6
View File
@@ -90,11 +90,11 @@
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>commons-logging</groupId>-->
<!-- <artifactId>commons-logging</artifactId>-->
<!-- <version>1.2</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
@@ -120,7 +120,11 @@
<artifactId>pebble</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.334</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
@@ -196,7 +196,7 @@ public class AdminRootController {
} else if (key.getStorageType() == 7) {
ret = FtpServiceImpl.Initialize(key);
} else if (key.getStorageType() == 8) {
ret = UFileImageupload.Initialize(key);
ret = S3Imageupload.Initialize(key);
}
Long l = imgService.getsourcememory(keyId);
jsonObject.put("isok", ret);
@@ -32,7 +32,7 @@ public class FirstJob {
@Autowired
private USSImageupload ussImageupload;
@Autowired
private UFileImageupload uFileImageupload;
private S3Imageupload s3Imageupload;
@Autowired
private FtpServiceImpl ftpService;
@Autowired
@@ -77,7 +77,7 @@ public class FirstJob {
}else if(keys.getStorageType()==7){
firstJob.ftpService.delFTP(keys.getId(), images);
}else if(keys.getStorageType()==8){
firstJob.uFileImageupload.delUFile(keys.getId(), images);
firstJob.s3Imageupload.deleS3(keys.getId(), images);
}else{
System.err.println("未获取到对象存储参数,上传失败。");
}
@@ -30,7 +30,7 @@ public class InitializationStorage implements CommandLineRunner {
private KeysMapper keysMapper;
@Override
public void run(String... args) throws Exception {
public void run(String... args) {
SubjectFilter.WEBHOST = allowedOrigins;
String name = ManagementFactory.getRuntimeMXBean().getName();
String pid = name.split("@")[0];
@@ -41,21 +41,20 @@ public class InitializationStorage implements CommandLineRunner {
List<Keys> keylist = keysMapper.getKeys();
for (Keys key : keylist) {
if(key.getStorageType()!=0 && key.getStorageType()!=null){
int ret =0;
if(key.getStorageType()==1){
ret =NOSImageupload.Initialize(key);
NOSImageupload.Initialize(key);
}else if (key.getStorageType()==2){
ret =OSSImageupload.Initialize(key);
OSSImageupload.Initialize(key);
}else if(key.getStorageType()==3){
ret = USSImageupload.Initialize(key);
USSImageupload.Initialize(key);
}else if(key.getStorageType()==4){
ret = KODOImageupload.Initialize(key);
KODOImageupload.Initialize(key);
}else if(key.getStorageType()==6){
ret = COSImageupload.Initialize(key);
COSImageupload.Initialize(key);
}else if(key.getStorageType()==7){
ret = FtpServiceImpl.Initialize(key);
FtpServiceImpl.Initialize(key);
}else if(key.getStorageType()==8){
ret = UFileImageupload.Initialize(key);
S3Imageupload.Initialize(key);
}
}
}
@@ -16,7 +16,6 @@ public class KeysServiceImpl implements KeysService {
@Autowired
private KeysMapper keysMapper;
@Autowired
private NOSImageupload nOSImageupload;
@Autowired
@@ -30,7 +29,7 @@ public class KeysServiceImpl implements KeysService {
@Autowired
private FtpServiceImpl ftpService;
@Autowired
private UFileImageupload uFileImageupload;
private S3Imageupload s3Imageupload;
@Override
@@ -67,7 +66,7 @@ public class KeysServiceImpl implements KeysService {
}else if(key.getStorageType()==7){
ret = ftpService.Initialize(key);
}else if(key.getStorageType()==8){
ret = uFileImageupload.Initialize(key);
ret = s3Imageupload.Initialize(key);
}else{
Print.Normal("为获取到存储参数,或者使用存储源是本地的。");
}
@@ -0,0 +1,167 @@
package cn.hellohao.service.impl;
import cn.hellohao.pojo.Images;
import cn.hellohao.pojo.Keys;
import cn.hellohao.pojo.ReturnImage;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.PutObjectRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.List;
import java.util.Map;
/**
* @author Hellohao
* @version 1.0
* @date 2023/3/15 14:04
*/
@Service
public class S3Imageupload {
private static Logger logger = LoggerFactory.getLogger(S3Imageupload.class);
static AmazonS3 AS3;
static Keys KEY;
public ReturnImage ImageuploadS3(
Map<Map<String, String>, File> fileMap, String username, Integer keyID) {
ReturnImage returnImage = new ReturnImage();
try {
if (null == AS3 || null == AS3) {
logger.error("S3 = 存储源对象为空");
returnImage.setCode("500");
return returnImage;
}
} catch (Exception e) {
e.printStackTrace();
returnImage.setCode("500");
return returnImage;
}
File file = null;
try {
for (Map.Entry<Map<String, String>, File> entry : fileMap.entrySet()) {
String prefix = entry.getKey().get("prefix");
String ShortUIDName = entry.getKey().get("name");
file = entry.getValue();
AS3.putObject(
new PutObjectRequest(
KEY.getBucketname(),
username + "/" + ShortUIDName + "." + prefix,
file));
// S3Object object = s3.getObject( new GetObjectRequest( key.getBucketname(),
}
returnImage.setCode("200");
} catch (Exception e) {
e.printStackTrace();
returnImage.setCode("500");
}
return returnImage;
}
public static Integer Initialize(Keys k) {
int ret = -1;
if (StringUtils.isBlank(k.getAccessKey())
|| StringUtils.isBlank(k.getAccessSecret())
|| StringUtils.isBlank(k.getRootPath())
|| StringUtils.isBlank(k.getEndpoint())
|| StringUtils.isBlank(k.getBucketname())
|| StringUtils.isBlank(k.getRequestAddress())) {
return -1;
}
try {
String regionStr = k.getRegion() == null ? "" : k.getRegion();
ClientConfiguration config = new ClientConfiguration();
config.setMaxConnections(500);
config.setConnectionTimeout(30);
// cn-north-1 us-east-1
BasicAWSCredentials credentials =
new BasicAWSCredentials(k.getAccessKey(), k.getAccessSecret());
AmazonS3 s3 =
AmazonS3ClientBuilder.standard()
.withClientConfiguration(config)
.withPathStyleAccessEnabled(false)
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(
k.getEndpoint(), regionStr))
.build();
ObjectListing objectListing = s3.listObjects(k.getBucketname());
ret = 1;
AS3 = s3;
KEY = k;
} catch (Exception e) {
logger.warn("S3 Object " + k.getKeyname() + " Is null");
ret = -1;
}
if(ret==-1){
ret = Initialize_Tow(k);
if(ret>-1){
//OK
}
}
return ret;
}
public static Integer Initialize_Tow(Keys k) {
int ret = -1;
try {
ClientConfiguration config = new ClientConfiguration();
AwsClientBuilder.EndpointConfiguration endpointConfig =
new AwsClientBuilder.EndpointConfiguration(k.getEndpoint(), k.getRegion());//cn-north-1
AWSCredentials awsCredentials = new BasicAWSCredentials(k.getAccessKey(),k.getAccessSecret());
AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
AmazonS3 s3 = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig)
.withClientConfiguration(config)
.withCredentials(awsCredentialsProvider)
.disableChunkedEncoding()
.withPathStyleAccessEnabled(true)
.build();
List<Bucket> buckets = s3.listBuckets();
boolean b = false;
for (Bucket bucket : buckets) {
if(k.getBucketname().equals(bucket.getName())){
b = true;
}
}
if(b==false){
throw new NullPointerException();
}
ret=1;
AS3 = s3;
KEY = k;
} catch (Exception e) {
ret = -1;
}
return ret;
}
public boolean deleS3(Integer keyID, Images images) {
boolean b = true;
try {
DeleteObjectRequest deleteObjectRequest =
new DeleteObjectRequest(KEY.getBucketname(), images.getImgname());
AS3.deleteObject(deleteObjectRequest);
} catch (Exception e) {
e.printStackTrace();
b = false;
}
return b;
}
}
@@ -15,7 +15,7 @@ import java.util.List;
import java.util.Map;
@Service
public class UFileImageupload {
public class UFileImageupload1 {
static UpYun uFile;
static Keys key;
@@ -24,7 +24,7 @@ public class deleImages {
@Autowired private COSImageupload cosImageupload;
@Autowired private KODOImageupload kodoImageupload;
@Autowired private USSImageupload ussImageupload;
@Autowired private UFileImageupload uFileImageupload;
@Autowired private S3Imageupload s3Imageupload;
@Autowired private FtpServiceImpl ftpService;
@Autowired private ImgAndAlbumService imgAndAlbumService;
@Autowired private ImgTempService imgTempService;
@@ -60,7 +60,7 @@ public class deleImages {
} else if (key.getStorageType() == 7) {
isDele = ftpService.delFTP(key.getId(), image);
} else if (key.getStorageType() == 8) {
isDele = uFileImageupload.delUFile(key.getId(), image);
isDele = s3Imageupload.deleS3(key.getId(), image);
} else {
System.err.println("未获取到对象存储参数,删除失败。");
}
+10 -12
View File
@@ -47,6 +47,13 @@ public class FirstRun implements InitializingBean {
String uid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
RunSqlScript.RunInsert("update user set uid='"+uid+"' where id = 1");
Integer ret0 =
RunSqlScript.RunSelectCount(judgeTable + "'keys' and column_name = 'Region'");
if (ret0 == 0) {
RunSqlScript.RunInsert(sql0);
Print.Normal("Add keys.Region||RootPath");
}
Integer ret1 = RunSqlScript.RunSelectCount(sql1);
if(ret1==0){
Print.Normal("In execution...");
@@ -83,11 +90,7 @@ public class FirstRun implements InitializingBean {
RunSqlScript.RunInsert(sql8);
Print.Normal("Stage 6");
}
Integer ret5 = RunSqlScript.RunSelectCount(judgeTable+"'config' and column_name = 'theme'");
if(ret5==0){
RunSqlScript.RunInsert(sql9);
Print.Normal("Stage 7");
}
Integer ret6 = RunSqlScript.RunSelectCount(judgeTable+" 'user' and column_name = 'token'");
if(ret6==0){
RunSqlScript.RunInsert(sql12);
@@ -105,12 +108,6 @@ public class FirstRun implements InitializingBean {
RunSqlScript.RunInsert(instartConfdata);
Print.Normal("Add table.confdata");
}
// Integer ret6 = RunSqlScript.RunSelectCount(judgeTable+" 'imgdata' and column_name = 'idname'");
// if(ret6==0){
// RunSqlScript.RunInsert(sql11);
// Print.Normal("Add imgdata.idname");
// }
RunSqlScript.RunInsert("alter table tbed.`config` modify column `explain` text,modify column `links` text,modify column `notice` text,modify column `baidu` text");
// RunSqlScript.RunInsert(inddx_md5key);
RunSqlScript.RunInsert("UPDATE tbed.`keys` SET `Endpoint` = '0' WHERE `id` = 8");
RunSqlScript.RunInsert("ALTER TABLE tbed.`user` MODIFY id int auto_increment;");
@@ -123,6 +120,8 @@ public class FirstRun implements InitializingBean {
private String isTableName = "SELECT count(table_name) FROM information_schema.TABLES WHERE TABLE_SCHEMA='tbed' and table_name =";
private String judgeTable = "select count(*) from information_schema.columns where TABLE_SCHEMA='tbed' and table_name = ";
//创建blacklist 2019-11-29
private String sql0 =
"alter table `keys` add (Region varchar(255) DEFAULT null,RootPath varchar(255) DEFAULT '/');";
private String sql1 = "select count(*) from information_schema.columns where table_name = 'uploadconfig' and column_name = 'blacklist'";
private String sql2 = "alter table uploadconfig add blacklist varchar(500);";
//创建imgandalbum和album 添加imgdata表字段explain 2019-12-20
@@ -133,7 +132,6 @@ public class FirstRun implements InitializingBean {
private String sql7 = "alter table album add userid int(10)";
//添加imgdata表字段md5key
private String sql8 = "alter table imgdata add md5key varchar(5000)";
private String sql9 = "ALTER TABLE config ADD theme int(4) DEFAULT '1' COMMENT '主题' ";
// 图片标识名字段
private String sql11 = "alter table `imgdata` add idname varchar(255) DEFAULT '未命名' ;";
@@ -5,7 +5,6 @@ import cn.hellohao.pojo.ReturnImage;
import cn.hellohao.service.impl.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.Map;
@@ -31,7 +30,7 @@ public class GetSource {
@Autowired
FtpServiceImpl ftpService;
@Autowired
UFileImageupload uFileImageupload;
S3Imageupload s3Imageupload;
public ReturnImage storageSource(Integer type, Map<Map<String, String>, File> fileMap, String userpath,Integer keyID){
ReturnImage returnImage = null;
@@ -51,7 +50,7 @@ public class GetSource {
}else if(type==7){
returnImage = ftpService.FtpUploadFile(fileMap, userpath,keyID);
}else if(type==8){
returnImage = uFileImageupload.ImageuploadUFile(fileMap, userpath,keyID);
returnImage = s3Imageupload.ImageuploadS3(fileMap, userpath,keyID);
}
else{
new StorageSourceInitException("GetSource类捕捉异常:未找到存储源");
+1 -1
View File
@@ -25,7 +25,6 @@ spring.redis.password=
spring.thymeleaf.suffix=.html
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.mapper-locations=classpath:mapper/*.xml
logging.level.cn.hellohao.dao=debug
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
@@ -50,4 +49,5 @@ spring.datasource.druid.stat-view-servlet.login-username=hellohao@dealer
spring.datasource.druid.stat-view-servlet.login-password=52BNmXPJL0rQQ3CU
spring.datasource.druid.stat-view-servlet.allow=127.0.0.1
spring.datasource.druid.web-stat-filter.exclusions=false
log4j.logger.cn.hellohao.dao=DEBUG
log4j2.formatMsgNoLookups=True
+120 -175
View File
@@ -1,197 +1,142 @@
<?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">
<!-- 级别从高到低 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">
<!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
<contextName>logback</contextName>
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<!-- 动态日志级别 -->
<jmxConfigurator/>
<property name="log.path" value="/HellohaoData/tbedlog" />
<!-- 定义日志文件 输出位置 -->
<property name="log.log_dir" value="logs"/>
<property name="log.log_name" value="log"/>
<!-- 日志最大的历史 30天 -->
<property name="log.maxHistory" value="30"/>
<property name="log.level" value="debug"/>
<property name="log.maxSize" value="5MB" />
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--输出到控制台-->
<!-- ConsoleAppender 控制台输出日志 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
<!-- &lt;!&ndash; 设置过滤级别 &ndash;&gt;-->
<!-- <level>INFO</level>-->
<!-- &lt;!&ndash; 用于配置符合过滤条件的操作 &ndash;&gt;-->
<!-- <onMatch>ACCEPT</onMatch>-->
<!-- &lt;!&ndash; 用于配置不符合过滤条件的操作 &ndash;&gt;-->
<!-- <onMismatch>DENY</onMismatch>-->
<!-- </filter>-->
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
<pattern>
<!-- 设置日志输出格式 -->
<!-- 日期 [线程] [class类]-[日志级别] log内容 -->
%blue(%d{yyyy-MM-dd HH:mm:ss,SSS}) [%cyan(%t)] [%yellow(%c)]-[%highlight(%p)] %m%n
</pattern>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_debug.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档 -->
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<!-- ERROR级别日志 -->
<!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<!-- 过滤器,只记录WARN级别的日志 -->
<!-- 果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
<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.SizeAndTimeBasedRollingPolicy">
<!--日志输出位置 可相对、和绝对路径 -->
<fileNamePattern>
${log.log_dir}/error/%d{yyyy-MM-dd}/error_${log.log_name}-%i.log
</fileNamePattern>
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件,假设设置每个月滚动,且<maxHistory>是6
则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除 -->
<maxHistory>${log.maxHistory}</maxHistory>
<!--日志文件最大的大小-->
<MaxFileSize>${log.maxSize}</MaxFileSize>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>
<!-- 设置日志输出格式 -->
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</encoder>
</appender>
<!-- INFO级别日志 appender -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/log_info.log</file>
<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.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.log_dir}/info/%d{yyyy-MM-dd}/info_${log.log_name}-%i.log</fileNamePattern>
<maxHistory>${log.maxHistory}</maxHistory>
<MaxFileSize>${log.maxSize}</MaxFileSize>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger - %msg%n</pattern>
</encoder>
</appender>
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
以及指定<appender>。<logger>仅有一个name属性,
一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
如果未设置此属性,那么当前logger将会继承上级的级别。
addtivity:是否向上级logger传递打印信息。默认是true。
-->
<!--<logger name="org.springframework.web" level="info"/>-->
<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->
<!--
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
-->
<!-- DEBUG级别日志 appender -->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/log_debug.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.log_dir}/debug/%d{yyyy-MM-dd}/debug_${log.log_name}-%i.log</fileNamePattern>
<maxHistory>${log.maxHistory}</maxHistory>
<MaxFileSize>${log.maxSize}</MaxFileSize>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger - %msg%n</pattern>
</encoder>
</appender>
<!--
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
不能设置为INHERITED或者同义词NULL。默认是DEBUG
可以包含零个或多个元素,标识这个appender将会添加到这个logger。
-->
<!--设置一个向上传递的appender,所有级别的日志都会输出-->
<appender name="app" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.log_dir}/app/%d{yyyy-MM-dd}/app_${log.log_name}-%i.log</fileNamePattern>
<maxHistory>${log.maxHistory}</maxHistory>
<MaxFileSize>${log.maxSize}</MaxFileSize>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger - %msg%n</pattern>
</encoder>
</appender>
<!--开发环境:打印控制台-->
<springProfile name="dev">
<logger name="cn.hellohao.dao" level="debug"/>
</springProfile>
<root level="info">
<!--name包下的类的日志输出-->
<logger name="cn.hellohao" additivity="true" level="DEBUG" >
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
<!-- <appender-ref ref="INFO" />-->
</logger>
<!-- root级别 DEBUG -->
<root level="DEBUG">
<!-- 控制台输出 -->
<!-- <appender-ref ref="CONSOLE"/>-->
<!-- 不管什么包下的日志都输出文件 -->
<appender-ref ref="DEBUG"/>
<appender-ref ref="ERROR" />
</root>
<!--生产环境:输出到文件-->
<!--<springProfile name="pro">-->
<!--<root level="info">-->
<!--<appender-ref ref="CONSOLE" />-->
<!--<appender-ref ref="DEBUG_FILE" />-->
<!--<appender-ref ref="INFO_FILE" />-->
<!--<appender-ref ref="ERROR_FILE" />-->
<!--<appender-ref ref="WARN_FILE" />-->
<!--</root>-->
<!--</springProfile>-->
</configuration>
</configuration>