Commit d5762457 authored by Reyhaneh Karimipour's avatar Reyhaneh Karimipour Committed by Jonathan Mace
Browse files

Add sampling interface and tests

parent 45568b1d
build
.DS_Store
.vscode/
\ No newline at end of file
......@@ -2,7 +2,15 @@ cmake_minimum_required(VERSION 3.4.1)
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 ")
......@@ -22,6 +30,7 @@ add_library (libxtrace SHARED
src/xtrace.cpp
src/xtrace_baggage.cpp
src/lexvarint.cpp
src/xtrace_sampler.cpp
${PROTO_SRCS}
)
set_target_properties(libxtrace
......@@ -67,7 +76,25 @@ target_link_libraries(luaxtrace libxtrace Threads::Threads protobuf boost_system
install(TARGETS luaxtrace DESTINATION ${CMAKE_INSTALL_LIBDIR})
# 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)
target_link_libraries(main libxtrace Threads::Threads protobuf boost_system )
include_directories(test)
# 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
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
......
#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 @@
#include <chrono>
#include <time.h>
#include "xtrace_sampler.h"
#include "baggage.h"
#include "xtrace.h"
#include "xtrace.pb.h"
......@@ -121,11 +121,13 @@ void XTrace::Logger::log(std::string file, int line, std::string message, std::m
void XTrace::StartTrace() {
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_label("Start Trace");
sendReport(report);
XTraceReportv4 report = makeReport();
report.set_label("Start Trace");
sendReport(report);
}
}
void XTrace::StartTrace(std::string tag) {
......@@ -134,15 +136,17 @@ void XTrace::StartTrace(std::string tag) {
void XTrace::StartTrace(std::vector<std::string> tags) {
XTraceBaggage::Clear(); // Clear old X-Trace metadata if it exists
XTraceBaggage::SetTaskID(make_event_id());
XTraceReportv4 report = makeReport();
report.set_agent("StartTrace");
report.set_label("Start Trace");
for (int i = 0; i < tags.size(); i++) {
report.add_tags(tags[i]);
if (XTraceSampler::sample()) {
XTraceBaggage::SetTaskID(make_event_id());
XTraceReportv4 report = makeReport();
report.set_agent("StartTrace");
report.set_label("Start Trace");
for (int i = 0; i < tags.size(); i++) {
report.add_tags(tags[i]);
}
sendReport(report);
}
sendReport(report);
}
bool XTrace::IsTracing() {
......
......@@ -96,3 +96,6 @@ void XTraceBaggage::SetParentEventID(uint64_t parentEventId) {
ThreadLocalBaggage::Set(b);
}
bool XTraceBaggage::HasParentEventIDs() {
return GetParentEventIDs().size() != 0;
}
......@@ -13,6 +13,7 @@ void SetTaskID(uint64_t taskId);
std::vector<uint64_t> GetParentEventIDs();
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();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment