如何看懂tomcat安装包logs文件夹下日志

29 篇文章 0 订阅

本篇文章较长 重要的是思路!!!之后你看Tomcat的任何一个类的源码都可以根据这种思路去定位和trace

对于一个正在找工作的渣渣来说 习惯性的翻源码慢慢也变成了乐趣 -鲁迅

对于Tomcat的源码我觉得看懂架构非常容易 对于细节因人而异 贴一张Tomcat的架构图(百度找的)左边就是我们conf目录下很重要的server.xml文件内容,右边则是官方给的架构图 可以看到一一对应

在这里插入图片描述

从上图我们可以看到server.xml文件中的标签与右边的架构图的组件具有相同的相对位置 而在源码中他们更是具有相同的关系

在这里插入图片描述

上面是我引入了EmbddedTomcat的依赖 即嵌入式Tomcat,之后编写的启动Tomcat的代码 我们可以看到其中的元素与我们在架构图上看到的相对关系完全一致 具体细节可以参照下列图(自己翻一遍最好)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过上面的示例我们可以得到这样一个结论 Tomcat的设计符合是jndi规范的 然后回归问题 如下图 一位同学在群里提出了这样一个问题

在这里插入图片描述

然后定位下问题所在 这个文件存在于Tomcat下载目录的logs文件夹下 而logs文件夹下为什么有这些日志文件那 我们可以观察server.xml文件 如下图 对的 就是你看到的那个位置 这里定义了accessLog的位置以及输出格式 可以发现pattern里面的正则与提出问题的输出语句格式相同

在这里插入图片描述

因此我们可以根据Tomcat设计的特性来从代码中找到AccessLogValve这个类 查看他的pattern的解释 但是从这个类中并没有pattern属性 于是我们可以去父类中找

在这里插入图片描述
在这里插入图片描述

定位到这条属性后 我们可以观察他的get set方法(思路) 然后根据server.xml中带的提示我们判断是进入common的代码块中 然后我们就可以去定位解析pattern的代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

 protected AccessLogElement createAccessLogElement(char pattern) {
        switch (pattern) {
        case 'a':
            return new RemoteAddrElement();
        case 'A':
            return new LocalAddrElement();
        case 'b':
            return new ByteSentElement(true);
        case 'B':
            return new ByteSentElement(false);
        case 'D':
            return new ElapsedTimeElement(true);
        case 'F':
            return new FirstByteTimeElement();
        case 'h':
            return new HostElement();
        case 'H':
            return new ProtocolElement();
        case 'l':
            return new LogicalUserNameElement();
        case 'm':
            return new MethodElement();
        case 'p':
            return new PortElement();
        case 'q':
            return new QueryElement();
        case 'r':
            return new RequestElement();
        case 's':
            return new HttpStatusCodeElement();
        case 'S':
            return new SessionIdElement();
        case 't':
            return new DateAndTimeElement();
        case 'T':
            return new ElapsedTimeElement(false);
        case 'u':
            return new UserElement();
        case 'U':
            return new RequestURIElement();
        case 'v':
            return new LocalServerNameElement();
        case 'I':
            return new ThreadNameElement();
        case 'X':
            return new ConnectionStatusElement();
        default:
            return new StringElement("???" + pattern + "???");
        }
    }

最后是翻译过程 他提出的最后的一个数字即%b的含义 对照上解析过程得知为sendByte即发送字节数 到此问题解决 其他可以自行参照验证

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值