Skip to content

Commit

Permalink
Support TCMalloc service
Browse files Browse the repository at this point in the history
  • Loading branch information
chenBright committed Jan 14, 2024
1 parent 2098dd3 commit eeef8d4
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/brpc/builtin/index_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ void IndexService::default_method(::google::protobuf::RpcController* controller,
<< Path("/threads", html_addr) << " : Check pstack"
<< (!FLAGS_enable_threads_service ? " (disabled)" : "") << NL
<< Path("/dir", html_addr) << " : Browse directories and files"
<< (!FLAGS_enable_dir_service ? " (disabled)" : "") << NL;
<< (!FLAGS_enable_dir_service ? " (disabled)" : "") << NL
<< Path("/tcmalloc", html_addr) << " : Get TCMalloc information"
<< (!IsTCMallocEnabled() ? " (disabled)" : "") << NL;
if (use_html) {
os << "</body></html>";
}
Expand Down
76 changes: 76 additions & 0 deletions src/brpc/builtin/tcmalloc_service.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#include "butil/time.h"
#include "butil/logging.h"
#include "brpc/controller.h" // Controller
#include "brpc/closure_guard.h" // ClosureGuard
#include "brpc/builtin/tcmalloc_service.h"
#include "brpc/details/tcmalloc_extension.h"

namespace brpc {

DEFINE_int32(max_tc_stats_buf_len, 32 * 1024, "max length of TCMalloc stats");
BRPC_VALIDATE_GFLAG(max_tc_stats_buf_len, PositiveInteger);

static inline void get_tcmalloc_num_prop(MallocExtension* malloc_ext,
const char* prop_name,
butil::IOBufBuilder& os) {
size_t value;
if (malloc_ext->GetNumericProperty(prop_name, &value)) {
os << prop_name << ": " << value << "\n";
}
}

void TcmallocService::default_method(::google::protobuf::RpcController* cntl_base,
const ::brpc::TCMallocRequest*,
::brpc::TCMallocResponse*,
::google::protobuf::Closure* done) {
ClosureGuard done_guard(done);
auto cntl = static_cast<Controller*>(cntl_base);
cntl->http_response().set_content_type("text/plain");
butil::IOBuf& resp = cntl->response_attachment();

MallocExtension* malloc_ext = MallocExtension::instance();
if (!malloc_ext) {
resp.append("tcmalloc is not enabled");
cntl->http_response().set_status_code(HTTP_STATUS_FORBIDDEN);
return;
}

butil::IOBufBuilder os;

os << "------------------------------------------------\n";
get_tcmalloc_num_prop(malloc_ext, "generic.total_physical_bytes", os);
get_tcmalloc_num_prop(malloc_ext, "generic.current_allocated_bytes", os);
get_tcmalloc_num_prop(malloc_ext, "generic.heap_size", os);
get_tcmalloc_num_prop(malloc_ext, "tcmalloc.current_total_thread_cache_bytes", os);
get_tcmalloc_num_prop(malloc_ext, "tcmalloc.central_cache_free_bytes", os);
get_tcmalloc_num_prop(malloc_ext, "tcmalloc.transfer_cache_free_bytes", os);
get_tcmalloc_num_prop(malloc_ext, "tcmalloc.thread_cache_free_bytes", os);
get_tcmalloc_num_prop(malloc_ext, "tcmalloc.pageheap_free_bytes", os);
get_tcmalloc_num_prop(malloc_ext, "tcmalloc.pageheap_unmapped_bytes", os);

int32_t len = FLAGS_max_tc_stats_buf_len;
std::unique_ptr<char[]> buf(new char[len]);
malloc_ext->GetStats(buf.get(), len);
os << buf;

os.move_to(resp);
}

} // namespace brpc
36 changes: 36 additions & 0 deletions src/brpc/builtin/tcmalloc_service.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#ifndef BRPC_TCMALLOC_SERVICE_H
#define BRPC_TCMALLOC_SERVICE_H

#include "brpc/builtin_service.pb.h"

namespace brpc {

class TcmallocService : public tcmalloc {
public:
void default_method(::google::protobuf::RpcController* cntl_base,
const ::brpc::TCMallocRequest* request,
::brpc::TCMallocResponse* response,
::google::protobuf::Closure* done) override;
};

} // namespace brpc


#endif //BRPC_TCMALLOC_SERVICE_H
6 changes: 6 additions & 0 deletions src/brpc/builtin_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ message VLogRequest {}
message VLogResponse {}
message MetricsRequest {}
message MetricsResponse {}
message TCMallocRequest {}
message TCMallocResponse {}
message BadMethodRequest {
required string service_name = 1;
}
Expand Down Expand Up @@ -169,3 +171,7 @@ service rpcz {
service dir {
rpc default_method(DirRequest) returns (DirResponse);
}

service tcmalloc {
rpc default_method(TCMallocRequest) returns (TCMallocResponse);
}
4 changes: 4 additions & 0 deletions src/brpc/details/tcmalloc_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ bool IsHeapProfilerEnabled() {
return MallocExtension::instance() != NULL;
}

bool IsTCMallocEnabled() {
return IsHeapProfilerEnabled();
}

static bool check_TCMALLOC_SAMPLE_PARAMETER() {
char* str = getenv("TCMALLOC_SAMPLE_PARAMETER");
if (str == NULL) {
Expand Down
2 changes: 2 additions & 0 deletions src/brpc/details/tcmalloc_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,5 +315,7 @@ class PERFTOOLS_DLL_DECL MallocExtension {
// True iff heap profiler is enabled.
bool IsHeapProfilerEnabled();

bool IsTCMallocEnabled();

// True iff TCMALLOC_SAMPLE_PARAMETER is set in environment.
bool has_TCMALLOC_SAMPLE_PARAMETER();
6 changes: 6 additions & 0 deletions src/brpc/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "brpc/builtin/sockets_service.h" // SocketsService
#include "brpc/builtin/hotspots_service.h" // HotspotsService
#include "brpc/builtin/prometheus_metrics_service.h"
#include "brpc/builtin/tcmalloc_service.h"
#include "brpc/details/method_status.h"
#include "brpc/load_balancer.h"
#include "brpc/naming_service.h"
Expand Down Expand Up @@ -527,6 +528,11 @@ int Server::AddBuiltinServices() {
LOG(ERROR) << "Fail to add ThreadsService";
return -1;
}
if (IsTCMallocEnabled() &&
AddBuiltinService(new (std::nothrow) TcmallocService)) {
LOG(ERROR) << "Fail to add TcmallocService";
return -1;
}

#if !BRPC_WITH_GLOG
if (AddBuiltinService(new (std::nothrow) VLogService)) {
Expand Down
19 changes: 19 additions & 0 deletions test/brpc_builtin_service_unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "brpc/builtin/bthreads_service.h" // BthreadsService
#include "brpc/builtin/ids_service.h" // IdsService
#include "brpc/builtin/sockets_service.h" // SocketsService
#include "brpc/builtin/tcmalloc_service.h"
#include "brpc/builtin/common.h"
#include "brpc/builtin/bad_method_service.h"
#include "echo.pb.h"
Expand Down Expand Up @@ -833,3 +834,21 @@ TEST_F(BuiltinServiceTest, sockets) {
CheckContent(cntl, "fd=-1");
}
}

TEST_F(BuiltinServiceTest, tcmalloc) {
brpc::TcmallocService service;
brpc::TCMallocRequest req;
brpc::TCMallocResponse res;
brpc::Controller cntl;
ClosureChecker done;
service.default_method(&cntl, &req, &res, &done);
EXPECT_FALSE(cntl.Failed());
CheckContent(cntl, "generic.current_allocated_bytes");
CheckContent(cntl, "generic.heap_size");
CheckContent(cntl, "tcmalloc.current_total_thread_cache_bytes");
CheckContent(cntl, "tcmalloc.central_cache_free_bytes");
CheckContent(cntl, "tcmalloc.transfer_cache_free_bytes");
CheckContent(cntl, "tcmalloc.thread_cache_free_bytes");
CheckContent(cntl, "tcmalloc.pageheap_free_bytes");
CheckContent(cntl, "tcmalloc.pageheap_unmapped_bytes");
}

0 comments on commit eeef8d4

Please sign in to comment.