?
? ? ? ? Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个 改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging。logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能。
?
logback.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <!-- ROOT 节点 --> <!-- 属性描述 scan:性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 定义日志文件 输入位置 --> <property name="log_dir" value="/logs" /> <!-- 日志最大的历史 60天 --> <property name="maxHistory" value="60"></property> <!-- 控制台输出日志 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern> </encoder> </appender> <!-- 出错日志 appender --> <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 在多数的Log工具中,级别是可以传递,例如如果指定了日志输出级别为DEBUG, 那么INFO、ERROR级别的log也会出现在日志文件。这种默认给程序的调试带来了很多的麻烦 通过配置Filter 来严格控制日志输入级别 <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"> <!-- 按天回滚 daily --> <fileNamePattern>${log_dir}/error-log-%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 日志最大的历史 60天 --> <maxHistory>${maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern> </encoder> </appender> <!-- INFO 日志 appender --> <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <fileNamePattern>${log_dir}/info-log-%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 日志最大的历史 60天 --> <maxHistory>${maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern> </encoder> </appender> <!-- 访问日志 appender --> <appender name="ACCESS" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <fileNamePattern>${log_dir}/access-log-%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 日志最大的历史 60天 --> <maxHistory>${maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern> </encoder> </appender> <!-- 系统用户操作日志 appender --> <appender name="SYS-USER" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <fileNamePattern>${log_dir}/sys_user-log-%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 日志最大的历史 60天 --> <maxHistory>${maxHistory}</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern> </encoder> </appender> <!-- 打印SQL输出 --> <logger name="com.ibatis" level="DEBUG" /> <logger name="com.ibatis.common.jdbc.SimpleDataSource" level="DEBUG" /> <logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG" /> <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="DEBUG" /> <logger name="java.sql.Connection" level="DEBUG" /> <logger name="java.sql.Statement" level="DEBUG" /> <logger name="java.sql.PreparedStatement" level="DEBUG" /> <root level="debug"> <appender-ref ref="STDOUT"/> </root> <!--error错误日志--> <logger name="error" level="error"> <appender-ref ref="ERROR"/> </logger> <!--info日志--> <logger name="info" level="info"> <appender-ref ref="INFO"/> </logger> <!--访问日志--> <logger name="access" level="info"> <appender-ref ref="ACCESS"/> </logger> <!--系统用户操作日志--> <logger name="sys-user" level="info"> <appender-ref ref="SYS-USER"/> </logger> </configuration>
?
?
TestLogbackServlet测试
package servlet.test1; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import log.base.LogUtils; public class TestLogbackServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doGet"); LogUtils.logAccess(request); try { LogUtils.logInfo("TEST Servlet request INFO mages"); int ii = 1 / 0; } catch (Exception e) { LogUtils.logError("系统出现异常>>>", e); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost"); } }
?
LogUtils.java
package log.base; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Enumeration; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class LogUtils { /** * 错误输入日志 */ public static final Logger ERROR_LOG = LoggerFactory.getLogger("error"); /** * info输出日志 */ public static final Logger INFO_LOG = LoggerFactory.getLogger("info"); /** * 记录所有请求日志操作 */ public static final Logger ACCESS_LOG = LoggerFactory.getLogger("access"); /** * 记录当前请求日志信息 * 格式:[username][jsessionid][ip][accept][UserAgent][url][params][Referer] * @param request 当前请求request */ public static void logAccess(HttpServletRequest request) { //获取当前用户名 String username = getSysLoginUserName(); String jsessionId = request.getRequestedSessionId(); String ip = IpUtils.getIpAddr(request); String accept = request.getHeader("accept"); String userAgent = request.getHeader("User-Agent"); String url = request.getRequestURI(); String params = getParams(request); String headers = getHeaders(request); StringBuilder s = new StringBuilder(); s.append(getBlock(username)); s.append(getBlock(jsessionId)); s.append(getBlock(ip)); s.append(getBlock(accept)); s.append(getBlock(userAgent)); s.append(getBlock(url)); s.append(getBlock(params)); s.append(getBlock(headers)); s.append(getBlock(request.getHeader("Referer"))); getAccessLog().info(s.toString()); } /** * 记录一直 info信息 * @param message */ public static void logInfo(String message) { String username = getSysLoginUserName(); StringBuilder s = new StringBuilder(); s.append(getBlock(username)); s.append(getBlock(message)); s.append(getBlock(message)); getInfoLog().info(s.toString()); } /** * 记录日志错误信息 * @param message * @param e */ public static void logError(String message, Throwable e) { String username = getSysLoginUserName(); StringBuilder s = new StringBuilder(); s.append(getBlock("exception")); s.append(getBlock(username)); s.append(getBlock(message)); getErrorLog().error(s.toString(), e); } /** * 记录页面错误 * 错误日志记录 [page/eception][username][statusCode][errorMessage][servletName][uri][exceptionName][ip][exception] * * @param request */ public static void logPageError(HttpServletRequest request) { String username = getSysLoginUserName(); Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); String message = (String) request.getAttribute("javax.servlet.error.message"); String uri = (String) request.getAttribute("javax.servlet.error.request_uri"); Throwable t = (Throwable) request.getAttribute("javax.servlet.error.exception"); if (statusCode == null) { statusCode = 0; } StringBuilder s = new StringBuilder(); s.append(getBlock(t == null ? "page" : "exception")); s.append(getBlock(username)); s.append(getBlock(statusCode)); s.append(getBlock(message)); s.append(getBlock(IpUtils.getIpAddr(request))); s.append(getBlock(uri)); s.append(getBlock(request.getHeader("Referer"))); StringWriter sw = new StringWriter(); while (t != null) { t.printStackTrace(new PrintWriter(sw)); t = t.getCause(); } s.append(getBlock(sw.toString())); getErrorLog().error(s.toString()); } private static String getParams(HttpServletRequest request) { Map<String, String[]> params = request.getParameterMap(); return JSON.toJSONString(params); } private static String getHeaders(HttpServletRequest request) { Map<String, List<String>> headers = Maps.newHashMap(); Enumeration<String> namesEnumeration = request.getHeaderNames(); while(namesEnumeration.hasMoreElements()) { String name = namesEnumeration.nextElement(); Enumeration<String> valueEnumeration = request.getHeaders(name); List<String> values = Lists.newArrayList(); while(valueEnumeration.hasMoreElements()) { values.add(valueEnumeration.nextElement()); } headers.put(name, values); } return JSON.toJSONString(headers); } private static String getBlock(Object msg) { if (msg == null) { msg = ""; } return "[" + msg.toString() + "]"; } private static String getSysLoginUserName() { return "sys_login_user"; } public static Logger getErrorLog() { return ERROR_LOG; } public static Logger getInfoLog() { return INFO_LOG; } public static Logger getAccessLog() { return ACCESS_LOG; } }
?
需要以下jar