Tomcat中日志组件

Posted wansw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat中日志组件相关的知识,希望对你有一定的参考价值。

Tomcat日志组件

AccessLog接口

public interface AccessLog {
    public void log(Request request, Response response, long time);
}

AccessLogAdapter

public class AccessLogAdapter implements AccessLog {
    private AccessLog[] logs;
    // 构造函数
    public AccessLogAdapter(AccessLog log) {
        Objects.requireNonNull(log);
        logs = new AccessLog[] { log };
    }
	// 添加新的 访问日志 AccessLog
    public void add(AccessLog log) {
        Objects.requireNonNull(log);
        AccessLog newArray[] = Arrays.copyOf(logs, logs.length + 1);
        newArray[newArray.length - 1] = log;
        logs = newArray;
    }
	// AccessLog 接口中的 log 方法,循环操作
    @Override
    public void log(Request request, Response response, long time) {
        for (AccessLog log: logs) {
            log.log(request, response, time);
        }
    }
}

Tomcat中日志

​ 默认在 server.xml 中配置了 AccessLogValve 。

<!-- server.xml Host 节点 -->
<Valve className="org.apache.catalina.valves.AccessLogValve" 	                              directory="logs"
       suffix=".txt"
       prefix="localhost_access_log"
       pattern="%h %l %u %t &quot;%r&quot; %s %b" />
<!-- 
className=org.apache.catalina.valves.AccessLogValve
directory=logs               存储位置
prefix						 文件前缀
suffix						 文件后缀
pattern						 输出格式
-->
@Override
public void log(CharArrayWriter message) {
    System.out.println("log");
    rotate();

    /* In case something external rotated the file instead */
    if (checkExists) {
        synchronized (this) {
            if (currentLogFile != null && !currentLogFile.exists()) {
                try {
                    close(false);
                } catch (Throwable e) {
                    ExceptionUtils.handleThrowable(e);
                    log.info(sm.getString("accessLogValve.closeFail"), e);
                }

                /* Make sure date is correct */
                dateStamp = fileDateFormatter.format(
                    new Date(System.currentTimeMillis()));

                open();
            }
        }
    }

    // Log this message
    try {
        synchronized(this) {
            if (writer != null) {
                message.writeTo(writer);
                writer.println("");
                if (!buffered) {
                    writer.flush();
                }
            }
        }
    } catch (IOException ioe) {
        log.warn(sm.getString(
            "accessLogValve.writeFail", message.toString()), ioe);
    }
}

调用过程

// ContainerBase
@Override
public void logAccess(Request request, Response response, long time,
                      boolean useDefault) {
    boolean logged = false;
	// 获取 注册的 日志组件
    AccessLog accessLog = getAccessLog();
    if (accessLog != null) {
        // 调用 适配器 log 方法
        accessLog.log(request, response, time);
        logged = true;
    }
    if (getParent() != null) {
        getParent().logAccess(request, response, time, 
                              (useDefault && !logged));
    }
}

@Override
public AccessLog getAccessLog() {
    // 默认 false
    if (accessLogScanComplete) {
        return accessLog;
    }
	// AccessLog 适配器
    AccessLogAdapter adapter = null;
    // 获取所有注册的 阀门 Valve
    Valve valves[] = getPipeline().getValves();
    for (Valve valve : valves) {
        // 判断 Valve 的类型
        if (valve instanceof AccessLog) {
            if (adapter == null) {
                adapter = new AccessLogAdapter((AccessLog) valve);
            } else {
                adapter.add((AccessLog) valve);
            }
        }
    }
    if (adapter != null) {
        accessLog = adapter;
    }
    accessLogScanComplete = true;
    return accessLog;
}

自定义 AccessLog

在 server.xml 中 ,配置 Valve ,在解析 server.xml 会自动注册。

public class WswAccessLogValve extends AbstractAccessLogValve {

    @Override
    protected void log(CharArrayWriter message) {
        System.out.println("access log");
    }
}
// message
//   ||
//   VV
// 0:0:0:0:0:0:0:1 - - [08/Dec/2018:23:47:07 +0800] "GET /tomcat/ HTTP/1.1" 200 139
<!-- server.xml Host 节点 -->
<Valve className="org.apache.catalina.valves.AccessLogValve" 	                  directory="logs" suffix=".txt"
       prefix="localhost_access_log"
       pattern="%h %l %u %t &quot;%r&quot; %s %b" />

<Valve className="org.apache.catalina.valves.WswAccessLogValve"/>
log			 			// AccessLogValve 中输出
access log		// WswAccessLogValve 中输出

以上是关于Tomcat中日志组件的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat中Logger组件

31 | Logger组件:Tomcat的日志框架及实战

在Tomcat的安装目录下conf目录下的server.xml文件中增加一个xml代码片段,该代码片段中每个属性的含义与用途

常用python日期日志获取内容循环的代码片段

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

argparse 代码片段只打印部分日志