Skip to content

Commit

Permalink
Introduce Telemetry & AppFs example
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Pelanek authored and SiskaPavel committed Oct 4, 2024
1 parent a11eef0 commit f66c1ff
Show file tree
Hide file tree
Showing 10 changed files with 614 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/workflows/cppcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
output_file: 'cppcheck_report.txt'
enable: warning,performance,portability,style,information
other_options: --error-exitcode=1 --library=googletest
exclude_check: ./example/
- name: Print cppcheck_report.txt
if: failure()
run: cat cppcheck_report.txt
Expand Down
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ option(TELEMETRY_PACKAGE_BUILDER "Enable RPM package builder (make rpm)" ON)
option(TELEMETRY_INSTALL_TARGETS "Generate the install target" ON)
option(TELEMETRY_ENABLE_TESTS "Build Unit tests (make test)" OFF)
option(TELEMETRY_ENABLE_DOC_DOXYGEN "Enable build of code documentation" OFF)
option(TELEMETRY_BUILD_EXAMPLE "Build included example files (make example)" OFF)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand All @@ -32,6 +33,10 @@ if (TELEMETRY_ENABLE_TESTS)
enable_testing()
endif()

if (TELEMETRY_BUILD_EXAMPLE)
add_subdirectory(example)
endif()

add_subdirectory(src)
add_subdirectory(doc)

Expand Down
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ endif

SRC_DIR = "$(shell pwd)/src"
INC_DIR = "$(shell pwd)/include"
EXAMPLE_DIR = "$(shell pwd)/example"

HEADE_FILTER = "$(SRC_DIR)|$(INC_DIR)"
SOURCE_DIR = "$(SRC_DIR)" "$(INC_DIR)"
HEADE_FILTER = "$(SRC_DIR)|$(INC_DIR)|$(EXAMPLE_DIR)"
SOURCE_DIR = "$(SRC_DIR)" "$(INC_DIR)" "$(EXAMPLE_DIR)"
CPP_CHECK_SOURCE_DIR = "$(SRC_DIR)" "$(INC_DIR)"
SOURCE_REGEX = '.*\.\(cpp\|hpp\)'

CPPCHECK_FLAGS = \
Expand Down Expand Up @@ -64,7 +66,7 @@ tidy-fix: all

.PHONY: cppcheck
cppcheck: build/Makefile
@$(CPPCHECK) $(CPPCHECK_FLAGS) --enable=$(CPPCHECK_CHECKS) $(SOURCE_DIR)
@$(CPPCHECK) $(CPPCHECK_FLAGS) --enable=$(CPPCHECK_CHECKS) $(CPP_CHECK_SOURCE_DIR)

.PHONY: test
test: build
Expand All @@ -75,3 +77,7 @@ test: build
doxygen: build
@cd build && $(CMAKE) $(CMAKE_ARGS) -DTELEMETRY_ENABLE_DOC_DOXYGEN=ON ..
@$(MAKE) --no-print-directory -C build $@

example: build
@cd build && $(CMAKE) $(CMAKE_ARGS) -DTELEMETRY_BUILD_EXAMPLE=ON ..
@$(MAKE) --no-print-directory -C build
10 changes: 10 additions & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
add_executable(example
main.cpp
dataCenter.cpp
server.cpp
)

target_link_libraries(example PRIVATE
telemetry::telemetry
telemetry::appFs
)
92 changes: 92 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Telemetry Example

## Overview

This example demonstrates a telemetry data structure that organizes and stores metrics from multiple servers located in different data centers. The structure allows for efficient retrieval and monitoring of key telemetry metrics such as CPU usage, memory usage, latency, and disk usage.

## AppFs Directory Structure

The resulting directory structure after running the application is as follows:

```bash
$ tree /tmp/telemetry
/tmp/telemetry
└── data_centers
├── new_york
│ ├── server_count
│ ├── servers
│ │ ├── server_0
│ │ │ └── stats
│ │ ├── server_1
│ │ │ └── stats
│ │ └── server_2
│ │ └── stats
│ └── summary
│ └── summary_stats
├── prague
│ ├── server_count
│ ├── servers
│ │ ├── server_0
│ │ │ └── stats
│ │ ├── server_1
│ │ │ └── stats
│ │ └── server_2
│ │ └── stats
│ └── summary
│ └── summary_stats
└── tokyo
├── server_count
├── servers
│ ├── server_0
│ │ └── stats
│ ├── server_1
│ │ └── stats
│ └── server_2
│ └── stats
└── summary
└── summary_stats
```
## Example of Telemetry Output

Here is an example of the contents of the `stats` file for a specific server:

```bash
$ cat /tmp/telemetry/data_centers/prague/servers/server_0/stats
cpu_usage: 74.28 (%)
disk_usage: 13.48 (%)
latency: 170.20 (ms)
memory_usage: 31.17 (%)
timestamp: 2024-10-03 15:18:41
```

Example of the contents of the summary_stats file for a data center:

```bash
$ cat /tmp/telemetry/data_centers/prague/summary/summary_stats
cpu_usage [avg]: 44.20 (%)
disk_usage [avg]: 35.78 (%)
latency [avg]: 121.82 (ms)
latency [max]: 193.88 (ms)
latency [min]: 7.04 (ms)
memory_usage [avg]: 54.20 (%)
```

## How to build & run

### Build
To build the example, simply run the following command in the root of the project:

```bash
make example
```
### Run
Once the build is complete, you can run the example by specifying the desired mount point:

```bash
./example <mount_point>
```
For example:

```bash
./example /tmp/telemetry
```
98 changes: 98 additions & 0 deletions example/dataCenter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* @file
* @author Pavel Siska <siska@cesnet.cz>
* @brief Implementation of the DataCenter class for managing multiple servers and their telemetry
* data.
*
* This source file implements the methods of the `DataCenter` class, which manages a collection
* of `Server` objects and their associated telemetry data. It includes functionalities for adding
* servers, setting up telemetry reporting, and aggregating data across all servers for summary
* statistics.
*
* @copyright Copyright (c) 2024 CESNET, z.s.p.o.
*/

#include "dataCenter.hpp"

namespace telemetry::example {

/**
* @brief Creates a summary file with aggregated telemetry data.
*
* @param filename The name of the summary file to be created.
* @param filePattern The pattern to match server telemetry files.
* @param patternRootDir Shared pointer to the working directory for patterns.
* @param dir Shared pointer to the directory where the summary file will be added.
* @return A shared pointer to the created aggregated file.
*/
static std::shared_ptr<telemetry::AggregatedFile> createSummaryFile(
const std::string& filename,
const std::string& filePattern,
std::shared_ptr<telemetry::Directory>& patternRootDir,
std::shared_ptr<telemetry::Directory>& dir)
{
const std::vector<telemetry::AggOperation> aggOps {
{telemetry::AggMethodType::AVG, "cpu_usage", "cpu_usage [avg]"},
{telemetry::AggMethodType::AVG, "memory_usage", "memory_usage [avg]"},
{telemetry::AggMethodType::AVG, "latency", "latency [avg]"},
{telemetry::AggMethodType::MIN, "latency", "latency [min]"},
{telemetry::AggMethodType::MAX, "latency", "latency [max]"},
{telemetry::AggMethodType::AVG, "disk_usage", "disk_usage [avg]"},
};

return dir->addAggFile(filename, filePattern, aggOps, patternRootDir);
}

DataCenter::DataCenter(std::string location, std::shared_ptr<telemetry::Directory>& dataCenterDir)
: m_rootDir(dataCenterDir)
, m_location(std::move(location))
{
setupTelemetry(dataCenterDir);
}

void DataCenter::addServer(Server server)
{
auto serverDir = m_rootDir->addDirs("servers/" + server.getId());
server.setupTelemetry(serverDir);

m_servers.emplace_back(std::move(server));
}

/**
* @brief Sets up telemetry reporting for the data center.
*
* This method initializes the telemetry reporting structure for the data center. It creates
* the necessary directories for storing server-specific telemetry data and summary statistics.
*
* It performs the following actions:
* - Creates a directory to hold all server directories (`servers`).
* - Creates a directory to store aggregated summary statistics (`summary`).
* - Adds a file that tracks the count of servers currently managed by the data center.
* - Creates an aggregated summary file that calculates average telemetry metrics (such as
* CPU usage, memory usage, latency, and disk usage) across all servers.
*
* The generated directories and files are added to the telemetry holder to manage their lifecycle
* and ensure they are updated as telemetry data is collected from individual servers.
*
* @param dataCenterDir Shared pointer to the telemetry directory where the telemetry structure will
* be established.
*/
void DataCenter::setupTelemetry(std::shared_ptr<telemetry::Directory>& dataCenterDir)
{
auto serversDir = dataCenterDir->addDir("servers");
auto summaryDir = dataCenterDir->addDir("summary");

const auto serverCountFile = dataCenterDir->addFile(
"server_count",
{[&]() -> telemetry::Scalar { return m_servers.size(); }, nullptr});

const auto summaryFile
= createSummaryFile("summary_stats", "server_\\d+/stats", serversDir, summaryDir);

m_holder.add(serversDir);
m_holder.add(summaryDir);
m_holder.add(serverCountFile);
m_holder.add(summaryFile);
}

} // namespace telemetry::example
65 changes: 65 additions & 0 deletions example/dataCenter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @file
* @author Pavel Siska <siska@cesnet.cz>
* @brief Declaration of the DataCenter class for managing multiple servers and their telemetry
* data.
*
* This header file defines the `DataCenter` class, which is responsible for managing a collection
* of `Server` objects and their associated telemetry data. The `DataCenter` allows adding servers,
* setting up their telemetry reporting, and aggregating data across all servers for summary
* statistics.
*
* The telemetry data is organized in a hierarchical directory structure and can include information
* such as CPU usage, memory usage, latency, and disk usage for each server.
*
* @copyright Copyright (c) 2024 CESNET, z.s.p.o.
*/

#pragma once

#include "server.hpp"

#include <memory>
#include <string>
#include <telemetry.hpp>
#include <vector>

namespace telemetry::example {

/**
* @brief Class representing a data center that manages multiple servers.
*
* This class provides functionality to add servers, setup telemetry reporting,
* and aggregate telemetry data across all managed servers.
*/
class DataCenter {
public:
/**
* @brief Constructs a new DataCenter object with a specified location and telemetry directory.
*
* @param location The physical location of the data center.
* @param dataCenterDir Shared pointer to the telemetry directory for this data center.
*/
DataCenter(std::string location, std::shared_ptr<telemetry::Directory>& dataCenterDir);

/**
* @brief Adds a server to the data center.
* @param server The server to be added.
*/
void addServer(Server server);

private:
/**
* @brief Sets up telemetry reporting for the data center.
* @param dataCenterDir Shared pointer to the telemetry directory.
*/
void setupTelemetry(std::shared_ptr<telemetry::Directory>& dataCenterDir);

std::shared_ptr<telemetry::Directory>
m_rootDir; ///< Pointer to the root data center telemetry directory.
std::string m_location; ///< The location of the data center.
telemetry::Holder m_holder; ///< Holder for managing telemetry files.
std::vector<Server> m_servers; ///< Vector to store added servers.
};

} // namespace telemetry::example
Loading

0 comments on commit f66c1ff

Please sign in to comment.