]>
git.proxmox.com Git - ceph.git/blob - ceph/src/mgr/ServiceMap.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "mgr/ServiceMap.h"
6 #include <fmt/format.h>
8 #include "common/Formatter.h"
10 using ceph::bufferlist
;
11 using ceph::Formatter
;
15 void ServiceMap::Daemon::encode(bufferlist
& bl
, uint64_t features
) const
17 ENCODE_START(2, 1, bl
);
19 encode(addr
, bl
, features
);
20 encode(start_epoch
, bl
);
21 encode(start_stamp
, bl
);
23 encode(task_status
, bl
);
27 void ServiceMap::Daemon::decode(bufferlist::const_iterator
& p
)
32 decode(start_epoch
, p
);
33 decode(start_stamp
, p
);
36 decode(task_status
, p
);
41 void ServiceMap::Daemon::dump(Formatter
*f
) const
43 f
->dump_unsigned("start_epoch", start_epoch
);
44 f
->dump_stream("start_stamp") << start_stamp
;
45 f
->dump_unsigned("gid", gid
);
46 f
->dump_string("addr", addr
.get_legacy_str());
47 f
->open_object_section("metadata");
48 for (auto& p
: metadata
) {
49 f
->dump_string(p
.first
.c_str(), p
.second
);
52 f
->open_object_section("task_status");
53 for (auto& p
: task_status
) {
54 f
->dump_string(p
.first
.c_str(), p
.second
);
59 void ServiceMap::Daemon::generate_test_instances(std::list
<Daemon
*>& ls
)
61 ls
.push_back(new Daemon
);
62 ls
.push_back(new Daemon
);
64 ls
.back()->metadata
["this"] = "that";
65 ls
.back()->task_status
["task1"] = "running";
70 std::string
ServiceMap::Service::get_summary() const
72 if (!summary
.empty()) {
75 if (daemons
.empty()) {
76 return "no daemons active";
79 // If "daemon_type" is present, this will be used in place of "daemon" when
80 // reporting the count (e.g., "${N} daemons").
82 // We will additional break down the count by various groupings, based
83 // on the following keys:
85 // "hostname" -> host(s)
86 // "zone_id" -> zone(s)
88 // The `ceph -s` will be something likes:
89 // iscsi: 3 portals active (3 hosts)
90 // rgw: 3 gateways active (3 hosts, 1 zone)
92 std::map
<std::string
, std::set
<std::string
>> groupings
;
93 std::string
type("daemon");
95 for (auto& d
: daemons
) {
97 if (auto p
= d
.second
.metadata
.find("daemon_type");
98 p
!= d
.second
.metadata
.end()) {
101 for (auto k
: {std::make_pair("zone", "zone_id"),
102 std::make_pair("host", "hostname")}) {
103 auto p
= d
.second
.metadata
.find(k
.second
);
104 if (p
!= d
.second
.metadata
.end()) {
105 groupings
[k
.first
].insert(p
->second
);
110 std::ostringstream ss
;
111 ss
<< num
<< " " << type
<< (num
> 1 ? "s" : "") << " active";
112 if (groupings
.size()) {
114 for (auto i
= groupings
.begin(); i
!= groupings
.end(); ++i
) {
115 if (i
!= groupings
.begin()) {
118 ss
<< i
->second
.size() << " " << i
->first
<< (i
->second
.size() ? "s" : "");
126 bool ServiceMap::Service::has_running_tasks() const
128 return std::any_of(daemons
.begin(), daemons
.end(), [](auto& daemon
) {
129 return !daemon
.second
.task_status
.empty();
133 std::string
ServiceMap::Service::get_task_summary(const std::string_view task_prefix
) const
135 // contruct a map similar to:
136 // {"service1 status" -> {"service1.0" -> "running"}}
137 // {"service2 status" -> {"service2.0" -> "idle"},
138 // {"service2.1" -> "running"}}
139 std::map
<std::string
, std::map
<std::string
, std::string
>> by_task
;
140 for (const auto& [service_id
, daemon
] : daemons
) {
141 for (const auto& [task_name
, status
] : daemon
.task_status
) {
142 by_task
[task_name
].emplace(fmt::format("{}.{}", task_prefix
, service_id
),
146 std::stringstream ss
;
147 for (const auto &[task_name
, status_by_service
] : by_task
) {
148 ss
<< "\n " << task_name
<< ":";
149 for (auto& [service
, status
] : status_by_service
) {
150 ss
<< "\n " << service
<< ": " << status
;
156 void ServiceMap::Service::count_metadata(const std::string
& field
,
157 std::map
<std::string
,int> *out
) const
159 for (auto& p
: daemons
) {
160 auto q
= p
.second
.metadata
.find(field
);
161 if (q
== p
.second
.metadata
.end()) {
169 void ServiceMap::Service::encode(bufferlist
& bl
, uint64_t features
) const
171 ENCODE_START(1, 1, bl
);
172 encode(daemons
, bl
, features
);
177 void ServiceMap::Service::decode(bufferlist::const_iterator
& p
)
185 void ServiceMap::Service::dump(Formatter
*f
) const
187 f
->open_object_section("daemons");
188 f
->dump_string("summary", summary
);
189 for (auto& p
: daemons
) {
190 f
->dump_object(p
.first
.c_str(), p
.second
);
195 void ServiceMap::Service::generate_test_instances(std::list
<Service
*>& ls
)
197 ls
.push_back(new Service
);
198 ls
.push_back(new Service
);
199 ls
.back()->daemons
["one"].gid
= 1;
200 ls
.back()->daemons
["two"].gid
= 2;
205 void ServiceMap::encode(bufferlist
& bl
, uint64_t features
) const
207 ENCODE_START(1, 1, bl
);
209 encode(modified
, bl
);
210 encode(services
, bl
, features
);
214 void ServiceMap::decode(bufferlist::const_iterator
& p
)
223 void ServiceMap::dump(Formatter
*f
) const
225 f
->dump_unsigned("epoch", epoch
);
226 f
->dump_stream("modified") << modified
;
227 f
->open_object_section("services");
228 for (auto& p
: services
) {
229 f
->dump_object(p
.first
.c_str(), p
.second
);
234 void ServiceMap::generate_test_instances(std::list
<ServiceMap
*>& ls
)
236 ls
.push_back(new ServiceMap
);
237 ls
.push_back(new ServiceMap
);
238 ls
.back()->epoch
= 123;
239 ls
.back()->services
["rgw"].daemons
["one"].gid
= 123;
240 ls
.back()->services
["rgw"].daemons
["two"].gid
= 344;
241 ls
.back()->services
["iscsi"].daemons
["foo"].gid
= 3222;