Compare commits
No commits in common. "dev" and "v0.2" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
build/
|
|
52
.vscode/settings.json
vendored
52
.vscode/settings.json
vendored
@ -8,56 +8,6 @@
|
|||||||
"*.tcc": "cpp",
|
"*.tcc": "cpp",
|
||||||
"deque": "cpp",
|
"deque": "cpp",
|
||||||
"unordered_map": "cpp",
|
"unordered_map": "cpp",
|
||||||
"system_error": "cpp",
|
"system_error": "cpp"
|
||||||
"atomic": "cpp",
|
|
||||||
"shared_mutex": "cpp",
|
|
||||||
"mutex": "cpp",
|
|
||||||
"cctype": "cpp",
|
|
||||||
"clocale": "cpp",
|
|
||||||
"cmath": "cpp",
|
|
||||||
"cstdarg": "cpp",
|
|
||||||
"cstddef": "cpp",
|
|
||||||
"cstdio": "cpp",
|
|
||||||
"cstdlib": "cpp",
|
|
||||||
"ctime": "cpp",
|
|
||||||
"cwchar": "cpp",
|
|
||||||
"cwctype": "cpp",
|
|
||||||
"array": "cpp",
|
|
||||||
"bit": "cpp",
|
|
||||||
"chrono": "cpp",
|
|
||||||
"compare": "cpp",
|
|
||||||
"concepts": "cpp",
|
|
||||||
"condition_variable": "cpp",
|
|
||||||
"cstdint": "cpp",
|
|
||||||
"exception": "cpp",
|
|
||||||
"algorithm": "cpp",
|
|
||||||
"functional": "cpp",
|
|
||||||
"iterator": "cpp",
|
|
||||||
"memory": "cpp",
|
|
||||||
"memory_resource": "cpp",
|
|
||||||
"numeric": "cpp",
|
|
||||||
"optional": "cpp",
|
|
||||||
"random": "cpp",
|
|
||||||
"ratio": "cpp",
|
|
||||||
"string_view": "cpp",
|
|
||||||
"tuple": "cpp",
|
|
||||||
"type_traits": "cpp",
|
|
||||||
"utility": "cpp",
|
|
||||||
"fstream": "cpp",
|
|
||||||
"initializer_list": "cpp",
|
|
||||||
"iosfwd": "cpp",
|
|
||||||
"istream": "cpp",
|
|
||||||
"limits": "cpp",
|
|
||||||
"new": "cpp",
|
|
||||||
"numbers": "cpp",
|
|
||||||
"semaphore": "cpp",
|
|
||||||
"sstream": "cpp",
|
|
||||||
"stdexcept": "cpp",
|
|
||||||
"stop_token": "cpp",
|
|
||||||
"streambuf": "cpp",
|
|
||||||
"thread": "cpp",
|
|
||||||
"cinttypes": "cpp",
|
|
||||||
"typeinfo": "cpp",
|
|
||||||
"variant": "cpp"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,30 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
|
||||||
|
|
||||||
project(metrics)
|
|
||||||
|
|
||||||
# Postavi verziju projekta
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
|
|
||||||
# Pronađi Boost biblioteku (ako nije uobičajeni direktorijum, postavi put)
|
|
||||||
# find_package(Boost REQUIRED COMPONENTS system)
|
|
||||||
|
|
||||||
# Dodaj direktorijume sa zaglavljima
|
|
||||||
include_directories(lib)
|
|
||||||
|
|
||||||
# Dodaj biblioteku
|
|
||||||
add_library(metrics STATIC
|
|
||||||
src/metrics.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# # Linkaj log biblioteku sa Boost-om
|
|
||||||
# target_link_libraries(log Boost::system)
|
|
||||||
|
|
||||||
# Dodaj testove
|
|
||||||
add_subdirectory(test)
|
|
||||||
|
|
||||||
|
|
||||||
# Instaliraj biblioteku
|
|
||||||
# install(TARGETS log DESTINATION lib)
|
|
||||||
# install(FILES lib/log.hpp lib/define.hpp lib/engine.hpp lib/filesystem.hpp lib/timers.hpp lib/trigger.hpp DESTINATION include/log)
|
|
||||||
#
|
|
2
LICENSE
2
LICENSE
@ -58,7 +58,7 @@ APPENDIX: How to apply the Apache License to your work.
|
|||||||
|
|
||||||
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||||
|
|
||||||
Copyright [2023] [Marcel Bandić - marcelb96@yahoo.com]
|
Copyright [2023] [Marcel Bandić]
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
61
README.md
61
README.md
@ -1,61 +0,0 @@
|
|||||||
|
|
||||||
# A library for tracking statistics and metrics
|
|
||||||
|
|
||||||
A simple library for measuring incremental parameters in C++ programs based on the key-value principle.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- Object oriented
|
|
||||||
- Thread safe
|
|
||||||
- Easy access to counters using the [] operator
|
|
||||||
- Simple incrementing of counters using the ++ operator
|
|
||||||
- Initial setup of the list of counters and values
|
|
||||||
- List of counter names
|
|
||||||
- Retrieving the status of all counters
|
|
||||||
- Reset all counters
|
|
||||||
- Retrieving the state of all counters and resetting the counters
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Just download the latest release and unzip it into your project. You can turn it on with:
|
|
||||||
|
|
||||||
```
|
|
||||||
#include "metrics/lib/metrics.hpp"
|
|
||||||
using namespace marcelb;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```c++
|
|
||||||
// init
|
|
||||||
Metrics<string> stats;
|
|
||||||
// operator [] and increment ++
|
|
||||||
stats["access"]++;
|
|
||||||
// print couter access
|
|
||||||
cout << stats["access"];
|
|
||||||
// get counters names
|
|
||||||
auto listCounterNames = stats.keys();
|
|
||||||
// get all couters
|
|
||||||
auto data = stats.get_data();
|
|
||||||
// reset counters
|
|
||||||
stats.clear();
|
|
||||||
// set counters
|
|
||||||
map<string, uint64_t> MyStats = {{"access", 3},{ "error", 0}};
|
|
||||||
stats.set(MyStats);
|
|
||||||
// get and clear all counters
|
|
||||||
auto dataWithClear = stats.get_data_and_clear();
|
|
||||||
```
|
|
||||||
## License
|
|
||||||
|
|
||||||
[APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0/)
|
|
||||||
|
|
||||||
|
|
||||||
## Support & Feedback
|
|
||||||
|
|
||||||
For support and any feedback, contact the address: marcelb96@yahoo.com.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Contributions are always welcome!
|
|
||||||
|
|
||||||
Feel free to fork and start working with or without a later pull request. Or contact for suggest and request an option.
|
|
||||||
|
|
@ -6,69 +6,68 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <shared_mutex>
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace marcelb {
|
namespace marcelb {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A template class for measuring arbitrary statistics
|
* Klasa za mjerenje proizvoljne statistike
|
||||||
*/
|
*/
|
||||||
template<typename K>
|
|
||||||
class Metrics {
|
class Metrics {
|
||||||
mutable shared_mutex mtx; // Mutex for concurrent read, exclusive write
|
mutex io;
|
||||||
map<K, atomic<uint64_t>> counters; // Supports any K (e.g., string, int)
|
map<string, uint> counters;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* Constructor, without predefining the name of the counter
|
Metrics ();
|
||||||
*/
|
Metrics (map<string, uint> _counters);
|
||||||
Metrics();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor, with predefined counters from the passed object
|
* Operator[] za pristup svakoj brojaču mjerenja
|
||||||
*/
|
*/
|
||||||
Metrics(map<K, uint64_t> _counters);
|
uint& operator[](const string& key) {
|
||||||
|
return counters[key];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operator[] to access each measurement counter
|
* Operator++ za inkrementalno povećanje brojača mjerenja
|
||||||
*/
|
*/
|
||||||
atomic<uint64_t>& operator[](const K& key);
|
Metrics& operator++ (int n) {
|
||||||
|
lock_guard<mutex> _io(io);
|
||||||
|
n++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(map<string, uint> _counters) {
|
||||||
|
counters = _counters;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operator++ to increment the measurement counter incrementally
|
* Metoda za resetiranje brojača
|
||||||
*/
|
*/
|
||||||
Metrics& operator++(int n);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to set the counter from the passed object
|
|
||||||
*/
|
|
||||||
void set(map<K, uint64_t> _counters);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A method to reset the counter
|
|
||||||
*/
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A method that returns a vector of strings of all counter names
|
* Metoda koja vraća vektor stringova svih naziva brojača
|
||||||
*/
|
*/
|
||||||
vector<K> keys() const;
|
vector<string> keys();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The method returns a map<K, uint64_t> of all measurements
|
* Metoda vraća map<string, uint> svih mjerenja
|
||||||
*/
|
*/
|
||||||
map<K, uint64_t> get_data() const;
|
map<string, uint> get_data();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The method returns a map<K, uint64_t> of all measurements and resets the counters
|
* Metoda vraća map<string, uint> svih mjerenja i resetira brojače
|
||||||
*/
|
*/
|
||||||
map<K, uint64_t> get_data_and_clear();
|
map<string, uint> get_data_and_clear();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,75 +1,35 @@
|
|||||||
#include "../lib/metrics.hpp"
|
#include "../lib/metrics.hpp"
|
||||||
|
|
||||||
namespace marcelb {
|
marcelb::Metrics::Metrics() {
|
||||||
|
}
|
||||||
|
|
||||||
template<typename K>
|
marcelb::Metrics::Metrics(map<string, uint> _counters) {
|
||||||
Metrics<K>::Metrics() {}
|
|
||||||
|
|
||||||
template<typename K>
|
|
||||||
Metrics<K>::Metrics(map<K, uint64_t> _counters) {
|
|
||||||
set(_counters);
|
set(_counters);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K>
|
void marcelb::Metrics::clear() {
|
||||||
void Metrics<K>::clear() {
|
lock_guard<mutex> _io(io);
|
||||||
unique_lock<shared_mutex> lock(mtx);
|
|
||||||
counters.clear();
|
counters.clear();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K>
|
vector<string> marcelb::Metrics::keys() {
|
||||||
vector<K> Metrics<K>::keys() const {
|
vector<string> _keys;
|
||||||
shared_lock<shared_mutex> lock(mtx);
|
for (auto counter : counters) {
|
||||||
vector<K> _keys;
|
|
||||||
for (auto& counter : counters) {
|
|
||||||
_keys.push_back(counter.first);
|
_keys.push_back(counter.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _keys;
|
return _keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K>
|
|
||||||
map<K, uint64_t> Metrics<K>::get_data() const {
|
map<string, uint> marcelb::Metrics::get_data() {
|
||||||
shared_lock<shared_mutex> lock(mtx);
|
return counters;
|
||||||
map<K, uint64_t> data;
|
|
||||||
for (const auto& counter : counters) {
|
|
||||||
data[counter.first] = counter.second.load();
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K>
|
|
||||||
map<K, uint64_t> Metrics<K>::get_data_and_clear() {
|
map<string, uint> marcelb::Metrics::get_data_and_clear() {
|
||||||
map<K, uint64_t> data = get_data();
|
auto data = counters;
|
||||||
clear();
|
clear();
|
||||||
return data;
|
return counters;
|
||||||
}
|
|
||||||
|
|
||||||
template<typename K>
|
|
||||||
atomic<uint64_t>& Metrics<K>::operator[](const K& key) {
|
|
||||||
shared_lock<shared_mutex> lock(mtx);
|
|
||||||
return counters[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename K>
|
|
||||||
Metrics<K>& Metrics<K>::operator++(int n) {
|
|
||||||
shared_lock<shared_mutex> lock(mtx);
|
|
||||||
// Increment all counters by n as an example
|
|
||||||
// for (auto& counter : counters) {
|
|
||||||
// counter.second.fetch_add(n, memory_order_relaxed);
|
|
||||||
// }
|
|
||||||
n++;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename K>
|
|
||||||
void Metrics<K>::set(map<K, uint64_t> _counters) {
|
|
||||||
unique_lock<shared_mutex> lock(mtx);
|
|
||||||
counters.clear();
|
|
||||||
for (auto& counter : _counters) {
|
|
||||||
counters[counter.first].store(counter.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template class Metrics<string>;
|
|
||||||
template class Metrics<uint32_t>;
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,3 +0,0 @@
|
|||||||
add_executable(metrics_test test.cpp)
|
|
||||||
|
|
||||||
target_link_libraries(metrics_test metrics)
|
|
@ -1,75 +1,22 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include "../lib/metrics.hpp"
|
#include "../lib/metrics.hpp"
|
||||||
|
|
||||||
using namespace marcelb;
|
using namespace marcelb;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
// atomic<int> a(0);
|
Metrics metrika;
|
||||||
|
|
||||||
// a++;
|
|
||||||
|
|
||||||
// cout << a << endl;
|
|
||||||
|
|
||||||
Metrics<string> metrika;
|
|
||||||
|
|
||||||
cout << " access " << metrika["access"]++ << endl;
|
cout << " access " << metrika["access"]++ << endl;
|
||||||
cout << " access " << metrika["access"]++ << endl;
|
cout << " access " << metrika["access"]++ << endl;
|
||||||
cout << " error " << metrika["error"] << endl;
|
cout << " error " << metrika["error"] << endl;
|
||||||
cout << " access " << metrika["access"] << endl;
|
cout << " access " << metrika["access"] << endl;
|
||||||
|
|
||||||
// metrika.keys();
|
metrika.keys();
|
||||||
|
|
||||||
cout << " error " << metrika["error"] << endl;
|
cout << " error " << metrika["error"] << endl;
|
||||||
cout << " access " << metrika["access"] << endl;
|
cout << " access " << metrika["access"] << endl;
|
||||||
|
|
||||||
Metrics<uint32_t> metrika2;
|
|
||||||
|
|
||||||
|
|
||||||
enum keys {
|
|
||||||
access = 1,
|
|
||||||
error
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cout << " access " << metrika2[keys::access]++ << endl;
|
|
||||||
cout << " access " << metrika2[keys::access]++ << endl;
|
|
||||||
cout << " error " << metrika2[keys::error] << endl;
|
|
||||||
cout << " access " << metrika2[keys::access] << endl;
|
|
||||||
|
|
||||||
// metrika2.keys();
|
|
||||||
|
|
||||||
cout << " error " << metrika2[keys::error] << endl;
|
|
||||||
cout << " access " << metrika2[keys::access] << endl;
|
|
||||||
|
|
||||||
|
|
||||||
// // init
|
|
||||||
// Metrics stats;
|
|
||||||
// // operator [] and increment ++
|
|
||||||
// stats["access"]++;
|
|
||||||
// // print couter access
|
|
||||||
// cout << stats["access"];
|
|
||||||
// // get counters names
|
|
||||||
// auto listCounterNames = stats.keys();
|
|
||||||
// // get all couters
|
|
||||||
// auto data = stats.get_data();
|
|
||||||
// // reset counters
|
|
||||||
// stats.clear();
|
|
||||||
// // set counters
|
|
||||||
// map<string, uint64_t> MyStats = {{"access", 3},{ "error", 0}};
|
|
||||||
// stats.set(MyStats);
|
|
||||||
// // get and clear all counters
|
|
||||||
auto dataWithClear = metrika.get_data_and_clear();
|
|
||||||
|
|
||||||
for (auto& [key, value] : dataWithClear) {
|
|
||||||
cout << "Log analitic " << key << ", value: " << value << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user