Skip to content

Commit bf0eb13

Browse files
authored
Add traffic_ctl hostdb status (#12603)
* Add traffic_ctl hostdb status * Fix descriptions * Set default string to UNKNOWN * Cleanup * Remove default for HostDBType * Fix return-type error
1 parent 24551fe commit bf0eb13

13 files changed

Lines changed: 412 additions & 2 deletions

File tree

doc/appendices/command-line/traffic_ctl.en.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ of subcommands that control different aspects of Traffic Server:
5252
:program:`traffic_ctl plugin`
5353
Interact with plugins.
5454
:program:`traffic_ctl host`
55-
Manipulate host status. parents for now but will be expanded to origins.
55+
Manipulate host status.
56+
:program:`traffic_ctl hostdb`
57+
Manipulate HostDB status.
5658
:program:`traffic_ctl rpc`
5759
Interact directly with the |RPC| server in |TS|
5860

@@ -560,6 +562,16 @@ records may be viewed using the :program:`traffic_ctl host status` command.
560562

561563
.. _traffic_ctl_rpc:
562564

565+
traffic_ctl hostdb
566+
------------------
567+
.. program:: traffic_ctl hostdb
568+
569+
.. option:: status
570+
571+
:ref:`admin_lookup_records`
572+
573+
Get the current status of HostDB.
574+
563575
traffic_ctl rpc
564576
---------------
565577
.. program:: traffic_ctl rpc

include/iocore/hostdb/HostDBProcessor.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ class HostDBRecord : public RefCountObj
393393
/// Get the array of info instances.
394394
swoc::MemSpan<HostDBInfo> rr_info();
395395

396+
/// Get the array of info instances to read
397+
swoc::MemSpan<const HostDBInfo> rr_info() const;
398+
396399
/** Find a host record by IP address.
397400
*
398401
* @param addr Address key.
@@ -784,6 +787,12 @@ HostDBRecord::rr_info()
784787
return {this->apply_offset<HostDBInfo>(rr_offset), rr_count};
785788
}
786789

790+
inline swoc::MemSpan<const HostDBInfo>
791+
HostDBRecord::rr_info() const
792+
{
793+
return {this->apply_offset<const HostDBInfo>(rr_offset), rr_count};
794+
}
795+
787796
inline bool
788797
HostDBRecord::is_failed() const
789798
{
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* @file
2+
@section license License
3+
4+
Licensed to the Apache Software Foundation (ASF) under one
5+
or more contributor license agreements. See the NOTICE file
6+
distributed with this work for additional information
7+
regarding copyright ownership. The ASF licenses this file
8+
to you under the Apache License, Version 2.0 (the
9+
"License"); you may not use this file except in compliance
10+
with the License. You may obtain a copy of the License at
11+
12+
http://www.apache.org/licenses/LICENSE-2.0
13+
14+
Unless required by applicable law or agreed to in writing, software
15+
distributed under the License is distributed on an "AS IS" BASIS,
16+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
See the License for the specific language governing permissions and
18+
limitations under the License.
19+
*/
20+
21+
#pragma once
22+
23+
#include "mgmt/rpc/jsonrpc/JsonRPCManager.h"
24+
25+
namespace rpc::handlers::hostdb
26+
{
27+
swoc::Rv<YAML::Node> get_hostdb_status(std::string_view const &id, YAML::Node const &);
28+
} // namespace rpc::handlers::hostdb

src/mgmt/rpc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ add_library(
4242
handlers/common/ErrorUtils.cc
4343
handlers/common/RecordsUtils.cc
4444
handlers/config/Configuration.cc
45+
handlers/hostdb/HostDB.cc
4546
handlers/records/Records.cc
4647
handlers/storage/Storage.cc
4748
handlers/server/Server.cc
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/**
2+
@section license License
3+
4+
Licensed to the Apache Software Foundation (ASF) under one
5+
or more contributor license agreements. See the NOTICE file
6+
distributed with this work for additional information
7+
regarding copyright ownership. The ASF licenses this file
8+
to you under the Apache License, Version 2.0 (the
9+
"License"); you may not use this file except in compliance
10+
with the License. You may obtain a copy of the License at
11+
12+
http://www.apache.org/licenses/LICENSE-2.0
13+
14+
Unless required by applicable law or agreed to in writing, software
15+
distributed under the License is distributed on an "AS IS" BASIS,
16+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
See the License for the specific language governing permissions and
18+
limitations under the License.
19+
*/
20+
21+
#include "mgmt/rpc/handlers/hostdb/HostDB.h"
22+
#include "mgmt/rpc/handlers/common/ErrorUtils.h"
23+
24+
#include "iocore/hostdb/HostDBProcessor.h"
25+
#include "../src/iocore/hostdb/P_HostDBProcessor.h"
26+
#include "swoc/MemSpan.h"
27+
#include "tsutil/TsSharedMutex.h"
28+
#include "yaml-cpp/node/node.h"
29+
#include <shared_mutex>
30+
#include <string>
31+
32+
namespace
33+
{
34+
DbgCtl dbg_ctl_rpc_server{"rpc.server"};
35+
DbgCtl dbg_ctl_rpc_handler_server{"rpc.handler.hostdb"};
36+
37+
constexpr std::string_view
38+
str(HostDBType type)
39+
{
40+
// No default to find HostDBType change
41+
switch (type) {
42+
case HostDBType::ADDR:
43+
return "ADDR";
44+
case HostDBType::SRV:
45+
return "SRV";
46+
case HostDBType::HOST:
47+
return "HOST";
48+
case HostDBType::UNSPEC:
49+
return "UNSPEC";
50+
}
51+
52+
return "";
53+
}
54+
55+
constexpr std::string_view
56+
str(sa_family_t type)
57+
{
58+
switch (type) {
59+
case AF_UNIX:
60+
return "AF_UNIX";
61+
case AF_INET:
62+
return "AF_INET";
63+
case AF_INET6:
64+
return "AF_INET6";
65+
case AF_UNSPEC:
66+
return "UNSPEC";
67+
default:
68+
return "UNKNOWN";
69+
}
70+
}
71+
} // end anonymous namespace
72+
73+
namespace YAML
74+
{
75+
template <> struct convert<HostDBCache> {
76+
static Node
77+
encode(const HostDBCache *const hostDB)
78+
{
79+
Node partitions;
80+
for (size_t i = 0; i < hostDB->refcountcache->partition_count(); i++) {
81+
auto &partition = hostDB->refcountcache->get_partition(i);
82+
std::vector<RefCountCacheHashEntry *> partition_entries;
83+
84+
{
85+
std::shared_lock<ts::shared_mutex> shared_lock{partition.lock};
86+
partition_entries.reserve(partition.count());
87+
partition.copy(partition_entries);
88+
}
89+
90+
Node partition_node;
91+
partition_node["id"] = i;
92+
93+
for (RefCountCacheHashEntry *entry : partition_entries) {
94+
HostDBRecord *record = static_cast<HostDBRecord *>(entry->item.get());
95+
partition_node["records"].push_back(*record);
96+
}
97+
98+
partitions.push_back(partition_node);
99+
}
100+
101+
auto &version = AppVersionInfo::get_version();
102+
103+
Node node;
104+
node["metadata"]["timestamp"] =
105+
std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
106+
node["metadata"]["version"] = version.full_version();
107+
node["partitions"] = partitions;
108+
109+
return node;
110+
}
111+
};
112+
113+
template <> struct convert<HostDBRecord> {
114+
static Node
115+
encode(const HostDBRecord &record)
116+
{
117+
Node metadata;
118+
metadata["name"] = record.name();
119+
metadata["type"] = str(record.record_type);
120+
metadata["af_familiy"] = str(record.af_family);
121+
metadata["failed"] = record.is_failed();
122+
metadata["ip_timestamp"] = record.ip_timestamp.time_since_epoch().count();
123+
124+
Node node;
125+
node["metadata"] = metadata;
126+
127+
swoc::MemSpan<const HostDBInfo> span = record.rr_info();
128+
for (const HostDBInfo &info : span) {
129+
YAML::Node info_node;
130+
if (record.is_srv()) {
131+
YAML::Node srv_node;
132+
srv_node["weight"] = info.data.srv.srv_weight;
133+
srv_node["priority"] = info.data.srv.srv_priority;
134+
srv_node["port"] = info.data.srv.srv_port;
135+
srv_node["target"] = info.srvname();
136+
137+
info_node["srv"] = srv_node;
138+
} else {
139+
char buf[INET6_ADDRSTRLEN];
140+
info.data.ip.toString(buf, sizeof(buf));
141+
142+
info_node["ip"] = std::string(buf);
143+
}
144+
145+
info_node["health"]["last_failure"] = info.last_failure.load().time_since_epoch().count();
146+
info_node["health"]["fail_count"] = static_cast<int>(info.fail_count.load());
147+
148+
node["info"].push_back(info_node);
149+
}
150+
151+
return node;
152+
}
153+
};
154+
} // namespace YAML
155+
156+
namespace rpc::handlers::hostdb
157+
{
158+
namespace err = rpc::handlers::errors;
159+
160+
swoc::Rv<YAML::Node>
161+
get_hostdb_status(std::string_view const & /* params ATS_UNUSED */, YAML::Node const & /* params ATS_UNUSED */)
162+
{
163+
swoc::Rv<YAML::Node> resp;
164+
try {
165+
YAML::Node data = YAML::convert<HostDBCache>::encode(hostDBProcessor.cache());
166+
167+
resp.result()["data"] = data;
168+
} catch (std::exception const &ex) {
169+
resp.errata()
170+
.assign(std::error_code{errors::Codes::SERVER})
171+
.note("Error found when calling get_hostdb_status API: {}", ex.what());
172+
}
173+
return resp;
174+
}
175+
} // namespace rpc::handlers::hostdb
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "HostDB info definition",
4+
"description":"This is the definition expected for a RPC hostdb status request. This should be used to obtain information of HostDB from Traffic Server Licensed under Apache V2 https://www.apache.org/licenses/LICENSE-2.0",
5+
"type": "object",
6+
"properties": {
7+
"metadata": {
8+
"type": "object",
9+
"properties": {
10+
"timestamp": {
11+
"type": "integer"
12+
},
13+
"version": {
14+
"type": "string"
15+
}
16+
}
17+
},
18+
"partitions": {
19+
"type": "array",
20+
"items": {
21+
"type": "object",
22+
"properties": {
23+
"id": {
24+
"type": "integer",
25+
"description": "Partition identifier"
26+
},
27+
"records": {
28+
"type": "array",
29+
"items": {
30+
"type": "object",
31+
"properties": {
32+
"metadata": {
33+
"type": "object",
34+
"properties": {
35+
"type": {
36+
"type": "string",
37+
"enum": ["UNSPEC", "ADDR", "SRV", "HOST"]
38+
},
39+
"af_family": {
40+
"type": "string",
41+
"enum": ["UNSPEC", "UNIX", "AF_INET", "AF_INET6"]
42+
},
43+
"name": {
44+
"type": "string",
45+
"description": "Query hostname or resolved name"
46+
},
47+
"failed": {
48+
"type": "boolean"
49+
},
50+
"ip_timestamp": {
51+
"type": "integer"
52+
}
53+
}
54+
},
55+
"info": {
56+
"type": "array",
57+
"items": {
58+
"type": "object",
59+
"properties": {
60+
"data": {
61+
"oneOf": [
62+
{
63+
"type": "object",
64+
"properties": {
65+
"ip": {
66+
"type": "string"
67+
}
68+
}
69+
},
70+
{
71+
"type": "object",
72+
"properties": {
73+
"srv": {
74+
"type": "object",
75+
"properties": {
76+
"weight": {
77+
"type": "integer"
78+
},
79+
"priority": {
80+
"type": "integer"
81+
},
82+
"port": {
83+
"type": "integer"
84+
},
85+
"target": {
86+
"type": "string"
87+
}
88+
}
89+
}
90+
}
91+
}
92+
]
93+
},
94+
"health": {
95+
"type": "object",
96+
"properties": {
97+
"last_failure": {
98+
"type": "integer"
99+
},
100+
"fail_count": {
101+
"type": "integer"
102+
}
103+
}
104+
}
105+
}
106+
}
107+
}
108+
}
109+
}
110+
}
111+
}
112+
}
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)