Add storageInfo
awesome memgraph function
Summary: Added a new awesome function called `storageInfo`. This function returns a list of key-value pairs containing the following (useful?) information: * number of vertices * number of edges * average degree * memory usage * disk usage The current implementation is in `awesome_memgraph_functions` but it will end up as a separate clause for better access control. Reviewers: teon.banek, mtomic, mferencevic Reviewed By: teon.banek Subscribers: pullbot, buda Differential Revision: https://phabricator.memgraph.io/D1850
This commit is contained in:
parent
773acc11d6
commit
1b11e109fa
@ -16,6 +16,7 @@
|
||||
#include "storage/single_node/storage_gc.hpp"
|
||||
#include "transactions/single_node/engine.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
#include "utils/stat.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
@ -27,7 +28,7 @@ struct Stat {
|
||||
|
||||
/// Vertex count is number of `VersionList<Vertex>` physically stored.
|
||||
std::atomic<int64_t> vertex_count{0};
|
||||
|
||||
|
||||
/// Vertex count is number of `VersionList<Edge>` physically stored.
|
||||
std::atomic<int64_t> edge_count{0};
|
||||
|
||||
@ -132,10 +133,15 @@ class GraphDb {
|
||||
if (vertex_count != 0) {
|
||||
stat_.avg_degree = 2 * static_cast<double>(edge_count) / vertex_count;
|
||||
} else {
|
||||
stat_.avg_degree = 0;
|
||||
stat_.avg_degree = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of bytes used by the durability directory on disk.
|
||||
uint64_t GetDurabilityDirDiskUsage() const {
|
||||
return utils::GetDirDiskUsage(config_.durability_directory);
|
||||
}
|
||||
|
||||
protected:
|
||||
Stat stat_;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "storage/single_node/vertex_accessor.hpp"
|
||||
#include "utils/cast.hpp"
|
||||
#include "utils/on_scope_exit.hpp"
|
||||
#include "utils/stat.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
@ -419,4 +420,20 @@ std::vector<std::string> GraphDbAccessor::IndexInfo() const {
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> GraphDbAccessor::StorageInfo() const {
|
||||
std::map<std::string, std::string> info;
|
||||
|
||||
db_.RefreshStat();
|
||||
auto &stat = db_.GetStat();
|
||||
|
||||
info.emplace("vertex_count", std::to_string(stat.vertex_count));
|
||||
info.emplace("edge_count", std::to_string(stat.edge_count));
|
||||
info.emplace("average_degree", std::to_string(stat.avg_degree));
|
||||
info.emplace("memory_usage", std::to_string(utils::GetMemoryUsage()));
|
||||
info.emplace("disk_usage", std::to_string(db_.GetDurabilityDirDiskUsage()));
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace database
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <experimental/optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <cppitertools/filter.hpp>
|
||||
@ -604,6 +605,18 @@ class GraphDbAccessor {
|
||||
/* Returns a list of index names present in the database. */
|
||||
std::vector<std::string> IndexInfo() const;
|
||||
|
||||
/**
|
||||
* Returns a map containing storage information.
|
||||
*
|
||||
* Inside the map, the following keys will exist:
|
||||
* - vertex_count
|
||||
* - edge_count
|
||||
* - average_degree
|
||||
* - memory_usage
|
||||
* - disk_usage
|
||||
**/
|
||||
std::map<std::string, std::string> StorageInfo() const;
|
||||
|
||||
/**
|
||||
* Insert this vertex into corresponding label and label+property (if it
|
||||
* exists) index.
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "storage/single_node_ha/storage_gc.hpp"
|
||||
#include "transactions/single_node_ha/engine.hpp"
|
||||
#include "utils/scheduler.hpp"
|
||||
#include "utils/stat.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
@ -140,6 +141,11 @@ class GraphDb {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of bytes used by the durability directory on disk.
|
||||
uint64_t GetDurabilityDirDiskUsage() const {
|
||||
return utils::GetDirDiskUsage(config_.durability_directory);
|
||||
}
|
||||
|
||||
protected:
|
||||
Stat stat_;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "storage/single_node_ha/vertex_accessor.hpp"
|
||||
#include "utils/cast.hpp"
|
||||
#include "utils/on_scope_exit.hpp"
|
||||
#include "utils/stat.hpp"
|
||||
|
||||
namespace database {
|
||||
|
||||
@ -418,4 +419,20 @@ std::vector<std::string> GraphDbAccessor::IndexInfo() const {
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> GraphDbAccessor::StorageInfo() const {
|
||||
std::map<std::string, std::string> info;
|
||||
|
||||
db_.RefreshStat();
|
||||
auto &stat = db_.GetStat();
|
||||
|
||||
info.emplace("vertex_count", std::to_string(stat.vertex_count));
|
||||
info.emplace("edge_count", std::to_string(stat.edge_count));
|
||||
info.emplace("average_degree", std::to_string(stat.avg_degree));
|
||||
info.emplace("memory_usage", std::to_string(utils::GetMemoryUsage()));
|
||||
info.emplace("disk_usage", std::to_string(db_.GetDurabilityDirDiskUsage()));
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace database
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <experimental/optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <cppitertools/filter.hpp>
|
||||
@ -595,6 +596,18 @@ class GraphDbAccessor {
|
||||
/* Returns a list of index names present in the database. */
|
||||
std::vector<std::string> IndexInfo() const;
|
||||
|
||||
/**
|
||||
* Returns a map containing storage information.
|
||||
*
|
||||
* Inside the map, the following keys will exist:
|
||||
* - vertex_count
|
||||
* - edge_count
|
||||
* - average_degree
|
||||
* - memory_usage
|
||||
* - disk_usage
|
||||
**/
|
||||
std::map<std::string, std::string> StorageInfo() const;
|
||||
|
||||
/**
|
||||
* Insert this vertex into corresponding label and label+property (if it
|
||||
* exists) index.
|
||||
|
@ -703,6 +703,17 @@ TypedValue WorkerId(TypedValue *args, int64_t nargs, const EvaluationContext &,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MG_SINGLE_NODE) || defined(MG_SINGLE_NODE_HA)
|
||||
TypedValue StorageInfo(TypedValue *, int64_t nargs, const EvaluationContext &,
|
||||
database::GraphDbAccessor *dba) {
|
||||
if (nargs != 0)
|
||||
throw QueryRuntimeException("'storageInfo' requires no arguments.");
|
||||
|
||||
auto info = dba->StorageInfo();
|
||||
return std::map<std::string, TypedValue>(info.begin(), info.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
TypedValue Id(TypedValue *args, int64_t nargs, const EvaluationContext &,
|
||||
database::GraphDbAccessor *dba) {
|
||||
if (nargs != 1) {
|
||||
@ -985,6 +996,9 @@ NameToFunction(const std::string &function_name) {
|
||||
#ifdef MG_DISTRIBUTED
|
||||
if (function_name == "WORKERID") return WorkerId;
|
||||
#endif
|
||||
#if defined(MG_SINGLE_NODE) || defined(MG_SINGLE_NODE_HA)
|
||||
if (function_name == "STORAGEINFO") return StorageInfo;
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/stat.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace telemetry {
|
||||
@ -74,17 +75,7 @@ const nlohmann::json GetResourceUsage() {
|
||||
auto cpu_total = GetCpuUsage(pid);
|
||||
cpu["usage"] = cpu_total.second;
|
||||
|
||||
// Parse memory usage.
|
||||
uint64_t memory = 0;
|
||||
auto statm_data = utils::ReadLines(fmt::format("/proc/{}/statm", pid));
|
||||
if (statm_data.size() >= 1) {
|
||||
auto split = utils::Split(statm_data[0]);
|
||||
if (split.size() >= 2) {
|
||||
memory = std::stoull(split[1]) * sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
}
|
||||
|
||||
return {{"cpu", cpu}, {"memory", memory}};
|
||||
return {{"cpu", cpu}, {"memory", utils::GetMemoryUsage()}};
|
||||
}
|
||||
|
||||
} // namespace telemetry
|
||||
|
45
src/utils/stat.hpp
Normal file
45
src/utils/stat.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
namespace utils {
|
||||
|
||||
/// Returns the number of bytes a directory is using on disk. If the given path
|
||||
/// isn't a directory, zero will be returned.
|
||||
inline uint64_t GetDirDiskUsage(
|
||||
const std::experimental::filesystem::path &path) {
|
||||
if (!std::experimental::filesystem::is_directory(path)) return 0;
|
||||
|
||||
uint64_t size = 0;
|
||||
for (auto &p : std::experimental::filesystem::directory_iterator(path)) {
|
||||
if (std::experimental::filesystem::is_directory(p)) {
|
||||
size += GetDirDiskUsage(p);
|
||||
} else if (std::experimental::filesystem::is_regular_file(p)) {
|
||||
size += std::experimental::filesystem::file_size(p);
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/// Returns the number of bytes the process is using in the memory.
|
||||
inline uint64_t GetMemoryUsage() {
|
||||
// Get PID of entire process.
|
||||
pid_t pid = getpid();
|
||||
uint64_t memory = 0;
|
||||
auto statm_data = utils::ReadLines(fmt::format("/proc/{}/statm", pid));
|
||||
if (statm_data.size() >= 1) {
|
||||
auto split = utils::Split(statm_data[0]);
|
||||
if (split.size() >= 2) {
|
||||
memory = std::stoull(split[1]) * sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
}
|
||||
return memory;
|
||||
}
|
||||
|
||||
} // namespace utils
|
Loading…
Reference in New Issue
Block a user