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 中输出

原文地址:https://www.cnblogs.com/wansw/p/10255746.html

时间: 2024-10-12 21:20:48

Tomcat中日志组件的相关文章

tomcat架构各个组件功能

tomcat组件与功能说明 Server:顶层组件,代表一个servlet容器的实体,server组件会在一个指定端口接收命令,比如shutdown 命令会停止服务. Service:service组件包括一到多个connector组件,这些connector组件将收到的请求发往同一个engine组件 Executor:提供一个线程池,可以给tomcat中的组件使用.比如connector组件可以配置使用executor Connector:与客户端直接交互的通讯组件.接收请求,返回响应给客户端

java中的日志组件-log4j

1.为什么使用日志组件 Log4J是Apache的一个开放源代码项目,它是一个日志操作包,通过使用Log4J,可以指定日志信息输出的目的地,如控制台.文件.CUI组件.NT的事件记录器:还可以控制每一条日志输出格式.此外,通过定义日志信息的级别,能够非常细致地控制日志的输出,最令人感兴趣的是,这些功能可以通过一个配置文件来灵活进行配置,而不需要修改应程序代码. 在应用程序中输出日志有3个目的: 监视代码中变量的变化情况,把数据周期性记录到文件中供其他应用进行统计分析工作: 跟踪代码运行时轨迹,作

.NetCore中的日志(1)日志组件解析

.NetCore中的日志(1)日志组件解析 0x00 问题的产生 日志记录功能在开发中很常用,可以记录程序运行的细节,也可以记录用户的行为.在之前开发时我一般都是用自己写的小工具来记录日志,输出目标包含控制台.文本文件.数据库,一般都是创建全局的Logger,在需要记录日志的地方调用相应的Logger输出至相应目标.遇到输出目标多了有时候也感觉挺麻烦的,不过也还能接受.开始学习.NetCore后接触到了日志记录框架(Logging组件),虽然完全可以用之前的方式记录日志,不过应该使用更通用的方式

[.Net Core] 在 Mvc 中简单使用日志组件

在 Mvc 中简单使用日志组件 基于 .Net Core 2.0,本文只是蜻蜓点水,并非深入浅出. 目录 使用内置的日志组件 简单过渡到第三方组件 - NLog 使用内置的日志 下面使用控制器 HomeController.cs 进行演示. 需要 using Microsoft.Extensions.Logging; 方案一: public class HomeController : Controller { private readonly ILogger _logger ; public

玩转ASP.NET Core中的日志组件

玩转ASP.NET Core中的日志组件简介日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 ConsoleDebugEventSourceEventLogTraceSourceAzure App Service除了内置的日志提供器,ASP.NET Core还支持了多种第三方日志工具,例如 elmah.ioGelfJSNLogKissLog.netLoggrNLogSe

Tomcat 中的 JDBC Pool

什么是连接池 什么是 Connection Pool -- 连接池呢? 我就不解释了.不太清楚的看这篇文章 [生产级别Nodejs开发实践-使用连接池](这篇文章的前半部分讲述了什么是连接池) Tomcat中的jdbc连接池 它的英文文档在:[The Tomcat JDBC Connection Pool] Tomcat 不仅是非常受欢迎的 Servlet 容器,也是同时为我们提供了很多非常实用组件. jdbc pool 就是其中一个非常实用且高效的 jdbc 连接池的实现. Tomcat 官方

设计一个中间件的访问日志组件

对任何一个系统,一个强大的日志记录功能是相当重要且必要的,根据日志的记录可以及时掌握系统运行时的健康状态及故障定位.然而作为web容器存在另外一种日志--访问日志.访问日志一般会记录客户端的访问相关信息,包括客户端ip.请求时间.请求协议.请求方法.请求字节数.响应码.会话id.处理时间等等.通过访问日志可以统计访问用户的数量.访问时间分布等规律及个人爱好等等,而这些数据可以帮助公司在运营策略上做出抉择. 如果让你来设计一个访问日志组件你会如何来设计?你应该很快就会想到访问日志的核心功能就是将信

在Tomcat中配置连接池和数据源

1.DataSource接口介绍 (1)DataSource 概述 JDBC1.0原来是用DriverManager类来产生一个对数据源的连接.JDBC2.0用一种替代的方法,使用DataSource的实现,代码变的更小巧精致,也更容易控制. 一个DataSource对象代表了一个真正的数据源.根据DataSource的实现方法,数据源既可以是从关系数据库,也电子表格,还可以是一个表格形式的文件.当一个DataSource对象注册到名字服务中(JNDI),应用程序就可以通过名字服务获得DataS

日志组件 logback

一.简介 Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- classic和logback-access.logback-core是其它两个模块的基础模块.logback-classic是log4j的一个 改良版本.此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging.logback-access访问模块与Servlet容器集成提