Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add hardware information of server as an attribute #5090

Merged
1 change: 1 addition & 0 deletions dbms/src/Server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ add_library (clickhouse-server-lib
NotFoundHandler.cpp
PingRequestHandler.cpp
RootRequestHandler.cpp
ServerInfo.cpp
Server.cpp
StatusFile.cpp
TCPHandler.cpp
Expand Down
29 changes: 24 additions & 5 deletions dbms/src/Server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <Poco/StringTokenizer.h>
#include <Poco/Timestamp.h>
#include <Server/RaftConfigParser.h>
#include <Server/ServerInfo.h>
#include <Server/StorageConfigParser.h>
#include <Server/UserConfigParser.h>
#include <Storages/FormatVersion.h>
Expand All @@ -72,7 +73,6 @@
#include <WindowFunctions/registerWindowFunctions.h>
#include <common/ErrorHandlers.h>
#include <common/config_common.h>
#include <common/getMemoryAmount.h>
#include <common/logger_useful.h>
#include <sys/resource.h>

Expand Down Expand Up @@ -1049,6 +1049,25 @@ int Server::main(const std::vector<std::string> & /*args*/)
LOG_FMT_INFO(log, "tiflash proxy thread is joined");
});

/// get server info.
Lloyd-Pottiger marked this conversation as resolved.
Show resolved Hide resolved
{
diagnosticspb::ServerInfoRequest request;
request.set_tp(static_cast<diagnosticspb::ServerInfoType>(1));
diagnosticspb::ServerInfoResponse response;
auto * helper = tiflash_instance_wrap.proxy_helper;
if (helper)
Lloyd-Pottiger marked this conversation as resolved.
Show resolved Hide resolved
{
std::string req = request.SerializeAsString();
helper->fn_server_info(helper->proxy_ptr, strIntoView(&req), &response);
}
else
{
LOG_FMT_INFO(log, "TiFlashRaftProxyHelper is null, failed to get server info");
}
server_info.parseSysInfo(response);
LOG_FMT_INFO(log, "ServerInfo: {}", server_info.debugString());
Lloyd-Pottiger marked this conversation as resolved.
Show resolved Hide resolved
}

CurrentMetrics::set(CurrentMetrics::Revision, ClickHouseRevision::get());

// print necessary grpc log.
Expand Down Expand Up @@ -1410,10 +1429,10 @@ int Server::main(const std::vector<std::string> & /*args*/)
// on ARM processors it can show only enabled at current moment cores
LOG_FMT_INFO(
log,
"Available RAM = {}; physical cores = {}; threads = {}.",
formatReadableSizeWithBinarySuffix(getMemoryAmount()),
getNumberOfPhysicalCPUCores(),
std::thread::hardware_concurrency());
"Available RAM = {}; physical cores = {}; logical cores = {}.",
server_info.memory_info.capacity,
server_info.cpu_info.physical_cores,
server_info.cpu_info.logical_cores);
}

LOG_FMT_INFO(log, "Ready for connections.");
Expand Down
10 changes: 7 additions & 3 deletions dbms/src/Server/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

#pragma once

#include <Server/IServer.h>
#include <Server/ServerInfo.h>
#include <daemon/BaseDaemon.h>

#include "IServer.h"

/** Server provides three interfaces:
* 1. HTTP - simple interface for any applications.
* 2. TCP - interface for native clickhouse-client and for server to server internal communications.
Expand All @@ -39,7 +39,7 @@ class Server : public BaseDaemon
return BaseDaemon::config();
}

virtual const TiFlashSecurityConfig & securityConfig() const override { return security_config; };
const TiFlashSecurityConfig & securityConfig() const override { return security_config; };

Poco::Logger & logger() const override
{
Expand All @@ -56,6 +56,8 @@ class Server : public BaseDaemon
return BaseDaemon::isCancelled();
}

ServerInfo getServerInfo() { return server_info; };

Lloyd-Pottiger marked this conversation as resolved.
Show resolved Hide resolved
protected:
void initialize(Application & self) override;

Expand All @@ -70,6 +72,8 @@ class Server : public BaseDaemon

TiFlashSecurityConfig security_config;

ServerInfo server_info;

class FlashGrpcServerHolder;
class TcpHttpServersHolder;
};
Expand Down
184 changes: 184 additions & 0 deletions dbms/src/Server/ServerInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// Copyright 2022 PingCAP, Ltd.
//
// Licensed 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 <Common/FmtUtils.h>
#include <Server/ServerInfo.h>

#include <unordered_map>

namespace DB
{
using diagnosticspb::ServerInfoItem;
using diagnosticspb::ServerInfoResponse;

void ServerInfo::parseCPUInfo(const diagnosticspb::ServerInfoItem & cpu_info_item)
{
for (const auto & pair : cpu_info_item.pairs())
{
if (pair.key() == "cpu-logical-cores")
{
cpu_info.logical_cores = static_cast<UInt16>(std::stoi(pair.value()));
}
else if (pair.key() == "cpu-physical-cores")
{
cpu_info.physical_cores = static_cast<UInt16>(std::stoi(pair.value()));
}
else if (pair.key() == "cpu-frequency")
{
cpu_info.frequency = pair.value();
}
else if (pair.key() == "l1-cache-size")
{
cpu_info.l1_cache_size = static_cast<UInt32>(std::stoull(pair.value()));
}
else if (pair.key() == "l1-cache-line-size")
{
cpu_info.l1_cache_line_size = static_cast<UInt8>(std::stoi(pair.value()));
}
else if (pair.key() == "l2-cache-size")
{
cpu_info.l2_cache_size = static_cast<UInt32>(std::stoull(pair.value()));
}
else if (pair.key() == "l2-cache-line-size")
{
cpu_info.l2_cache_line_size = static_cast<UInt8>(std::stoi(pair.value()));
}
else if (pair.key() == "l3-cache-size")
{
cpu_info.l3_cache_size = static_cast<UInt32>(std::stoull(pair.value()));
}
else if (pair.key() == "l3-cache-line-size")
{
cpu_info.l3_cache_line_size = static_cast<UInt8>(std::stoi(pair.value()));
}
else if (pair.key() == "cpu-arch")
{
cpu_info.arch = pair.value();
}
}
}

void ServerInfo::parseDiskInfo(const diagnosticspb::ServerInfoItem & disk_info_item)
{
Disk disk;
disk.name = disk_info_item.name();
for (const auto & pair : disk_info_item.pairs())
{
if (pair.key() == "type")
{
std::unordered_map<String, Disk::DiskType> disk_type_map = {
{"hdd", Disk::DiskType::HDD},
{"ssd", Disk::DiskType::SSD},
{"unknown", Disk::DiskType::UNKNOWN}};
disk.disk_type = disk_type_map[pair.value()];
Lloyd-Pottiger marked this conversation as resolved.
Show resolved Hide resolved
}
else if (pair.key() == "total")
{
disk.total_space = static_cast<UInt64>(std::stoull(pair.value()));
}
else if (pair.key() == "free")
{
disk.free_space = static_cast<UInt64>(std::stoull(pair.value()));
}
else if (pair.key() == "path")
{
disk.mount_point = pair.value();
}
else if (pair.key() == "fstype")
{
disk.fs_type = pair.value();
}
}
disk_infos.push_back(disk);
}

void ServerInfo::parseMemoryInfo(const diagnosticspb::ServerInfoItem & memory_info_item)
{
for (const auto & pair : memory_info_item.pairs())
{
if (pair.key() == "capacity")
{
memory_info.capacity = std::stoull(pair.value());
}
}
}

void ServerInfo::parseSysInfo(diagnosticspb::ServerInfoResponse & sys_info_response)
Lloyd-Pottiger marked this conversation as resolved.
Show resolved Hide resolved
{
for (const auto & item : sys_info_response.items())
{
if (item.tp() == "cpu")
{
parseCPUInfo(item);
}
else if (item.tp() == "disk")
{
parseDiskInfo(item);
}
else if (item.tp() == "memory")
{
parseMemoryInfo(item);
}
}
}

String ServerInfo::debugString() const
{
FmtBuffer fmt_buf;
fmt_buf.fmtAppend("CPU: \n"
" logical_cores: {}\n"
JinheLin marked this conversation as resolved.
Show resolved Hide resolved
" physical_cores: {}\n"
" frequency: {}\n"
" l1_cache_size: {}\n"
" l1_cache_line_size: {}\n"
" l2_cache_size: {}\n"
" l2_cache_line_size: {}\n"
" l3_cache_size: {}\n"
" l3_cache_line_size: {}\n"
" arch: {}\n",
cpu_info.logical_cores,
cpu_info.physical_cores,
cpu_info.frequency,
cpu_info.l1_cache_size,
cpu_info.l1_cache_line_size,
cpu_info.l2_cache_size,
cpu_info.l2_cache_line_size,
cpu_info.l3_cache_size,
cpu_info.l3_cache_line_size,
cpu_info.arch);

for (const auto & disk_info : disk_infos)
{
fmt_buf.fmtAppend("Disk: \n"
Lloyd-Pottiger marked this conversation as resolved.
Show resolved Hide resolved
" name: {}\n"
" type: {}\n"
" total_space: {}\n"
" free_space: {}\n"
" mount_point: {}\n"
" fs_type: {}\n",
disk_info.name,
disk_info.disk_type,
disk_info.total_space,
disk_info.free_space,
disk_info.mount_point,
disk_info.fs_type);
}
fmt_buf.fmtAppend("Memory: \n"
" capacity: {}\n",
memory_info.capacity);

return fmt_buf.toString();
}

} // namespace DB
96 changes: 96 additions & 0 deletions dbms/src/Server/ServerInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2022 PingCAP, Ltd.
//
// Licensed 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.

#pragma once
#include <common/types.h>

#include <vector>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <kvproto/diagnosticspb.grpc.pb.h>
#pragma GCC diagnostic pop

namespace DB
{
class ServerInfo
{
public:
struct CPUInfo
{
/// number of logical CPU cores
UInt16 logical_cores{};
/// number of physical CPU cores
UInt16 physical_cores{};
JaySon-Huang marked this conversation as resolved.
Show resolved Hide resolved
/// number of L1 cache size
/// units: Byte
UInt32 l1_cache_size{};
/// number of L2 cache size
/// units: Byte
UInt32 l2_cache_size{};
/// number of L3 cache size
/// units: Byte
UInt32 l3_cache_size{};
/// number of L1 cache line size
UInt8 l1_cache_line_size{};
/// number of L2 cache line size
UInt8 l2_cache_line_size{};
/// number of L3 cache line size
UInt8 l3_cache_line_size{};
/// CPU architecture
String arch;
/// CPU frequency
String frequency;
};

struct Disk
{
String name;
enum DiskType
{
HDD,
SSD,
UNKNOWN
};
DiskType disk_type;
UInt64 total_space;
Lloyd-Pottiger marked this conversation as resolved.
Show resolved Hide resolved
UInt64 free_space;
String mount_point;
String fs_type;
};
using DiskInfo = std::vector<Disk>;

struct MemoryInfo
{
/// total memory size
/// units: Byte
UInt64 capacity;
};

ServerInfo() = default;
~ServerInfo() = default;
void parseCPUInfo(const diagnosticspb::ServerInfoItem & cpu_info_item);
void parseDiskInfo(const diagnosticspb::ServerInfoItem & disk_info_item);
void parseMemoryInfo(const diagnosticspb::ServerInfoItem & memory_info_item);
void parseSysInfo(diagnosticspb::ServerInfoResponse & sys_info_response);
String debugString() const;

CPUInfo cpu_info;
DiskInfo disk_infos;
MemoryInfo memory_info{};
};
} // namespace DB