Browse Source

Added statistics reading and a command-line tool to monitor them

master
Ludovic 'Archivist' Lagouardette 5 years ago
parent
commit
847bce9710
5 changed files with 126 additions and 3 deletions
  1. +1
    -0
      Makefile
  2. +11
    -1
      include/network.hpp
  3. +70
    -0
      src/db_stats.cpp
  4. +38
    -1
      src/izaro-storage.cpp
  5. +6
    -1
      src/test_client.cpp

+ 1
- 0
Makefile View File

@ -60,6 +60,7 @@ $(TARGET): $(OBJECTS) $(TJS_OBJECTS) build
@mkdir -p $(@D)
$(CXX) $(CXXFLAGS) $(INCLUDE) $(LDFLAGS) -o $(APP_DIR)/$(TARGETNAME) src/$(TARGET) $(OBJECTS) $(TJS_OBJECTS)
$(CXX) $(CXXFLAGS) $(INCLUDE) $(LDFLAGS) -o $(APP_DIR)/test_client src/test_client.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) $(LDFLAGS) -o $(APP_DIR)/db_stats src/db_stats.cpp
.PHONY: all build clean

+ 11
- 1
include/network.hpp View File

@ -7,7 +7,8 @@ enum class db_op : uint32_t {
version = 0,
read = 1,
write = 2,
remove = 3
remove = 3,
stats = 4
};
struct [[gnu::packed]] received_data {
@ -21,4 +22,13 @@ struct [[gnu::packed]] sending_data {
bitops::regulated<uint64_t> rep_id = 0;
record_identifier identifier = record_identifier{};
db_page page = {0};
};
struct [[gnu::packed]] stats_data {
bitops::regulated<uint64_t> free;
bitops::regulated<uint64_t> free_deleted;
bitops::regulated<uint64_t> total_pages;
bitops::regulated<uint64_t> total_records;
bitops::regulated<uint64_t> total_delete;
bitops::regulated<uint64_t> cow_full;
};

+ 70
- 0
src/db_stats.cpp View File

@ -0,0 +1,70 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <variant>
#include <chrono>
#include <algorithm>
#include "database.hpp"
#include "network.hpp"
#include <memory>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include "commander.hpp"
int main(int argc, char** argv)
{
try{
while(argc == 3)
{
std::stringstream ip_stream{argv[1]};
std::array<uint8_t, 4> ip;
std::string token;
std::getline(ip_stream, token, '.');
ip[0] = std::stoi(token);
std::getline(ip_stream, token, '.');
ip[1] = std::stoi(token);
std::getline(ip_stream, token, '.');
ip[2] = std::stoi(token);
std::getline(ip_stream, token, '.');
ip[3] = std::stoi(token);
uint16_t port = std::stoi(argv[2]);
auto soc = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = *(in_addr_t*)ip.data();
server.sin_port = htons(port);
connect(soc, (struct sockaddr*)&server, sizeof(server));
sending_data reply;
received_data request;
request.op = db_op::stats;
send(soc, (void*)&request, (socklen_t)sizeof(request), 0);
recv(soc, (void*)&reply, (socklen_t)sizeof(reply), 0);
auto stats = (stats_data*)&reply.page;
std::cout << "free_pages\t" << stats->free << std::endl;
std::cout << "deleted_pages\t" << stats->free_deleted << std::endl;
std::cout << "total_pages\t" << stats->total_pages << std::endl;
std::cout << "total_records\t" << stats->total_records << std::endl;
std::cout << "delete_cache\t" << stats->total_delete << std::endl;
std::cout << "inaccessible\t" << stats->cow_full << std::endl;
return 0;
}
}catch(...) {}
std::cerr << "Invalid command, expects ``db_stats IPV4 PORT''" << std::endl;
return 1;
}

+ 38
- 1
src/izaro-storage.cpp View File

@ -65,6 +65,20 @@ int main(
}
size_t db_port = 20450;
if(cmd_args.isFlagSet("-port"))
{
try{
db_port = std::stoi(cmd_args.getFlagValue("-port"));
if(db_port>std::numeric_limits<uint16_t>::max()) throw std::runtime_error("invalid_port");
} catch (...) {
std::cerr << "Invalid port value" << std::endl;
return 1;
}
}
#ifdef UNITTEST
{
database db(database::create(utest_str, utest_size*2));
@ -163,7 +177,7 @@ int main(
auto soc = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(mi">20450);
addr.sin_port = htons(n">db_port);
memset((void*)&addr.sin_addr, 0, sizeof(addr.sin_addr));
bind(soc,(struct sockaddr*)&addr,sizeof(addr));
@ -227,6 +241,29 @@ int main(
reply_size = sizeof(reply.rep_id) + sizeof(reply.identifier);
}
break;
case db_op::stats:
{
reply.rep_id = recv.rep_id;
auto stats = (stats_data*)&reply.page;
stats->total_pages = (*run_db.metadata).page_cnt;
stats->total_records = (*run_db.metadata).record_cnt;
stats->free_deleted = (*run_db.metadata).last_delete;
stats->free =
(*run_db.metadata).last_delete
+ (*run_db.metadata).page_cnt
- (*run_db.metadata).last_page;
uint64_t cow_full = 0;
for(auto& elem : run_db.records)
{
if(elem.second.timestamp == std::numeric_limits<uint64_t>::max())
{
++cow_full;
}
}
stats->cow_full = cow_full;
reply_size = sizeof(reply);
}
break;
default:
std::cerr << "bad_request " << (uint32_t)static_cast<db_op>(recv.op) << std::endl;
continue;

+ 6
- 1
src/test_client.cpp View File

@ -2,9 +2,14 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <random>
int main(int, char** argv) {
{
std::random_device hrng{};
std::minstd_rand srng{hrng()};
auto soc = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server;
server.sin_family = AF_INET;
@ -32,7 +37,7 @@ int main(int, char** argv) {
for(size_t idx=0;idx<tot;idx++)
{
tar.y.internal = idx;
tar.y.internal = srng();
request.op = db_op::write;
sendto(
soc,

Loading…
Cancel
Save