This is an automated email from the ASF dual-hosted git repository.
chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git
The following commit(s) were added to refs/heads/master by this push:
new 9291db9d Render vars builtin as an HTML name-value table (#3413)
9291db9d is described below
commit 9291db9d6d2ad19ead25ef09f4f3702b22e68c25
Author: darion-yaphet <[email protected]>
AuthorDate: Thu Sep 3 14:10:35 2026 +0800
Render vars builtin as an HTML name-value table (#3413)
* fix(vars): render /vars as an HTML name-value table
Replace the plain paragraph list with a gridtable so variable
names and values align in columns, and keep expandable flot
charts in a dedicated detail row.
* test(vars): prevent HTML table rendering regressions
Cover HTML responses triggered by a User-Agent, including the grid table,
variable row, and expandable detail row. Preserve plain-text output coverage.
Constraint: HTML mode is selected by the User-Agent header
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Update both rendering-mode assertions when changing VarsService
markup
Tested: BuiltinServiceTest.vars
Not-tested: Full suite; the default C++0x test configuration is
incompatible with local GoogleTest 1.17
---
src/brpc/builtin/vars_service.cpp | 37 +++++++++++++++++++++++-----------
test/brpc_builtin_service_unittest.cpp | 24 +++++++++++++++++++---
2 files changed, 46 insertions(+), 15 deletions(-)
diff --git a/src/brpc/builtin/vars_service.cpp
b/src/brpc/builtin/vars_service.cpp
index 007b0404..473b370e 100644
--- a/src/brpc/builtin/vars_service.cpp
+++ b/src/brpc/builtin/vars_service.cpp
@@ -45,6 +45,7 @@ namespace brpc {
void PutVarsHeading(std::ostream& os, bool expand_all) {
os << "<script language=\"javascript\" type=\"text/javascript\"
src=\"/js/jquery_min\"></script>\n"
"<script language=\"javascript\" type=\"text/javascript\"
src=\"/js/flot_min\"></script>\n"
+ << gridtable_style()
<< TabsHead()
<< "<style type=\"text/css\">\n"
"#layer1 { margin:0; padding:0; width:1111px; }\n"
@@ -66,6 +67,9 @@ void PutVarsHeading(std::ostream& os, bool expand_all) {
"}\n"
// style of <p>
"p {padding: 2px 0; margin: 0px; }\n"
+ ".detail-row td {\n"
+ " padding:0px;\n"
+ "}\n"
// style of container of flot graph.
".detail {\n"
" margin: 0px;\n"
@@ -93,13 +97,13 @@ void PutVarsHeading(std::ostream& os, bool expand_all) {
"function prepareGraphs() {\n"
// Hide all graphs at first.
- " $(\".detail\").hide();\n"
+ " $(\".detail-row\").hide();\n"
// Register clicking functions.
" $(\".variable\").click(function() {\n"
- " var mod = $(this).next(\".detail\");\n"
+ " var mod = $(this).next(\".detail-row\");\n"
" mod.slideToggle(\"fast\");\n"
- " var var_name = mod.children(\":first-child\").attr(\"id\");\n"
+ " var var_name =
mod.find(\".detail\").children(\":first-child\").attr(\"id\");\n"
" if (!everEnabled[var_name]) {\n"
" everEnabled[var_name] = true;\n"
// Create tooltip at first click.
@@ -272,21 +276,24 @@ public:
name, _os, series_options);
plot = (rc == 0);
if (plot) {
- _os << "<p class=\"variable\">";
+ _os << "<tr class=\"variable\">";
} else {
- _os << "<p class=\"nonplot-variable\">";
+ _os << "<tr class=\"nonplot-variable\">";
}
}
- _os << name << VAR_SEP;
if (_use_html) {
- _os << "<span id=\"value-" << name << "\">";
+ _os << "<td>" << name << "</td><td><span id=\"value-" << name <<
"\">";
+ } else {
+ _os << name << VAR_SEP;
}
_os << desc;
if (_use_html) {
- _os << "</span></p>\n";
+ _os << "</span></td></tr>\n";
if (plot) {
- _os << "<div class=\"detail\"><div id=\"" << name
- << "\" class=\"flot-placeholder\"></div></div>\n";
+ _os << "<tr class=\"detail-row\"><td colspan=\"2\">"
+ "<div class=\"detail\"><div id=\"" << name
+ << "\" class=\"flot-placeholder\"></div></div>"
+ "</td></tr>\n";
}
} else {
_os << "\r\n";
@@ -369,7 +376,7 @@ void
VarsService::default_method(::google::protobuf::RpcController* cntl_base,
" enabled = {};\n"
" everEnabled = {};\n"
" }\n"
- " $(\".detail\").hide();\n"
+ " $(\".detail-row\").hide();\n"
" $('#layer1').html(data);\n"
" prepareGraphs();\n"
" window.history.pushState('', '', toURL(searchText));\n"
@@ -406,7 +413,10 @@ void
VarsService::default_method(::google::protobuf::RpcController* cntl_base,
os << "<p>Search : <input id='searchbox' type='text'"
" onkeyup='onQueryChanged()'></p>"
"<div id=\"layer1\">\n";
- }
+ }
+ if (use_html) {
+ os << "<table class=\"gridtable\"
border=\"1\"><tr><th>Name</th><th>Value</th></tr>\n";
+ }
VarsDumper dumper(os, use_html);
bvar::DumpOptions options;
options.question_mark = '$';
@@ -422,6 +432,9 @@ void
VarsService::default_method(::google::protobuf::RpcController* cntl_base,
cntl->SetFailed(ENOMETHOD, "Fail to find any bvar by `%s'",
options.white_wildcards.c_str());
}
+ if (use_html) {
+ os << "</table>";
+ }
if (with_tabs) {
os << "</div></body></html>";
}
diff --git a/test/brpc_builtin_service_unittest.cpp
b/test/brpc_builtin_service_unittest.cpp
index e4f61e70..e496c05f 100644
--- a/test/brpc_builtin_service_unittest.cpp
+++ b/test/brpc_builtin_service_unittest.cpp
@@ -697,15 +697,33 @@ TEST_F(BuiltinServiceTest, vars) {
brpc::VarsService service;
brpc::VarsRequest req;
brpc::VarsResponse res;
+ bvar::Adder<int64_t> myvar;
+ myvar.expose("myvar");
+ myvar << 9;
{
ClosureChecker done;
brpc::Controller cntl;
- bvar::Adder<int64_t> myvar;
- myvar.expose("myvar");
- myvar << 9;
service.default_method(&cntl, &req, &res, &done);
EXPECT_FALSE(cntl.Failed());
+ EXPECT_EQ("text/plain", cntl.http_response().content_type());
CheckFieldInContent(cntl, "myvar : ", 9);
+ EXPECT_EQ(std::string::npos,
+ cntl.response_attachment().to_string().find("<table"));
+ }
+ {
+ ClosureChecker done;
+ brpc::Controller cntl;
+ SetUpController(&cntl, true);
+ cntl.http_request()._unresolved_path = "myvar";
+ service.default_method(&cntl, &req, &res, &done);
+ EXPECT_FALSE(cntl.Failed());
+ EXPECT_EQ("text/html", cntl.http_response().content_type());
+ CheckContent(cntl,
+ "<table class=\"gridtable\"
border=\"1\"><tr><th>Name</th><th>Value</th></tr>");
+ CheckContent(cntl,
+ "<tr class=\"variable\"><td>myvar</td><td><span
id=\"value-myvar\">9</span></td></tr>");
+ CheckContent(cntl,
+ "<tr class=\"detail-row\"><td colspan=\"2\"><div
class=\"detail\"><div id=\"myvar\"
class=\"flot-placeholder\"></div></div></td></tr>");
}
{
ClosureChecker done;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]