Skip to content

Commit

Permalink
Merge pull request #16 from brpc/jiangrujie-dev
Browse files Browse the repository at this point in the history
Add documentation in english (TBR offline)
  • Loading branch information
jamesge authored Sep 18, 2017
2 parents f3b388a + bea6f4c commit 16fbb25
Show file tree
Hide file tree
Showing 5 changed files with 632 additions and 68 deletions.
15 changes: 7 additions & 8 deletions docs/cn/http_client.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ URL的一般形式如下图:

确实,在简单使用场景下,这两者有所重复,但在复杂场景中,两者差别很大,比如:

- 访问挂在bns下的多个http server。此时Channel.Init传入的是bns节点名称,对uri()的赋值则是包含Host的完整URL(比如"www.foo.com/index.html?name=value"),BNS下所有的http server都会看到"Host: www.foo.com";uri()也可以是只包含路径的URL,比如"/index.html?name=value",框架会以目标server的ip和port为Host,地址为10.46.188.39:8989的http server将会看到"Host: 10.46.188.39:8989"。
- 访问挂在bns下的多个http server。此时Channel.Init传入的是bns节点名称,对uri()的赋值则是包含Host的完整URL(比如"www.foo.com/index.html?name=value"),BNS下所有的http server都会看到"Host: [www.foo.com](http://www.foo.com/)";uri()也可以是只包含路径的URL,比如"/index.html?name=value",框架会以目标server的ip和port为Host,地址为10.46.188.39:8989的http server将会看到"Host: 10.46.188.39:8989"。
- 通过http proxy访问目标server。此时Channel.Init传入的是proxy server的地址,但uri()填入的是目标server的URL。

# 常见设置
Expand Down Expand Up @@ -132,7 +132,7 @@ os.move_to(cntl->request_attachment());
Notes on http header:
- 根据 HTTP 协议[规定](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2), header 的 field_name部分不区分大小写。在r33861前,field_name都转为了小写,在r33861后,大小写能保持不变(仍然支持大小写不敏感)
- 根据 HTTP 协议[规定](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2), header 的 field_name部分不区分大小写。brpc对于field_name大小写保持不变,且仍然支持大小写不敏感
- 如果 HTTP 头中出现了相同的 field_name, 根据协议[规定](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2),value将被合并到一起, 中间用逗号(,) 分隔, 具体value如何理解,需要用户自己确定.
- query之间用"&"分隔, key和value之间用"="分隔, value可以省略,比如key1=value1&key2&key3=value3中key2是合理的query,值为空字符串。
Expand All @@ -144,12 +144,11 @@ Notes on http header:
当Server返回的http status code不是2xx时,该次http访问即视为失败,client端会设置对应的ErrorCode:
- 在r31923前,1xx和3xx错误对应EPROTONOSUPPORT,4xx错误对应EREQUEST,其余错误对应EINTERNAL。http body不会置入`cntl->response_attachment()`。
- 在r31923后,所有错误被统一为EHTTP。如果用户发现`cntl->ErrorCode()`为EHTTP,那么可以检查`cntl->http_response().status_code()`以获得具体的http错误。同时http body会置入`cntl->response_attachment()`,用户可以把代表错误的html或json传递回来。
- 所有错误被统一为EHTTP。如果用户发现`cntl->ErrorCode()`为EHTTP,那么可以检查`cntl->http_response().status_code()`以获得具体的http错误。同时http body会置入`cntl->response_attachment()`,用户可以把代表错误的html或json传递回来。
# 压缩request body
在r33877后,调用Controller::set_request_compress_type(brpc::COMPRESS_TYPE_GZIP)可将http body用gzip压缩,并设置"Content-Encoding"为"gzip"。
调用Controller::set_request_compress_type(brpc::COMPRESS_TYPE_GZIP)可将http body用gzip压缩,并设置"Content-Encoding"为"gzip"。
# 解压response body
Expand All @@ -172,9 +171,9 @@ if (encoding != NULL && *encoding == "gzip") {

# 持续下载

r33796前brpc client在下载一个超长的body时,需要一直等待直到body完整才会视作RPC结束,这个过程中超长body都会存在内存中,如果body是无限长的(比如直播用的flv文件),那么内存会持续增长,直到超时。换句话说,r33796前的brpc client不适合下载大文件。
通常下载一个超长的body时,需要一直等待直到body完整才会视作RPC结束,这个过程中超长body都会存在内存中,如果body是无限长的(比如直播用的flv文件),那么内存会持续增长,直到超时。这样的http client不适合下载大文件。

r33796后brpc client支持在读取完body前就结束RPC,让用户在RPC结束后再读取持续增长的body。注意这个功能不等同于“支持http chunked mode”,brpc的http实现一直支持解析chunked mode,这里的问题是如何让用户处理超长或无限长的body,和body是否以chunked mode传输无关。
brpc client支持在读取完body前就结束RPC,让用户在RPC结束后再读取持续增长的body。注意这个功能不等同于“支持http chunked mode”,brpc的http实现一直支持解析chunked mode,这里的问题是如何让用户处理超长或无限长的body,和body是否以chunked mode传输无关。

使用方法如下:

Expand Down Expand Up @@ -215,4 +214,4 @@ r33796后brpc client支持在读取完body前就结束RPC,让用户在RPC结
# 访问带认证的Server
根据Server的认证方式生成对应的auth_data,并设置为http header "Authorization"的值。比如用的是curl,那就加上选项`-H "Authorization : <auth_data>"。`查询[giano文档](http://doc.noah.baidu.com/new/baas/base_tool.md)了解如何在Shell中生成auth_data。
根据Server的认证方式生成对应的auth_data,并设置为http header "Authorization"的值。比如用的是curl,那就加上选项`-H "Authorization : <auth_data>"。`
74 changes: 14 additions & 60 deletions docs/cn/streaming_log.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,52 +16,12 @@ PLOG(FATAL) << "Fail to call function setting errno";
VLOG(1) << "verbose log tier 1";
CHECK_GT(1, 2) << "1 can't be greater than 2";

// public/common >= r32401支持限制打印频率。
LOG_EVERY_SECOND(INFO) << "High-frequent logs";
LOG_EVERY_N(ERROR, 10) << "High-frequent logs";
LOG_FIRST_N(INFO, 20) << "Logs that prints for at most 20 times";
LOG_ONCE(WARNING) << "Logs that only prints once";
```
## 配置comlog
```c++
// logging默认重定向至comlog,要配置comlog的话,要额外include comlog_sink.h
#include <butil/comlog_sink.h>
// 从./conf/log.conf读取comlog的配置。SetupFromConfig是我们提供的封装函数,不用像com_loadlog那样区分path和file。
if (logging::ComlogSink::GetInstance()->SetupFromConfig("conf/log.conf") != 0) {
LOG(ERROR) << "Fail to setup comlog from conf/log.conf";
return -1;
}
OR
// 直接调用com_loadlog从./conf/log.conf读取comlog的配置。
if (com_loadlog("./conf", "log.conf") != 0) {
LOG(ERROR) << "Fail to com_loadlog";
return -1;
}
OR
// 把日志打入./my_log/<process-name>.log中,comlog选项取默认值。
logging::ComlogSinkOptions options;
options.log_dir = "my_log";
if (logging::ComlogSink::GetInstance()->Setup(&options) != 0) {
LOG(ERROR) << "Fail to setup comlog from options";
return -1;
}
OR
// 把日志打入./log/<process-name>.log中,comlog选项取默认值。
if (logging::ComlogSink::GetInstance()->Setup(NULL) != 0) {
LOG(ERROR) << "Fail to setup comlog by default options";
return -1;
}
```

# DESCRIPTION
流式日志是打印复杂对象或模板对象的不二之选。大部分业务对象都很复杂,如果用printf形式的函数打印,你需要先把对象转成string,才能以%s输出。但string组合起来既不方便(比如没法append数字),还得分配大量的临时内存(string导致的)。C++中解决这个问题的方法便是“把日志流式地送入std::ostream对象”。比如为了打印对象A,那么我们得实现如下的函数:
Expand Down Expand Up @@ -122,17 +82,17 @@ LOG(WARNING) << "Unusual thing happened ..." << ...;
LOG(TRACE) << "Something just took place..." << ...;
```
streaming log的日志等级是comlog和glog的合集,具体的来说,下表是日志等级的映射关系
streaming log的日志等级与glog映射关系如下
| streaming log | comlog | glog | 使用场景 |
| ------------- | ---------------------------- | -------------------- | ---------------------------------------- |
| FATAL | COMLOG_FATAL | FATAL (coredump) | 致命错误。但由于百度内大部分FATAL实际上非致命,所以streaming log的FATAL默认不像glog那样直接coredump,除非打开了[-crash_on_fatal_log](http://brpc.baidu.com:8765/flags/crash_on_fatal_log) |
| ERROR | COMLOG_FATAL | ERROR | 不致命的错误。 |
| WARNING | COMLOG_WARNING | WARNING | 不常见的分支。 |
| NOTICE | COMLOG_NOTICE | - | 一般来说你不应该使用NOTICE,它用于打印重要的业务日志,若要使用务必和检索端同学确认。glog没有NOTICE。 |
| INFO, TRACE | COMLOG_TRACE | INFO | 打印重要的副作用。比如打开关闭了某某资源之类的。 |
| VLOG(n) | COMLOG_TRACE | INFO | 打印分层的详细日志。 |
| DEBUG | COMLOG_TRACEVLOG(1) (NDEBUG) | INFOVLOG(1) (NDEBUG) | 仅为代码兼容性,基本没有用。若要使日志仅在未定义NDEBUG时才打印,用DLOG/DPLOG/DVLOG等即可。 |
| streaming log | glog | 使用场景 |
| ------------- | -------------------- | ---------------------------------------- |
| FATAL | FATAL (coredump) | 致命错误。但由于百度内大部分FATAL实际上非致命,所以streaming log的FATAL默认不像glog那样直接coredump,除非打开了[-crash_on_fatal_log](http://brpc.baidu.com:8765/flags/crash_on_fatal_log) |
| ERROR | ERROR | 不致命的错误。 |
| WARNING | WARNING | 不常见的分支。 |
| NOTICE | - | 一般来说你不应该使用NOTICE,它用于打印重要的业务日志,若要使用务必和检索端同学确认。glog没有NOTICE。 |
| INFO, TRACE | INFO | 打印重要的副作用。比如打开关闭了某某资源之类的。 |
| VLOG(n) | INFO | 打印分层的详细日志。 |
| DEBUG | INFOVLOG(1) (NDEBUG) | 仅为代码兼容性,基本没有用。若要使日志仅在未定义NDEBUG时才打印,用DLOG/DPLOG/DVLOG等即可。 |
## PLOG
Expand All @@ -148,7 +108,7 @@ if (fd < 0) {

## noflush

如果你暂时不希望刷入comlog,加上noflush。这一般会用在打印循环中:
如果你暂时不希望刷到屏幕,加上noflush。这一般会用在打印循环中:

```c++
LOG(TRACE) << "Items:" << noflush;
Expand All @@ -158,7 +118,7 @@ for (iterator it = items.begin(); it != items.end(); ++it) {
LOG(TRACE);
```
前两次TRACE日志都没有刷到comlog,而是还记录在thread-local缓冲中,第三次TRACE日志则把缓冲都刷入了comlog。如果items里面有三个元素,不加noflush的打印结果可能是这样的:
前两次TRACE日志都没有刷到屏幕,而是还记录在thread-local缓冲中,第三次TRACE日志则把缓冲都刷入了屏幕。如果items里面有三个元素,不加noflush的打印结果可能是这样的:
```
TRACE: ... Items:
Expand All @@ -173,7 +133,7 @@ TRACE: ... item3
TRACE: ... Items: item1 item2 item3
```
r34694前noflush和调用处的pthread绑定,如果在noflush后发送了RPC(可能跨越pthread),那么日志输出可能不符合预期。r34694后noflush支持bthread,可以实现类似于UB的pushnotice的效果,即检索线程一路打印都暂不刷出(加上noflush),直到最后检索结束时再一次性刷出。注意,如果检索过程是异步的,就不应该使用noflush,因为异步显然会跨越bthread,使noflush仍然失效。
noflush支持bthread,可以实现类似于UB的pushnotice的效果,即检索线程一路打印都暂不刷出(加上noflush),直到最后检索结束时再一次性刷出。注意,如果检索过程是异步的,就不应该使用noflush,因为异步显然会跨越bthread,使noflush仍然失效。
## LOG_IF
Expand Down Expand Up @@ -299,7 +259,7 @@ CHECK(x > y); // Check failed: x > y.
## LogSink
streaming log通过logging::SetLogSink修改日志刷入的目标,默认是屏幕。用户可以继承LogSink,实现自己的日志打印逻辑。我们默认提供了两个LogSink实现
streaming log通过logging::SetLogSink修改日志刷入的目标,默认是屏幕。用户可以继承LogSink,实现自己的日志打印逻辑。我们默认提供了个LogSink实现
### StringSink
Expand All @@ -316,9 +276,3 @@ TEST_F(StreamingLogTest, log_at) {
::logging::SetLogSink(old_sink);
}
```

### ComlogSink

定义在butil/comlog_sink.h中,把日志打印入comlog,主要用于线上系统,用法见[SYNOPSIS](#SYNOPSIS)一段。

使用ComlogSink的streaming log可以和com_writelog, ul_writelog混用。你并不需要把程序中所有日志都换成streaming log。
Loading

0 comments on commit 16fbb25

Please sign in to comment.