笔者是一个爱折腾的人,本着对软件开发的热爱,都要尝试一番:
- 导入pom依赖文件,笔者这里是用的Spring boot版本控制这里就不写版本号了;
<!--SpringBoot基本场景启动-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
- 写入配置文件:
log4j.rootLogger=DEBUG,stdout,HTML
#控制台输出日志
log4j.additivity.org.apache=true
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold=INFO
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-5p %c{1}:%L - %m%n
#打印html的log文件
log4j.appender.HTML = org.apache.log4j.DailyRollingFileAppender
log4j.appender.HTML.File=${user.dir}/fileService/log4j/log.html
log4j.appender.HTML.DatePattern='.'yyyy-MM-dd-a
log4j.appender.HTML.encoding=UTF-8
#这里注意: 写的是html的配置class全路径
log4j.appender.HTML.layout =com.rubik.merchant.config.HTMLLogFormatLayOut
log4j.appender.HTML.Threshold=INFO
- 配置html的格式类,这个全类名要写入上方的配置文件中的
import org.apache.log4j.HTMLLayout;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.helpers.Transform;
import org.apache.log4j.spi.LoggingEvent;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
/**
* @Auther: MR.rp
* @Date: 2021/11/19 11:04
* @Description:
*/
@Component
public class HTMLLogFormatLayOut extends HTMLLayout {
public HTMLLogFormatLayOut() {
}
protected final int BUF_SIZE = 256;
protected final int MAX_CAPACITY = 1024;
static String TRACE_PREFIX = "<br> ";
private StringBuffer sbuf = new StringBuffer(BUF_SIZE);
public static final String TITLE_OPTION = "Title";
boolean locationInfo = true;
public String format(LoggingEvent event) {
if (sbuf.capacity() > MAX_CAPACITY) {
sbuf = new StringBuffer(BUF_SIZE);
} else {
sbuf.setLength(0);
}
sbuf.append(Layout.LINE_SEP + "<tr>" + Layout.LINE_SEP);
/* 日志生成时间 */
sbuf.append("<td>");
sbuf.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new java.util.Date()));
sbuf.append("</td>" + Layout.LINE_SEP);
/* 日志级别 */
sbuf.append("<td title='日志级别'>");
if (event.getLevel().equals(Level.FATAL)) {
sbuf.append("<span style=\"color:red;font-weight: 700 ;\">");
sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
sbuf.append("</span>");
} else if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
sbuf.append("<span style=\"color:orange;font-weight: 600 ;\">");
sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
sbuf.append("</span>");
} else {
sbuf.append("<span style=\"color:green;\">");
sbuf.append(Transform.escapeTags(String.valueOf(event.getLevel())));
sbuf.append("</span>");
}
sbuf.append("</td>" + Layout.LINE_SEP);
/* 日志内容 */
String content = Transform.escapeTags(event.getRenderedMessage());
if (content.contains("|")) {
String[] temp = content.split("\\|");
sbuf.append("<td title='类型'>");
sbuf.append(temp[0]);
sbuf.append("</td>" + Layout.LINE_SEP);
} else {
sbuf.append("<td title='日志内容'>");
sbuf.append(content);
sbuf.append("</td>" + Layout.LINE_SEP);
}
sbuf.append("</tr>" + Layout.LINE_SEP);
if (event.getNDC() != null) {
sbuf.append("<tr><td bgcolor=\"#EEEEEE\" style=\"font-size : xx-small;\" colspan=\"6\" title=\"Nested Diagnostic Context\">");
sbuf.append("NDC: " + Transform.escapeTags(event.getNDC()));
sbuf.append("</td></tr>" + Layout.LINE_SEP);
}
String[] s = event.getThrowableStrRep();
if (s != null) {
sbuf.append("<tr><td bgcolor=\"#993300\" style=\"color:White; font-size : xx-small;\" colspan=\"6\">");
appendThrowableAsHTML(s, sbuf);
sbuf.append("</td></tr>" + Layout.LINE_SEP);
}
return sbuf.toString();
}
/**
* 生成HTML
*
* @param s
* @param sbuf
*/
private void appendThrowableAsHTML(String[] s, StringBuffer sbuf) {
if (s != null) {
int len = s.length;
if (len == 0)
return;
sbuf.append(Transform.escapeTags(s[0]));
sbuf.append(Layout.LINE_SEP);
for (int i = 1; i < len; i++) {
sbuf.append(TRACE_PREFIX);
sbuf.append(Transform.escapeTags(s[i]));
sbuf.append(Layout.LINE_SEP);
}
}
}
/**
* 返回的日志文件头
*/
public String getHeader() {
// 日志文件 的头
String title = "日志文件";
// 日志文件 表格的 头
StringBuffer sbuf = new StringBuffer();
sbuf.append("<!DOCTYPE HTML>" + Layout.LINE_SEP);
sbuf.append("<html>" + Layout.LINE_SEP);
sbuf.append("<head>" + Layout.LINE_SEP);
sbuf.append("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">");
sbuf.append("<title>" + title + "</title>" + Layout.LINE_SEP);
sbuf.append("<style type=\"text/css\">" + Layout.LINE_SEP);
sbuf.append("body, table {font-family: 'Courier New',arial,sans-serif; font-size: 13px;}"
+ Layout.LINE_SEP);
sbuf.append("th {background: #336699; color: #FFFFFF; text-align: center;}"
+ Layout.LINE_SEP);
sbuf.append("</style>" + Layout.LINE_SEP);
sbuf.append("</head>" + Layout.LINE_SEP);
sbuf.append("<body bgcolor=\"#FFFFFF\" topmargin=\"6\" leftmargin=\"6\">"
+ Layout.LINE_SEP);
sbuf.append("<table cellspacing=\"0\" cellpadding=\"1\" border=\"1\" bordercolor=\"#224466\" width=\"100%\">"
+ Layout.LINE_SEP);
sbuf.append("<tr>" + Layout.LINE_SEP);
sbuf.append("<th style='width:200px'>时间</th>" + Layout.LINE_SEP);
sbuf.append("<th style='width:150px'>日志级别</th>" + Layout.LINE_SEP);
sbuf.append("<th>类型</th>" + Layout.LINE_SEP);
sbuf.append("</tr>" + Layout.LINE_SEP);
sbuf.append("<br></br>" + Layout.LINE_SEP);
return sbuf.toString();
}
}
设置tomcat资源映射:
- 这个类要么不写,写了映射就要统一放行,包括static目录如下所示:
- 文件映射一般我会写在工作目录下,用 {user.dir}获取绝对路径,这里工作目录可以填写绝对路径;
- 这里的 file:为本地静态资源的映射路径,设置后此路径文件可以服务器访问,log的html文件要配置在这里
@Configuration
@Slf4j
public class WebMvcConfig implements WebMvcConfigurer {
// 实现静态资源的映射
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/") // 映射swagger2
.addResourceLocations("file:/这里是工作目录/") // 映射本地静态资源
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/");
}
}
如果你用了权限类的框架记得给配置的映射路径放行
笔者用的spring security放行如下:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui.html","/webjars/**","/v2/**","/swagger-resources/**","/doc.html","/file/**","/images/**","/log4j/**");
}
那么我们启动项目测试一下吧:
- 正常启动后:在工作目录中,生成了log日志
我们可以看到日志被正常访问了,你学废了吗;