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:
Matija Santl 2019-01-03 08:45:01 +01:00
parent 773acc11d6
commit 1b11e109fa
9 changed files with 135 additions and 13 deletions

View File

@ -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_;

View File

@ -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

View File

@ -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.

View File

@ -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_;

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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
View 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