diff --git a/clang-tools-extra/clangd/index/remote/Service.proto b/clang-tools-extra/clangd/index/remote/Service.proto --- a/clang-tools-extra/clangd/index/remote/Service.proto +++ b/clang-tools-extra/clangd/index/remote/Service.proto @@ -10,8 +10,11 @@ package clang.clangd.remote.v1; +import "google/protobuf/empty.proto"; import "Index.proto"; +message MonitoringInfoReply { optional string info = 1; } + // Semantics of SymbolIndex match clangd::SymbolIndex with all required // structures corresponding to their clangd::* counterparts. service SymbolIndex { @@ -22,5 +25,7 @@ rpc Refs(RefsRequest) returns (stream RefsReply) {} rpc Relations(RelationsRequest) returns (stream RelationsReply) {} + + rpc MonitoringInfo(google.protobuf.Empty) returns (MonitoringInfoReply) {} } diff --git a/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt --- a/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt +++ b/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt @@ -17,4 +17,6 @@ RemoteIndexProto RemoteIndexServiceProto clangdRemoteMarshalling + + grpc++_reflection ) diff --git a/clang-tools-extra/clangd/index/remote/server/Server.cpp b/clang-tools-extra/clangd/index/remote/server/Server.cpp --- a/clang-tools-extra/clangd/index/remote/server/Server.cpp +++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp @@ -30,6 +30,7 @@ #include "llvm/Support/VirtualFileSystem.h" #include +#include #include #include #include @@ -90,7 +91,7 @@ class RemoteIndexServer final : public v1::SymbolIndex::Service { public: RemoteIndexServer(clangd::SymbolIndex &Index, llvm::StringRef IndexRoot) - : Index(Index) { + : Index(Index), ServiceStartTime(std::chrono::system_clock::now()) { llvm::SmallString<256> NativePath = IndexRoot; llvm::sys::path::native(NativePath); ProtobufMarshaller = std::unique_ptr(new Marshaller( @@ -279,8 +280,23 @@ Millis); } + grpc::Status MonitoringInfo(grpc::ServerContext *Context, + const google::protobuf::Empty *Request, + v1::MonitoringInfoReply *Reply) override { + auto Uptime = std::chrono::duration_cast( + std::chrono::system_clock::now() - ServiceStartTime) + .count(); + Reply->set_info(llvm::formatv( + "Service started at {0:%Y-%m-%d %H:%M:%S}. Uptime: {1} h {2} m.", + ServiceStartTime, Uptime / 60, Uptime % 60)); + logRequest(*Request); + logResponse(*Reply); + return grpc::Status::OK; + } + std::unique_ptr ProtobufMarshaller; clangd::SymbolIndex &Index; + llvm::sys::TimePoint<> ServiceStartTime; }; // Detect changes in \p IndexPath file and load new versions of the index @@ -313,6 +329,7 @@ RemoteIndexServer Service(Index, IndexRoot); grpc::EnableDefaultHealthCheckService(true); + grpc::reflection::InitProtoReflectionServerBuilderPlugin(); grpc::ServerBuilder Builder; Builder.AddListeningPort(ServerAddress.str(), grpc::InsecureServerCredentials()); diff --git a/llvm/cmake/modules/FindGRPC.cmake b/llvm/cmake/modules/FindGRPC.cmake --- a/llvm/cmake/modules/FindGRPC.cmake +++ b/llvm/cmake/modules/FindGRPC.cmake @@ -22,6 +22,8 @@ add_library(protobuf ALIAS protobuf::libprotobuf) set_target_properties(gRPC::grpc++ PROPERTIES IMPORTED_GLOBAL TRUE) add_library(grpc++ ALIAS gRPC::grpc++) + set_target_properties(gRPC::grpc++_reflection PROPERTIES IMPORTED_GLOBAL TRUE) + add_library(grpc++_reflection ALIAS gRPC::grpc++_reflection) set(GRPC_CPP_PLUGIN $) set(PROTOC ${Protobuf_PROTOC_EXECUTABLE}) @@ -71,6 +73,9 @@ add_library(grpc++ UNKNOWN IMPORTED GLOBAL) message(STATUS "Using grpc++: " ${GRPC_LIBRARY}) set_target_properties(grpc++ PROPERTIES IMPORTED_LOCATION ${GRPC_LIBRARY}) + find_library(GRPC_REFLECTION_LIBRARY grpc++_reflection $GRPC_OPTS REQUIRED) + add_library(grpc++_reflection UNKNOWN IMPORTED GLOBAL) + set_target_properties(grpc++_reflection PROPERTIES IMPORTED_LOCATION ${GRPC_REFLECTION_LIBRARY}) find_library(PROTOBUF_LIBRARY protobuf $PROTOBUF_OPTS REQUIRED) message(STATUS "Using protobuf: " ${PROTOBUF_LIBRARY}) add_library(protobuf UNKNOWN IMPORTED GLOBAL)