Skip to content
Snippets Groups Projects
Commit 8479ba14 authored by Jonathan Mace's avatar Jonathan Mace
Browse files

Merge branch 'master' into 'master'

Add sampling interface and tests

See merge request !1
parents 45568b1d d5762457
No related branches found
No related tags found
1 merge request!1Add sampling interface and tests
build build
.DS_Store
.vscode/
\ No newline at end of file
...@@ -2,7 +2,15 @@ cmake_minimum_required(VERSION 3.4.1) ...@@ -2,7 +2,15 @@ cmake_minimum_required(VERSION 3.4.1)
project(libxtrace) project(libxtrace)
include_directories( include ) include_directories(
include
src
)
link_directories(
/usr/lib/x86_64-linux-gnu
/usr/include
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 ") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 ")
...@@ -22,6 +30,7 @@ add_library (libxtrace SHARED ...@@ -22,6 +30,7 @@ add_library (libxtrace SHARED
src/xtrace.cpp src/xtrace.cpp
src/xtrace_baggage.cpp src/xtrace_baggage.cpp
src/lexvarint.cpp src/lexvarint.cpp
src/xtrace_sampler.cpp
${PROTO_SRCS} ${PROTO_SRCS}
) )
set_target_properties(libxtrace set_target_properties(libxtrace
...@@ -67,7 +76,25 @@ target_link_libraries(luaxtrace libxtrace Threads::Threads protobuf boost_system ...@@ -67,7 +76,25 @@ target_link_libraries(luaxtrace libxtrace Threads::Threads protobuf boost_system
install(TARGETS luaxtrace DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS luaxtrace DESTINATION ${CMAKE_INSTALL_LIBDIR})
# Compile the main example program # Compile the main example program
add_executable (main src/main.cc ) add_executable (main src/main.cc)
target_include_directories(main PRIVATE /usr/local/include/xtrace /usr/include)
target_link_libraries(main libxtrace Threads::Threads protobuf boost_system config++ )
find_package(Catch2 REQUIRED)
target_include_directories(main PRIVATE /usr/local/include/xtrace) include_directories(test)
target_link_libraries(main libxtrace Threads::Threads protobuf boost_system )
# Compile the tests
add_executable(tests
test/tests.cpp
test/xtrace-cpp/test/test_sampler.cpp
test/xtrace-cpp/test/direct_test_sampler.cpp
)
target_include_directories(tests PRIVATE /usr/local/include/xtrace /usr/include)
target_link_libraries(tests
libxtrace
config++
Catch2::Catch2
)
# xtrace-cpp # xtrace-cpp
Barebones C++ implementation of X-Trace compatible with latest brown tracing framework + baggage version Barebones C++ implementation of X-Trace compatible with latest brown tracing framework + baggage version
# Building # Build Instructions
## Dependencies
To build the project, libconfig++-dev needs to be installed.
To install the library, run the following command.
```
sudo apt-get install libconfig++-dev
```
## Building
``` ```
mkdir build mkdir build
......
#ifndef _XTRACE_SAMPLER_
#define _XTRACE_SAMPLER_
namespace XTraceSampler {
namespace SamplingSetting {
extern bool sample;
extern double samplingRate;
void getDefaultSetting();
bool getSample();
double getSamplingRate();
}
class Sampler {
public:
Sampler();
virtual bool sample();
virtual void setParameter(double);
};
class UniformSampler: public Sampler {
private:
double p;
public:
UniformSampler();
UniformSampler(double p, unsigned int seed);
bool sample();
void setParameter(double p);
};
extern int startedTracesNum;
extern int samplingDecisionsNum;
extern Sampler* sampler;
void createSampler();
void initSampler();
void incrStartedTraces();
void incrSamplingDecisions();
bool sample();
int getStartedTracesNumber();
int getSamplingDecisionsNumber();
}
#endif
xtrace =
{
sampling = {
sample = true;
sampling_rate = 1.0;
};
};
\ No newline at end of file
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <chrono> #include <chrono>
#include <time.h> #include <time.h>
#include "xtrace_sampler.h"
#include "baggage.h" #include "baggage.h"
#include "xtrace.h" #include "xtrace.h"
#include "xtrace.pb.h" #include "xtrace.pb.h"
...@@ -121,11 +121,13 @@ void XTrace::Logger::log(std::string file, int line, std::string message, std::m ...@@ -121,11 +121,13 @@ void XTrace::Logger::log(std::string file, int line, std::string message, std::m
void XTrace::StartTrace() { void XTrace::StartTrace() {
XTraceBaggage::Clear(); // Clear old X-Trace metadata if it exists XTraceBaggage::Clear(); // Clear old X-Trace metadata if it exists
XTraceBaggage::SetTaskID(make_event_id()); if (XTraceSampler::sample()) {
XTraceBaggage::SetTaskID(make_event_id());
XTraceReportv4 report = makeReport(); XTraceReportv4 report = makeReport();
report.set_label("Start Trace"); report.set_label("Start Trace");
sendReport(report); sendReport(report);
}
} }
void XTrace::StartTrace(std::string tag) { void XTrace::StartTrace(std::string tag) {
...@@ -134,15 +136,17 @@ void XTrace::StartTrace(std::string tag) { ...@@ -134,15 +136,17 @@ void XTrace::StartTrace(std::string tag) {
void XTrace::StartTrace(std::vector<std::string> tags) { void XTrace::StartTrace(std::vector<std::string> tags) {
XTraceBaggage::Clear(); // Clear old X-Trace metadata if it exists XTraceBaggage::Clear(); // Clear old X-Trace metadata if it exists
XTraceBaggage::SetTaskID(make_event_id()); if (XTraceSampler::sample()) {
XTraceBaggage::SetTaskID(make_event_id());
XTraceReportv4 report = makeReport();
report.set_agent("StartTrace"); XTraceReportv4 report = makeReport();
report.set_label("Start Trace"); report.set_agent("StartTrace");
for (int i = 0; i < tags.size(); i++) { report.set_label("Start Trace");
report.add_tags(tags[i]); for (int i = 0; i < tags.size(); i++) {
report.add_tags(tags[i]);
}
sendReport(report);
} }
sendReport(report);
} }
bool XTrace::IsTracing() { bool XTrace::IsTracing() {
......
...@@ -96,3 +96,6 @@ void XTraceBaggage::SetParentEventID(uint64_t parentEventId) { ...@@ -96,3 +96,6 @@ void XTraceBaggage::SetParentEventID(uint64_t parentEventId) {
ThreadLocalBaggage::Set(b); ThreadLocalBaggage::Set(b);
} }
bool XTraceBaggage::HasParentEventIDs() {
return GetParentEventIDs().size() != 0;
}
...@@ -13,6 +13,7 @@ void SetTaskID(uint64_t taskId); ...@@ -13,6 +13,7 @@ void SetTaskID(uint64_t taskId);
std::vector<uint64_t> GetParentEventIDs(); std::vector<uint64_t> GetParentEventIDs();
void SetParentEventID(uint64_t eventId); void SetParentEventID(uint64_t eventId);
bool HasParentEventIDs();
} }
......
#include <cstdlib>
#include <ctime>
#include <libconfig.h++>
#include <iostream>
#include "xtrace_sampler.h"
bool XTraceSampler::SamplingSetting::sample = true;
double XTraceSampler::SamplingSetting::samplingRate = 1.0;
void XTraceSampler::SamplingSetting::getDefaultSetting() {
libconfig::Config config;
try {
config.readFile("../resources/reference.cfg");
const libconfig::Setting &root = config.getRoot();
const libconfig::Setting &sampling = root["xtrace"]["sampling"];
sample = sampling.lookup("sample");
samplingRate = sampling.lookup("sampling_rate");
}
catch(const std::exception& e) {
std::cerr << e.what() << '\n';
}
}
bool XTraceSampler::SamplingSetting::getSample() {
return sample;
}
double XTraceSampler::SamplingSetting::getSamplingRate() {
return samplingRate;
}
XTraceSampler::Sampler::Sampler() {}
bool XTraceSampler::Sampler::sample() {
return true;
}
void XTraceSampler::Sampler::setParameter(double p) {}
XTraceSampler::UniformSampler::UniformSampler() {
this -> p = SamplingSetting::getSamplingRate();
srand(static_cast<unsigned int>(clock()));
}
XTraceSampler::UniformSampler::UniformSampler(double p, unsigned int seed) {
this -> p = p;
srand(seed);
}
bool XTraceSampler::UniformSampler::sample() {
if ((double)rand() / RAND_MAX < this -> p) {
return true;
}
else {
return false;
}
}
void XTraceSampler::UniformSampler::setParameter(double p) {
this -> p = p;
}
int XTraceSampler::startedTracesNum = 0;
int XTraceSampler::samplingDecisionsNum = 0;
XTraceSampler::Sampler* XTraceSampler::sampler = NULL;
void XTraceSampler::createSampler() {
initSampler();
SamplingSetting::getDefaultSetting();
if (SamplingSetting::getSample()) {
sampler = new UniformSampler();
}
else {
sampler = new Sampler();
}
}
void XTraceSampler::initSampler() {
sampler = NULL;
startedTracesNum = 0;
samplingDecisionsNum = 0;
}
void XTraceSampler::incrStartedTraces() {
startedTracesNum++;
}
void XTraceSampler::incrSamplingDecisions() {
samplingDecisionsNum++;
}
bool XTraceSampler::sample() {
if (sampler == NULL) {
createSampler();
}
incrSamplingDecisions();
if (sampler -> sample()) {
incrStartedTraces();
return true;
}
else {
return false;
}
}
int XTraceSampler::getStartedTracesNumber() {
return startedTracesNum;
}
int XTraceSampler::getSamplingDecisionsNumber() {
return samplingDecisionsNum;
}
\ No newline at end of file
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
#include "xtrace_sampler.h"
TEST_CASE("All test cases reside in other .cpp files.", "[multi-file]") {}
\ No newline at end of file
#include <catch2/catch.hpp>
#include "xtrace_sampler.h"
#include "xtrace.h"
#include "pubsub.h"
#include "xtrace_baggage.h"
TEST_CASE( "Directly test sample = false", "[no-sample]" ) {
XTraceSampler::initSampler();
int sampleCallsNumber = 1000;
XTraceSampler::sampler = new XTraceSampler::Sampler();
for (int i = 0; i < sampleCallsNumber; i++) {
REQUIRE(XTraceSampler::sample());
}
REQUIRE(XTraceSampler::getStartedTracesNumber() == sampleCallsNumber);
REQUIRE(XTraceSampler::getSamplingDecisionsNumber() == sampleCallsNumber);
}
TEST_CASE( "Directly test sample = true, p = 0.5", "[sample]" ) {
XTraceSampler::initSampler();
int tracesNumber = 1000;
double samplingRate = 0.48;
XTraceSampler::sampler = new XTraceSampler::UniformSampler(0.5, 20);
for (int i = 0; i < tracesNumber; i++) {
XTraceSampler::sample();
}
int decisionsNum = XTraceSampler::getSamplingDecisionsNumber();
REQUIRE((double)XTraceSampler::getStartedTracesNumber() / decisionsNum == samplingRate);
REQUIRE(decisionsNum == tracesNumber);
}
TEST_CASE( "Check results for sample = true", "[sample]" ) {
XTraceSampler::initSampler();
int tracesNumber = 10;
XTraceSampler::sampler = new XTraceSampler::UniformSampler(0.2, 20);
bool expectedDecisions[10] = {true, false, false, false, false, false, false, false, false, false};
for (int i = 0; i < tracesNumber; i++) {
REQUIRE(XTraceSampler::sample() == expectedDecisions[i]);
}
}
#include <catch2/catch.hpp>
#include "xtrace_sampler.h"
#include "xtrace.h"
#include "pubsub.h"
#include "xtrace_baggage.h"
TEST_CASE( "Test sample = false", "[no-sample]" ) {
XTraceSampler::initSampler();
int tracesNumber = 1000;
for (int i = 0; i < tracesNumber; i++) {
uint64_t oldTaskID = XTraceBaggage::GetTaskID();
XTrace::StartTrace("Testing trace");
REQUIRE(XTraceBaggage::HasTaskID());
REQUIRE(XTraceBaggage::GetTaskID() != oldTaskID);
XTrace::log("Ending trace");
}
REQUIRE(XTraceSampler::getStartedTracesNumber() == tracesNumber);
REQUIRE(XTraceSampler::getSamplingDecisionsNumber() == tracesNumber);
}
TEST_CASE( "Test sample = true, p = 0", "[sample]" ) {
XTraceSampler::initSampler();
int tracesNumber = 1000;
XTraceSampler::sampler = new XTraceSampler::UniformSampler(0, static_cast<unsigned int>(clock()));
for (int i = 0; i < tracesNumber; i++) {
XTrace::StartTrace("Testing trace");
XTrace::log("Ending trace");
REQUIRE(!XTraceBaggage::HasTaskID());
REQUIRE(!XTraceBaggage::HasParentEventIDs());
}
REQUIRE(XTraceSampler::getStartedTracesNumber() == 0);
REQUIRE(XTraceSampler::getSamplingDecisionsNumber() == tracesNumber);
}
TEST_CASE( "Test sample = true, p = 1", "[sample]" ) {
XTraceSampler::initSampler();
int tracesNumber = 1000;
XTraceSampler::sampler = new XTraceSampler::UniformSampler(1, static_cast<unsigned int>(clock()));
for (int i = 0; i < tracesNumber; i++) {
XTrace::StartTrace("Testing trace");
XTrace::log("Ending trace");
REQUIRE(XTraceBaggage::HasTaskID());
REQUIRE(XTraceBaggage::HasParentEventIDs());
}
REQUIRE(XTraceSampler::getStartedTracesNumber() == tracesNumber);
REQUIRE(XTraceSampler::getSamplingDecisionsNumber() == tracesNumber);
}
TEST_CASE( "Check has parents for sample = true", "[sample]" ) {
XTraceSampler::initSampler();
int tracesNumber = 2;
bool expectedDecisions[2] = {true, false};
XTraceSampler::sampler = new XTraceSampler::UniformSampler(1, static_cast<unsigned int>(clock()));
for (int i = 0; i < tracesNumber; i++) {
XTraceSampler::sampler -> setParameter(1 - i);
XTrace::StartTrace("Testing trace");
XTrace::log("Ending trace");
REQUIRE(XTraceBaggage::HasTaskID() == expectedDecisions[i]);
REQUIRE(XTraceBaggage::HasParentEventIDs() == expectedDecisions[i]);
}
}
TEST_CASE( "Check no parents for sample = true", "[sample]" ) {
XTraceSampler::initSampler();
int tracesNumber = 2;
bool expectedDecisions[2] = {false, true};
XTraceSampler::sampler = new XTraceSampler::UniformSampler(1, static_cast<unsigned int>(clock()));
for (int i = 0; i < tracesNumber; i++) {
XTraceSampler::sampler -> setParameter(i);
XTrace::StartTrace("Testing trace");
XTrace::log("Ending trace");
REQUIRE(XTraceBaggage::HasTaskID() == expectedDecisions[i]);
REQUIRE(XTraceBaggage::HasParentEventIDs() == expectedDecisions[i]);
}
PubSub::shutdown();
PubSub::join();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment