content/references/java-chassis/zh_CN/build-provider/access-log-configuration.html (771 lines of code) (raw):

<!DOCTYPE html> <html class="writer-html5" lang="en" > <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="shortcut icon" href="../img/favicon.ico" /> <title>Access Log - ServiceComb Java Chassis 开发指南</title> <link rel="stylesheet" href="../css/theme.css" /> <link rel="stylesheet" href="../css/theme_extra.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/github.min.css" /> <script> // Current page data var mkdocs_page_name = "Access Log"; var mkdocs_page_input_path = "build-provider/access-log-configuration.md"; var mkdocs_page_url = null; </script> <script src="../js/jquery-3.6.0.min.js" defer></script> <!--[if lt IE 9]> <script src="../js/html5shiv.min.js"></script> <![endif]--> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script> <script>hljs.initHighlightingOnLoad();</script> </head> <body class="wy-body-for-nav" role="document"> <div class="wy-grid-for-nav"> <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav"> <div class="wy-side-scroll"> <div class="wy-side-nav-search"> <a href="../index.html" class="icon icon-home"> ServiceComb Java Chassis 开发指南 </a> </div> <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> <ul> <li class="toctree-l1"><a class="reference internal" href="../toc.html">目录</a> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../index.html">概述</a> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../start/catalog.html">快速入门</a> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../start/design.html">设计选型参考</a> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="definition/service-definition.html">微服务定义</a> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="catalog.html">开发服务提供者</a> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../build-consumer/catalog.html">开发服务消费者</a> </li> </ul> <ul> <li class="toctree-l1"><a class="reference internal" href="../general-development/catalog.html">通用功能开发</a> </li> </ul> <p class="caption"><span class="caption-text">多样化的通信协议功能参考</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../transports/introduction.html">多协议介绍</a> </li> <li class="toctree-l1"><a class="reference internal" href="../transports/rest-over-servlet.html">REST over Servlet</a> </li> <li class="toctree-l1"><a class="reference internal" href="../transports/rest-over-vertx.html">REST over Vertx</a> </li> <li class="toctree-l1"><a class="reference internal" href="../transports/http2.html">REST over HTTP2</a> </li> <li class="toctree-l1"><a class="reference internal" href="../transports/highway-rpc.html">Highway</a> </li> </ul> <p class="caption"><span class="caption-text">多样化的服务注册与发现功能参考</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../registry/introduction.html">注册发现说明</a> </li> <li class="toctree-l1"><a class="reference internal" href="../registry/service-center.html">使用服务中心</a> </li> <li class="toctree-l1"><a class="reference internal" href="../registry/local-registry.html">本地注册发现</a> </li> <li class="toctree-l1"><a class="reference internal" href="../registry/distributed.html">去中心化注册发现</a> </li> </ul> <p class="caption"><span class="caption-text">管理服务配置</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../config/general-config.html">通用配置说明</a> </li> <li class="toctree-l1"><a class="reference internal" href="../config/read-config.html">在程序中读取配置信息</a> </li> </ul> <p class="caption"><span class="caption-text">服务治理功能参考</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../references-handlers/intruduction.html">处理链介绍</a> </li> <li class="toctree-l1"><a class="reference internal" href="../references-handlers/loadbalance.html">负载均衡</a> </li> <li class="toctree-l1"><a class="reference internal" href="../references-handlers/ratelimit.html">限流</a> </li> <li class="toctree-l1"><a class="reference internal" href="../references-handlers/router.html">灰度发布</a> </li> <li class="toctree-l1"><a class="reference internal" href="../references-handlers/fault-injection.html">故障注入</a> </li> <li class="toctree-l1"><a class="reference internal" href="../references-handlers/governance.html">流量特征治理</a> </li> <li class="toctree-l1"><a class="reference internal" href="../references-handlers/fail-retry.html">快速失败和重试</a> </li> </ul> <p class="caption"><span class="caption-text">网关功能参考</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../edge/open-service.html">介绍</a> </li> <li class="toctree-l1"><a class="reference internal" href="../edge/by-servicecomb-sdk.html">使用 Edge Service 做网关</a> </li> <li class="toctree-l1"><a class="reference internal" href="../edge/zuul.html">使用 `zuul` 和 `spring cloud gateway` 做网关</a> </li> <li class="toctree-l1"><a class="reference internal" href="../edge/nginx.html">nginx 网关简单介绍</a> </li> </ul> <p class="caption"><span class="caption-text">安全特性参考</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../references-handlers/publickey.html">公钥认证</a> </li> <li class="toctree-l1"><a class="reference internal" href="../security/tls.html">使用TLS通信</a> </li> <li class="toctree-l1"><a class="reference internal" href="../security/shi-yong-rsa-ren-zheng.html">使用RSA认证</a> </li> </ul> <p class="caption"><span class="caption-text">服务打包和运行</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../packaging/standalone.html">以standalone模式打包</a> </li> <li class="toctree-l1"><a class="reference internal" href="../packaging/web-container.html">以WEB容器模式打包</a> </li> </ul> <p class="caption"><span class="caption-text">专题文章</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../using-java-chassis-in-spring-boot/using-java-chassis-in-spring-boot.html">在Spring Boot中使用java chassis</a> </li> <li class="toctree-l1"><a class="reference internal" href="../featured-topics/features.html">新功能介绍系列文章</a> </li> <li class="toctree-l1"><a class="reference internal" href="../featured-topics/compatibility.html">兼容问题和兼容性策略</a> </li> <li class="toctree-l1"><a class="reference internal" href="../featured-topics/upgrading.html">升级指导系列文章</a> </li> <li class="toctree-l1"><a class="reference internal" href="../featured-topics/performance.html">性能问题分析和调优</a> </li> </ul> <p class="caption"><span class="caption-text">常用配置项参考</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../config-reference/rest-transport-client.html">REST Transport Client 配置项</a> </li> <li class="toctree-l1"><a class="reference internal" href="../config-reference/config-center-client.html">Config Center Client 配置项</a> </li> <li class="toctree-l1"><a class="reference internal" href="../config-reference/service-center-client.html">Service Center Client 配置项</a> </li> <li class="toctree-l1"><a class="reference internal" href="../config-reference/kie-client.html">ServiceComb Kie Client 配置项</a> </li> </ul> <p class="caption"><span class="caption-text">常见问题</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="../question-and-answer/faq.html">FAQ</a> </li> <li class="toctree-l1"><a class="reference internal" href="../question-and-answer/question_answer.html">Q & A</a> </li> <li class="toctree-l1"><a class="reference internal" href="../question-and-answer/interface-compatibility.html">微服务接口兼容常见问题</a> </li> </ul> </div> </div> </nav> <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"> <nav class="wy-nav-top" role="navigation" aria-label="Mobile navigation menu"> <i data-toggle="wy-nav-top" class="fa fa-bars"></i> <a href="../index.html">ServiceComb Java Chassis 开发指南</a> </nav> <div class="wy-nav-content"> <div class="rst-content"><div role="navigation" aria-label="breadcrumbs navigation"> <ul class="wy-breadcrumbs"> <li><a href="../index.html" class="icon icon-home" alt="Docs"></a> &raquo;</li> <li>Access Log</li> <li class="wy-breadcrumbs-aside"> </li> </ul> <hr/> </div> <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> <div class="section" itemprop="articleBody"> <h1 id="access-log">Access Log</h1> <h2 id="_1">概念阐述</h2> <p>ServiceComb 提供了基于 Vert.x 的 access log 和 request log 功能。当用户使用 REST over Vertx 通信方式时,可以通过简单的配置启用 access log 打印功能。当用户 client 端进行远程调用时,可以通过简单的配置启用 request log 打印功能</p> <h2 id="_2">场景描述</h2> <ol> <li> <p>用户在调试服务时可能需要开启 access log。在使用 REST over servlet 通信方式的情况下,可以使用 web容器 的 access log 功能;而在使用 REST over Vertx 通信方式的情况下,可以使用 ServiceComb 提供的一套 access log 功能。</p> </li> <li> <p>用户想要跟踪,记录客户端远程调用信息, 可以开启 request log。request log 同时支持记录 rest 和 highway 远程调用方式。</p> </li> </ol> <h2 id="_3">配置说明</h2> <h3 id="access-log-request-log">启用 Access Log &amp; Request Log</h3> <p>用户需要在 microservice.yaml 文件中增加配置以启用 access log 和 request log,配置示例如下:</p> <pre><code class="language-yaml">servicecomb: accesslog: ## server 端 启用access log enabled: true ## server 端 自定义 access log 日志格式 pattern: &quot;%h - - %t %r %s %B %D&quot; request: ## client 端开启 request log enabled: true ## client 端自定义 request log 日志格式 pattern: &quot;%h %SCB-transport - - %t %r %s %D&quot; </code></pre> <p><em><strong>Access log &amp; Request log 配置项说明</strong></em></p> <table> <thead> <tr> <th align="left">配置项</th> <th align="left">取值范围</th> <th align="left">默认值</th> <th align="left">说明</th> </tr> </thead> <tbody> <tr> <td align="left">servicecomb.accesslog.enabled</td> <td align="left">true/false</td> <td align="left"><strong>false</strong></td> <td align="left">如果为true则启用access log,否则不启用</td> </tr> <tr> <td align="left">servicecomb.accesslog.pattern</td> <td align="left">表示打印格式的字符串</td> <td align="left"><strong>"%h - - %t %r %s %B %D"</strong></td> <td align="left">配置项见_<strong>日志元素说明表</strong>_</td> </tr> <tr> <td align="left">servicecomb.accesslog.request.enabled</td> <td align="left">true/false</td> <td align="left"><strong>false</strong></td> <td align="left">如果为true则启用request log,否则不启用</td> </tr> <tr> <td align="left">servicecomb.accesslog.request.pattern</td> <td align="left">表示打印格式的字符串</td> <td align="left"><strong>"%h %SCB-transport - - %t %r %s %D"</strong></td> <td align="left">配置项见_<strong>日志元素说明表</strong>_</td> </tr> </tbody> </table> <h3 id="_4">日志格式配置</h3> <p>目前可用的日志元素配置项见 <strong><em>日志元素说明表(Apache &amp; W3C)</em></strong> 和 <strong><em>日志元素说明表(ServiceComb)</em></strong> 。</p> <p><em><strong>日志元素说明表 (Apache &amp; W3C)</strong></em></p> <table> <thead> <tr> <th align="left">元素名称</th> <th align="left">Apache日志格式</th> <th align="left">W3C日志格式</th> <th align="left">说明</th> </tr> </thead> <tbody> <tr> <td align="left">HTTP method</td> <td align="left">%m</td> <td align="left">cs-method</td> <td align="left">-</td> </tr> <tr> <td align="left">HTTP status</td> <td align="left">%s</td> <td align="left">sc-status</td> <td align="left">-</td> </tr> <tr> <td align="left">Duration in second</td> <td align="left">%T</td> <td align="left">-</td> <td align="left">-</td> </tr> <tr> <td align="left">Duration in millisecond</td> <td align="left">%D</td> <td align="left">-</td> <td align="left">-</td> </tr> <tr> <td align="left">Remote hostname</td> <td align="left">%h</td> <td align="left">-</td> <td align="left">-</td> </tr> <tr> <td align="left">Local hostname</td> <td align="left">%v</td> <td align="left">-</td> <td align="left">-</td> </tr> <tr> <td align="left">Local port</td> <td align="left">%p</td> <td align="left">-</td> <td align="left">-</td> </tr> <tr> <td align="left">Size of response</td> <td align="left">%B</td> <td align="left">-</td> <td align="left">如果消息体长度为零则打印"0"</td> </tr> <tr> <td align="left">Size of response</td> <td align="left">%b</td> <td align="left">-</td> <td align="left">如果消息体长度为零则打印"-"</td> </tr> <tr> <td align="left">First line of request</td> <td align="left">%r</td> <td align="left">-</td> <td align="left">包含HTTP Method、Uri、Http版本三部分内容</td> </tr> <tr> <td align="left">URI path</td> <td align="left">%U</td> <td align="left">cs-uri-stem</td> <td align="left">-</td> </tr> <tr> <td align="left">Query string</td> <td align="left">%q</td> <td align="left">cs-uri-query</td> <td align="left">-</td> </tr> <tr> <td align="left">URI path and query string</td> <td align="left">-</td> <td align="left">cs-uri</td> <td align="left">-</td> </tr> <tr> <td align="left">Request protocol</td> <td align="left">%H</td> <td align="left">-</td> <td align="left">-</td> </tr> <tr> <td align="left">Datetime the request is received</td> <td align="left">%t</td> <td align="left">-</td> <td align="left">按照默认设置打印时间戳,格式为"EEE, dd MMM yyyy HH:mm:ss zzz",语言为英文,时区为GMT</td> </tr> <tr> <td align="left">Configurable datetime the request is received</td> <td align="left">%{PATTERN}t</td> <td align="left">-</td> <td align="left">按照指定的格式打印时间戳,语言为英文,时区为GMT</td> </tr> <tr> <td align="left">Configurable datetime the request is received</td> <td align="left">%{PATTERN&#124;TIMEZONE&#124;LOCALE}t</td> <td align="left">-</td> <td align="left">按照指定的格式、语言、时区打印时间戳。允许省略其中的某部分配置(但两个分隔符号"&#124;"不可省略)。</td> </tr> <tr> <td align="left">Request header</td> <td align="left">%{VARNAME}i</td> <td align="left">-</td> <td align="left">如果没有找到指定的header,则打印"-"</td> </tr> <tr> <td align="left">Response header</td> <td align="left">%{VARNAME}o</td> <td align="left">-</td> <td align="left">如果没有找到指定的header,则打印"-"</td> </tr> <tr> <td align="left">Cookie</td> <td align="left">%{VARNAME}C</td> <td align="left">-</td> <td align="left">如果没有找到指定的cookie,则打印"-"</td> </tr> </tbody> </table> <p><em><strong>日志元素说明表(ServiceComb)</strong></em></p> <table> <thead> <tr> <th align="left">Element</th> <th align="left">Placeholder</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="left">TraceId</td> <td align="left">%SCB-traceId</td> <td align="left">打印ServiceComb生成的trace id,找不到则打印"-"</td> </tr> <tr> <td align="left">Invocation Context</td> <td align="left">%{VARNAME}SCB-ctx</td> <td align="left">打印key为<code>VARNAME</code>的invocation context值,找不到则打印"-"</td> </tr> <tr> <td align="left">Transport Method</td> <td align="left">%SCB-transport</td> <td align="left">打印当前调用的 <strong>transport method</strong> 。 <code>rest</code> 或者 <code>highway</code></td> </tr> </tbody> </table> <p><em><strong>Access log 与 Request log 的日志元素对比</strong></em></p> <table> <thead> <tr> <th>元素名称</th> <th>Apache&amp;W3C日志格式</th> <th>access log</th> <th>access log 说明</th> <th>request log</th> <th>request log说明</th> </tr> </thead> <tbody> <tr> <td>HTTP method</td> <td>%m &amp; cs-method</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>HTTP status</td> <td>%s &amp; sc-status</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Duration in second</td> <td>%T</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Duration in millisecond</td> <td>%D</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Remote hostname</td> <td>%h</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Local hostname</td> <td>%v</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Local port</td> <td>%p</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Size of response</td> <td>%B</td> <td>support</td> <td>如果消息体长度为零则打印"0"</td> <td>unsupported</td> <td>-</td> </tr> <tr> <td>Size of response</td> <td>%b</td> <td>support</td> <td>如果消息体长度为零则打印"-"</td> <td>unsupported</td> <td>-</td> </tr> <tr> <td>First line of request</td> <td>%r</td> <td>support</td> <td>包含HTTP Method、Uri、Http版本三部分内容</td> <td>support</td> <td>包含HTTP Method、Uri、Http版本三部分内容</td> </tr> <tr> <td>URI path</td> <td>%U &amp; cs-uri-stem</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Query string</td> <td>%q &amp; cs-uri-query</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>URI path and query string</td> <td>cs-uri</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Request protocol</td> <td>%H</td> <td>support</td> <td>-</td> <td>support</td> <td>-</td> </tr> <tr> <td>Datetime of the request</td> <td>%t</td> <td>support</td> <td>收到请求的时间。默认格式为"EEE, dd MMM yyyy HH:mm:ss zzz",语言为英文,时区为GMT</td> <td>support</td> <td>发送请求的时间。默认格式为"EEE, dd MMM yyyy HH:mm:ss zzz",语言为英文,时区为GMT</td> </tr> <tr> <td>Configurable datetime the request of the request</td> <td>%{PATTERN}t</td> <td>support</td> <td>收到请求的时间。按照指定的格式打印时间戳,语言为英文,时区为GMT</td> <td>support</td> <td>发送请求的时间。按照指定的格式打印时间戳,语言为英文,时区为GMT</td> </tr> <tr> <td>Configurable datetime the request of the request</td> <td>%{PATTERN&#124;TIMEZONE&#124;LOCALE}t</td> <td>support</td> <td>收到请求的时间。按照指定的格式、语言、时区打印时间戳。允许省略其中的某部分配置(但两个分隔符号"&#124;"不可省略)。</td> <td>support</td> <td>发送请求的时间。按照指定的格式、语言、时区打印时间戳。允许省略其中的某部分配置(但两个分隔符号"&#124;"不可省略)。</td> </tr> <tr> <td>Request header</td> <td>%{VARNAME}i</td> <td>support</td> <td>如果没有找到指定的header,则打印"-"</td> <td>support</td> <td>如果没有找到指定的header,则打印"-"</td> </tr> <tr> <td>Response header</td> <td>%{VARNAME}o</td> <td>support</td> <td>如果没有找到指定的header,则打印"-"</td> <td>support</td> <td>如果没有找到指定的header,则打印"-"</td> </tr> <tr> <td>Cookie</td> <td>%{VARNAME}C</td> <td>support</td> <td>如果没有找到指定的cookie,则打印"-"</td> <td>support</td> <td>如果没有找到指定的cookie,则打印"-"</td> </tr> <tr> <td>TraceId</td> <td>%SCB-traceId</td> <td>support</td> <td>打印ServiceComb生成的trace id,找不到则打印"-"</td> <td>support</td> <td>打印ServiceComb生成的trace id,找不到则打印"-"</td> </tr> <tr> <td>Invocation Context</td> <td>%{VARNAME}SCB-ctx</td> <td>support</td> <td>打印key为<code>VARNAME</code>的invocation context值,找不到则打印"-"</td> <td>support</td> <td>打印key为<code>VARNAME</code>的invocation context值,找不到则打印"-"</td> </tr> <tr> <td>transport method</td> <td>%SCB-transport</td> <td>unsupported</td> <td>只支持 rest 形式调用</td> <td>support</td> <td>调用使用的transport method</td> </tr> </tbody> </table> <h3 id="_5">日志输出文件配置</h3> <p>Access log &amp; Request log 的日志打印实现框架默认采用 Slf4j ,其中 logger 名称分别为 <code>accesslog</code> 和 <code>requestlog</code>, 可以结合应用使用的日志框架将日志输出到不同的文件中。</p> <h3 id="access-log-request-log_1">自定义扩展 Access Log &amp; Request Log</h3> <p>用户可以利用 ServiceComb 提供的 AccessLogItem 扩展机制,定制自己的 AccessLogItem, 我们把 Request Log 也当做一种 Access Log。</p> <h4 id="_6">相关类说明</h4> <ol> <li><strong>AccessLogItem</strong></li> </ol> <pre><code class="language-java">public interface AccessLogItem&lt;T&gt; { // 从Server端获取信息,打印 Access Log 日志 default void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) { } // 从Client 端获取信息, 打印 Request Log default void appendClientFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) { } } </code></pre> <blockquote> <p><strong>AccessLogItem</strong> 的定义如上所示</p> <ul> <li> <p><strong>Server 端</strong> 每收到一个请求,会触发一次 Access Log 日志打印。<strong>Client 端</strong> 每次对外远程调用结束,会触发一次 Request Log 日志打印。 </p> </li> <li> <p>每次日志打印,SDK 都会遍历有效的 <code>AccessLogItem</code> ,调用对应的方法获取此 Item 生成的 Log片 段,并将全部片段拼接成一条 Log 打印到日志文件中。 </p> </li> </ul> </blockquote> <ol> <li><strong>VertxRestAccessLogItemMeta</strong></li> </ol> <pre><code class="language-java"> // pattern占位符前缀 protected String prefix; // pattern占位符后缀 protected String suffix; // 优先级序号 protected int order; // AccessLogItem构造器 protected AccessLogItemCreator&lt;RoutingContext&gt; accessLogItemCreator; </code></pre> <p><code>VertxRestAccessLogItemMeta</code> 包含如上属性,它定义了 ServiceComb 如何解析 pattern 字符串以获得特定的 AccessLogItem。</p> <ul> <li> <p>如果用户想要定义一个占位符为 <code>%user-defined</code> 的 <code>AccessLogItem</code> ,则需要声明一个 <code>VertxRestAccessLogItemMeta</code> 的子类,设置 prefix="%user-defined",suffix=null,当 <code>AccessLogPatternParser</code> 解析到 "%user-defined" 时,从此 meta 类中取得 <code>AccessLogItemCreator</code> 创建对应的 <code>AccessLogItem</code>。<strong>注意</strong>:由于 "%user-defined" 占位符中没有变量部分,因此调用 <code>AccessLogItemCreator</code> 传入的配置参数为null。</p> </li> <li> <p>如果用户想要定义一个占位符为 <code>%{VARNAME}user-defined</code> 的 <code>AccessLogItem</code>,则声明的 <code>VertxRestAccessLogItemMeta</code> 子类中,设置prefix="%{",suffix="}user-defined",当 <code>AccessLogPatternParser</code> 解析到 "%{VARNAME}user-defined"时,会截取出"VARNAME"作为配置参数传入<code>AccessLogItemCreator</code>,创建一个<code>AccessLogItem</code>。</p> </li> </ul> <p><code>VertxRestAccessLogItemMeta</code> 有一个子类 <code>CompositeVertxRestAccessLogItemMeta</code>,当用户需要定义多个 AccessLogItem 时,可以将多个 <code>VertxRestAccessLogItemMeta</code> 聚合到 <code>CompositeVertxRestAccessLogItemMeta</code> 中。Parser 加载到类型为 <code>CompositeVertxRestAccessLogItemMeta</code> 的AccessLogItemMeta时,会调用其 <code>getAccessLogItemMetas()</code> 方法获得一组 AccessLogItemMeta。<code>VertxRestAccessLogItemMeta</code> 使用SPI机制加载,而<code>CompositeVertxRestAccessLogItemMeta</code>可以让用户只在SPI配置文件中配置一条记录就加载多条meta信息,给了用户更灵活的选择。</p> <ol> <li><strong>AccessLogItemCreator</strong></li> </ol> <pre><code class="language-java">public interface AccessLogItemCreator&lt;T&gt; { // 接收配置值,返回一个AccessLogItem。如果AccessLogItem的占位符没有可变的配置值部分,则此方法会接收到null。 AccessLogItem&lt;T&gt; createItem(String config); } </code></pre> <p>用户通过设置在自定义的 <code>VertxRestAccessLogItemMeta</code> 中的 <code>AccessLogItemCreator</code> 实例化自己的 <code>AccessLogItem</code>。由于这是一个函数式接口,当 <code>AccessLogItem</code> 的初始化方式较简单时,可以直接使用 Lambda表达式定义Creator,以简化开发。</p> <h4 id="accesslogitemmeta">AccessLogItemMeta 的匹配规则</h4> <p>AccessLogItemMeta 加载进 Parser 后,会进行一次排序。Parser 解析 pattern 串时会从前到后匹配 meta list,总的匹配规则如下:</p> <ol> <li> <p>优先匹配高优先级的meta。</p> </li> <li> <p>优先匹配有后缀的meta,当匹配上多个有后缀meta时,取前后缀相距最小的一个。</p> </li> <li> <p>优先匹配占位符长的meta,例如有两个 meta,"%abc"和"%a",如果匹配中了"%abc"则直接返回,不再匹配"%a"。</p> </li> </ol> <h4 id="_7">示例说明</h4> <ol> <li>扩展自定义 AccessLogItem</li> </ol> <p>首先用户需要 <code>AccessLogItem</code> 接口实现自己的 item:</p> <pre><code class="language-java">public class UserDefinedAccessLogItem implements AccessLogItem&lt;RoutingContext&gt; { private String config; public UserDefinedAccessLogItem(String config) { this.config = config; } @Override public void appendServerFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) { builder.append(&quot;user-defined--server-&quot;) .append(accessLogEvent.getRoutingContext().response().getStatusCode()) .append(&quot;-&quot;) .append(config); } @Override public void appendClientFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) { builder.append(&quot;user-server-defined-&quot;) .append(clientLogEvent.getResponse().getStatus()) .append(&quot;-&quot;) .append(config); } } </code></pre> <ol> <li>定义 <strong>AccessLogItem</strong> 的 meta 类</li> </ol> <p>继承 <code>VertxRestAccessLogItemMeta</code> 或 <code>CompositeVertxRestAccessLogItemMeta</code> 类,定义AccessLogItem的前后缀等信息:</p> <pre><code class="language-java">public class UserDefinedCompositeExtendedAccessLogItemMeta extends CompositeVertxRestAccessLogItemMeta { private static final List&lt;VertxRestAccessLogItemMeta&gt; META_LIST = new ArrayList&lt;&gt;(); static { META_LIST.add(new VertxRestAccessLogItemMeta(&quot;%{&quot;, &quot;}user-defined&quot;, UserDefinedAccessLogItem::new)); } @Override public List&lt;VertxRestAccessLogItemMeta&gt; getAccessLogItemMetas() { return META_LIST; } } </code></pre> <ol> <li>配置SPI加载文件</li> </ol> <p>在 <code>resources/META-INF/services/</code> 目录下定义一个名为 "org.apache.servicecomb.common.accessLog.core.parser.VertxRestAccessLogItemMeta" 的文件,将上一步中定义的meta类完整类名填写到该文件中,供Parser加载meta类。</p> <ol> <li>配置 Access Log 的 pattern</li> </ol> <pre><code class="language-yaml"># 服务端配置 servicecomb: accesslog: enabled: true ## 应用作为服务端,开启 Access log pattern: &quot;%{param}user-defined&quot; ## Access log 日志格式 request: enabled: true ## 应用作为客户端,开启 Request log pattern: &quot;%{param}user-defined&quot; ## Request log 日志格式 </code></pre> <p>以服务端为例, 运行服务触发Access Log打印,假设请求返回状态码是 200,则可以看到Access Log打印内容为 "<code>user-defined--server-200-param</code>"。</p> </div> </div><footer> <hr/> <div role="contentinfo"> <!-- Copyright etc --> </div> Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>. </footer> </div> </div> </section> </div> <div class="rst-versions" role="note" aria-label="Versions"> <span class="rst-current-version" data-toggle="rst-current-version"> </span> </div> <script>var base_url = '..';</script> <script src="../js/theme_extra.js" defer></script> <script src="../js/theme.js" defer></script> <script src="../search/main.js" defer></script> <script defer> window.onload = function () { SphinxRtdTheme.Navigation.enable(true); }; </script> </body> </html>