This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-docs.git

commit cca6915f707d34f6dade06d51c72492668edd513
Author: yaohaishi <yaohai...@huawei.com>
AuthorDate: Tue Jun 12 21:18:36 2018 +0800

    增加AccessLog自定义扩展的说明
---
 .../build-provider/access-log-configuration.md     | 161 +++++++++++++++++----
 1 file changed, 133 insertions(+), 28 deletions(-)

diff --git 
a/java-chassis-reference/zh_CN/build-provider/access-log-configuration.md 
b/java-chassis-reference/zh_CN/build-provider/access-log-configuration.md
index 775b945..15f7a64 100644
--- a/java-chassis-reference/zh_CN/build-provider/access-log-configuration.md
+++ b/java-chassis-reference/zh_CN/build-provider/access-log-configuration.md
@@ -31,33 +31,39 @@ _**Access log 配置项说明**_
 
 ### 日志格式配置
 
-目前可用的日志元素配置项见_**日志元素说明表**_。
+目前可用的日志元素配置项见 ***日志元素说明表(Apache & W3C)*** 和 ***日志元素说明表(ServiceComb)*** 。
 
-_**日志元素说明表**_
+_**日志元素说明表 (Apache & W3C)**_
 
 | 元素名称 | Apache日志格式 | W3C日志格式 | 说明 |
 | :--- | :--- | :--- | :--- |
-| Method | %m | cs-method |  |
-| Status | %s | sc-status |  |
-| Duration s | %T | - |  |
-| Duration ms | %D | - |  |
-| Remote Host | %h | - |  |
-| Local Host | %v | - |  |
-| Local port | %p | - |  |
-| Bytes Written v1 | %B | - | 如果消息体长度为零则打印"0" |
-| Bytes Written v2 | %b | - | 如果消息体长度为零则打印"-" |
+| HTTP method | %m | cs-method | - |
+| HTTP status | %s | sc-status | - |
+| Duration in second | %T | - | - |
+| Duration in millisecond | %D | - | - |
+| Remote hostname | %h | - | - |
+| Local hostname | %v | - | - |
+| Local port | %p | - | - |
+| Size of response | %B | - | 如果消息体长度为零则打印"0" |
+| Size of response | %b | - | 如果消息体长度为零则打印"-" |
 | First line of request | %r | - | 包含HTTP Method、Uri、Http版本三部分内容 |
-| URI path only | %U | cs-uri-stem |  |
-| Query only | %q | cs-uri-query |  |
-| URI path incl query | - | cs-uri |  |
-| Version / Protocol | %H | - |  |
-| Datetime Apache | %t | - | 按照默认设置打印时间戳,格式为"EEE, dd MMM yyyy HH:mm:ss 
zzz",语言为英文,时区为GMT |
-| Datetime Apache Configurable v1 | %{PATTERN}t | - | 
按照指定的格式打印时间戳,语言为英文,时区为GMT |
-| Datetime Apache Configurable v2 | %{PATTERN&#124;TIMEZONE&#124;LOCALE}t | - 
| 按照指定的格式、语言、时区打印时间戳。允许省略其中的某部分配置(但两个分隔符号"&#124;"不可省略)。 |
-| Incoming Headers | %{IDENTIFIER}i | - | 如果没有找到指定的header,则打印"-" |
-| Outgoing Response Headers | %{IDENTIFIER}o | - | 如果没有找到指定的header,则打印"-" |
-| Cookie | %{IDENTIFIER}c | - | 如果没有找到指定的cookie,则打印"-" |
-| TraceId | - | - | ServiceComb框架提供的TraceId打印元素,占位符格式为"%SCB-traceId" |
+| URI path | %U | cs-uri-stem | - |
+| Query string | %q | cs-uri-query | - |
+| URI path and query string | - | cs-uri | - |
+| Request protocol | %H | - | - |
+| Datetime the request is received | %t | - | 按照默认设置打印时间戳,格式为"EEE, dd MMM yyyy 
HH:mm:ss zzz",语言为英文,时区为GMT |
+| Configurable datetime the request is received | %{PATTERN}t | - | 
按照指定的格式打印时间戳,语言为英文,时区为GMT |
+| Configurable datetime the request is received | 
%{PATTERN&#124;TIMEZONE&#124;LOCALE}t | - | 
按照指定的格式、语言、时区打印时间戳。允许省略其中的某部分配置(但两个分隔符号"&#124;"不可省略)。 |
+| Request header | %{VARNAME}i | - | 如果没有找到指定的header,则打印"-" |
+| Response header | %{VARNAME}o | - | 如果没有找到指定的header,则打印"-" |
+| Cookie | %{VARNAME}C | - | 如果没有找到指定的cookie,则打印"-" |
+
+_**日志元素说明表(ServiceComb)**_
+
+| Element | Placeholder | Comment |
+| :----   | :---------- | :------ |
+| TraceId | %SCB-traceId | 打印ServiceComb生成的trace id,找不到则打印"-" |
+| Invocation Context | %{VARNAME}SCB-ctx | 打印key为`VARNAME`的invocation 
context值,找不到则打印"-" |
 
 ### 日志输出文件配置
 
@@ -68,10 +74,10 @@ _**日志文件配置项**_
 | 配置项 | 默认值 | 含义 | 说明 |
 | :--- | :--- | :--- | :--- |
 | paas.logs.accesslog.dir | ${paas.logs.dir} | 日志文件输出目录 | 与普通日志输出到同一个目录中 |
-| paas.logs.accesslog.file | access.log | 日志文件名 |  |
-| log4j.appender.access.MaxBackupIndex | 10 | 最大保存的日志滚动文件个数 |  |
+| paas.logs.accesslog.file | access.log | 日志文件名 | - |
+| log4j.appender.access.MaxBackupIndex | 10 | 最大保存的日志滚动文件个数 | - |
 | log4j.appender.access.MaxFileSize | 20MB | 日志文件最大体积 | 正在记录的文件达到此大小时触发日志滚动存储 |
-| log4j.appender.access.logPermission | rw------- | 日志文件权限 |  |
+| log4j.appender.access.logPermission | rw------- | 日志文件权限 | - |
 
 > _**注意:**_  
 > 由于ServiceComb的日志打印功能只依赖slf4j的接口,因此用户可以选择其他日志打印框架,选择其他日志打印框架时需要用户自行配置日志文件输出选项。
@@ -136,6 +142,108 @@ _**日志文件配置项**_
 </configuration>
 ```
 
+### 自定义扩展Access Log
+
+用户可以利用ServiceComb提供的AccessLogItem扩展机制,定制自己的AccessLogItem。
+
+#### 相关类说明
+
+1. `AccessLogItem`
+
+  ```java
+  public interface AccessLogItem<T> {
+    /**
+     * 从accessLogParam中获取特定的内容,组装成access log的打印内容并返回
+     */
+    String getFormattedItem(AccessLogParam<T> accessLogParam);
+  }
+  ```
+  `AccessLogItem`的定义如上所示,每一次请求触发Access Log打印时,ServiceComb的Access 
Log机制都会遍历有效的`AccessLogItem`,调用`getFormattedItem`方法获取此Item生成的Access 
Log片段,并将全部片段拼接成一条Access Log打印到日志文件中。
+  参数`AccessLogParam<T>`包含请求开始时间、结束时间以及类型为`T`的请求上下文信息,在REST over 
Vertx通信方式中,类型`T`为Vert.x的`RoutingContext`。
+
+2. `VertxRestAccessLogItemMeta`
+
+  ```java
+  // pattern占位符前缀
+  protected String prefix;
+  // pattern占位符后缀
+  protected String suffix;
+  // 优先级序号
+  protected int order;
+  // AccessLogItem构造器
+  protected AccessLogItemCreator<RoutingContext> accessLogItemCreator;
+  ```
+  
`VertxRestAccessLogItemMeta`包含如上属性,它定义了ServiceComb如何解析pattern字符串以获得特定的AccessLogItem。
+  - 
如果用户想要定义一个占位符为`%user-defined`的`AccessLogItem`,则需要声明一个`VertxRestAccessLogItemMeta`的子类,设置prefix="%user-defined",suffix=null,当`AccessLogPatternParser`解析到"%user-defined"时,从此meta类中取得`AccessLogItemCreator`创建对应的`AccessLogItem`。**注意**:由于"%user-defined"占位符中没有变量部分,因此调用`AccessLogItemCreator`传入的配置参数为null。
+  - 
如果用户想要定义一个占位符为`%{VARNAME}user-defined`的`AccessLogItem`,则声明的`VertxRestAccessLogItemMeta`子类中,设置prefix="%{",suffix="}user-defined",当`AccessLogPatternParser`解析到"%{VARNAME}user-defined"时,会截取出"VARNAME"作为配置参数传入`AccessLogItemCreator`,创建一个`AccessLogItem`。
+
+  
`VertxRestAccessLogItemMeta`有一个子类`CompositeVertxRestAccessLogItemMeta`,当用户需要定义多个AccessLogItem时,可以将多个`VertxRestAccessLogItemMeta`聚合到`CompositeVertxRestAccessLogItemMeta`中。Parser加载到类型为`CompositeVertxRestAccessLogItemMeta`的AccessLogItemMeta时,会调用其`getAccessLogItemMetas()`方法获得一组AccessLogItemMeta。`VertxRestAccessLogItemMeta`使用SPI机制加载,而`CompositeVertxRestAccessLogItemMeta`可以让用户只在SPI配置文件中配置一条记录就加载多条meta信息,给了用户更灵活的选择。
+
+3. `AccessLogItemCreator`
+
+  ```java
+  public interface AccessLogItemCreator<T> {
+    // 接收配置值,返回一个AccessLogItem。如果AccessLogItem的占位符没有可变的配置值部分,则此方法会接收到null。
+    AccessLogItem<T> createItem(String config);
+  }
+  ```
+
+  
用户通过设置在自定义的`VertxRestAccessLogItemMeta`中的`AccessLogItemCreator`实例化自己的`AccessLogItem`。由于这是一个函数式接口,当`AccessLogItem`的初始化方式较简单时,可以直接使用Lambda表达式定义Creator,以简化开发。
+
+#### AccessLogItemMeta的匹配规则
+
+AccessLogItemMeta加载进Parser后,会进行一次排序。Parser解析pattern串时会从前到后匹配meta list,总的匹配规则如下:
+1. 优先匹配高优先级的meta。
+2. 优先匹配有后缀的meta,当匹配上多个有后缀meta时,取前后缀相距最小的一个。
+3. 优先匹配占位符长的meta,例如有两个meta,"%abc"和"%a",如果匹配中了"%abc"则直接返回,不再匹配"%a"。
+
+#### 示例说明
+
+1. 扩展自定义AccessLogItem
+
+  首先用户需要`AccessLogItem`接口实现自己的item:
+  ```java
+  public class UserDefinedAccessLogItem implements 
AccessLogItem<RoutingContext> {
+    private String config;
+
+    public UserDefinedAccessLogItem(String config) {
+      this.config = config;
+    }
+
+    @Override
+    public String getFormattedItem(AccessLogParam<RoutingContext> 
accessLogParam) {
+      // 此处是用户自定义的逻辑,需要从AccessLogParam或其他地方取相关数据,生成并返回access log片段
+      return "user-defined-[" + config + "]-[" + 
accessLogParam.getStartMillisecond() + "]";
+    }
+  }
+  ```
+
+2. 定义AccessLogItem的meta类
+
+  
继承`VertxRestAccessLogItemMeta`或`CompositeVertxRestAccessLogItemMeta`类,定义AccessLogItem的前后缀等信息:
+  ```java
+  public class UserDefinedCompositeExtendedAccessLogItemMeta extends 
CompositeVertxRestAccessLogItemMeta {
+    private static final List<VertxRestAccessLogItemMeta> META_LIST = new 
ArrayList<>();
+
+    static {
+      META_LIST.add(new VertxRestAccessLogItemMeta("%{", "}user-defined", 
UserDefinedAccessLogItem::new));
+    }
+
+    @Override
+    public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {
+      return META_LIST;
+    }
+  }
+  ```
+
+3. 配置SPI加载文件
+
+  
在`resources/META-INF/services/`目录下定义一个名为"org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta"的文件,将上一步中定义的meta类完整类名填写到该文件中,供Parser加载meta类。
+
+4. 配置Access Log的pattern
+
+  在microservice.yaml文件中的配置pattern,假设为"%{test-config}user-defined",运行服务触发Access 
Log打印,假设请求开始时间为1,则可以看到Access Log打印内容为"user-defined-[test-config]-[1]"。
+
 ## 示例代码
 
 ### microservice.yaml文件中的配置
@@ -159,6 +267,3 @@ log4j.appender.access.MaxBackupIndex=10
 log4j.appender.access.MaxFileSize=20MB
 log4j.appender.access.logPermission=rw-------
 ```
-
-
-

Reply via email to