Skip to content

Commit

Permalink
HPCC-30474 Provide JTrace option to declare span start time
Browse files Browse the repository at this point in the history
- Exposes helper method to obtain timestamp in nanos
- Exposes createServerSpan function w/ optional starttime param
- Adds simple cppunit tests excersizing both newly exposed functions

Signed-off-by: Rodrigo Pastrana <[email protected]>
  • Loading branch information
rpastrana committed Dec 8, 2023
1 parent 2c6648f commit 8a8f7ec
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
20 changes: 20 additions & 0 deletions system/jlib/jtrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class CTraceManager : implements ITraceManager, public CInterface
CTraceManager();
IMPLEMENT_IINTERFACE

virtual ISpan * createServerSpan(const char * name, const IProperties * httpHeaders, SpanFlags flags, std::chrono::nanoseconds spanStartTime) const override;
virtual ISpan * createServerSpan(const char * name, StringArray & httpHeaders, SpanFlags flags) const override;
virtual ISpan * createServerSpan(const char * name, const IProperties * httpHeaders, SpanFlags flags) const override;

Expand Down Expand Up @@ -737,6 +738,16 @@ class CServerSpan : public CSpan
}

public:
CServerSpan(const char * spanName, const IProperties * httpHeaders, SpanFlags flags, std::chrono::nanoseconds spanStartTime)
: CSpan(spanName)
{
opts.start_system_time = opentelemetry::common::SystemTimestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(spanStartTime));
opts.kind = opentelemetry::trace::SpanKind::kServer;
setSpanContext(httpHeaders, flags);
init(flags);
setContextAttributes();
}

CServerSpan(const char * spanName, const IProperties * httpHeaders, SpanFlags flags)
: CSpan(spanName)
{
Expand Down Expand Up @@ -808,6 +819,11 @@ class CServerSpan : public CSpan

//---------------------------------------------------------------------------------------------------------------------

std::chrono::nanoseconds nowTimesStampInNanos()
{
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch());
}

IProperties * getClientHeaders(const ISpan * span)
{
Owned<IProperties> headers = createProperties(true);
Expand Down Expand Up @@ -1062,6 +1078,10 @@ ISpan * CTraceManager::createServerSpan(const char * name, const IProperties * h
return new CServerSpan(name, httpHeaders, flags);
}

ISpan * CTraceManager::createServerSpan(const char * name, const IProperties * httpHeaders, SpanFlags flags, std::chrono::nanoseconds spanStartTime) const
{
return new CServerSpan(name, httpHeaders, flags, spanStartTime);
}

//---------------------------------------------------------------------------------------------------------------------

Expand Down
3 changes: 3 additions & 0 deletions system/jlib/jtrace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#ifndef JTRACE_HPP
#define JTRACE_HPP
#include <chrono>

/**
* @brief This follows open telemetry's span attribute naming conventions
Expand Down Expand Up @@ -62,6 +63,7 @@ extern jlib_decl IProperties * getSpanContext(const ISpan * span);

interface ITraceManager : extends IInterface
{
virtual ISpan * createServerSpan(const char * name, const IProperties * httpHeaders, SpanFlags flags, std::chrono::nanoseconds spanStartTime) const = 0;
virtual ISpan * createServerSpan(const char * name, StringArray & httpHeaders, SpanFlags flags = SpanFlags::None) const = 0;
virtual ISpan * createServerSpan(const char * name, const IProperties * httpHeaders, SpanFlags flags = SpanFlags::None) const = 0;
virtual bool isTracingEnabled() const = 0;
Expand All @@ -70,6 +72,7 @@ interface ITraceManager : extends IInterface
extern jlib_decl ISpan * getNullSpan();
extern jlib_decl void initTraceManager(const char * componentName, const IPropertyTree * componentConfig, const IPropertyTree * globalConfig);
extern jlib_decl ITraceManager & queryTraceManager();
extern jlib_decl std::chrono::nanoseconds nowTimesStampInNanos();

//The following class is responsible for ensuring that the active span is restored in a context when the scope is exited
//Use a template class so it can be reused for IContextLogger and IEspContext
Expand Down
13 changes: 13 additions & 0 deletions testing/unittests/jlibtests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class JlibTraceTest : public CppUnit::TestFixture
CPPUNIT_TEST(testNullSpan);
CPPUNIT_TEST(testClientSpanGlobalID);
CPPUNIT_TEST(testEnsureTraceID);
CPPUNIT_TEST(testDeclaredSpanStartTime);
CPPUNIT_TEST_SUITE_END();

const char * simulatedGlobalYaml = R"!!(global:
Expand Down Expand Up @@ -104,6 +105,18 @@ class JlibTraceTest : public CppUnit::TestFixture

protected:

void testDeclaredSpanStartTime()
{
std::chrono::nanoseconds nownanos = nowTimesStampInNanos();
Owned<IProperties> emptyMockHTTPHeaders = createProperties();

Owned<ISpan> serverSpan = queryTraceManager().createServerSpan("declaredSpanStartSpan", emptyMockHTTPHeaders, SpanFlags::None, nownanos);

Owned<IProperties> retrievedSpanCtxAttributes = createProperties();
bool getSpanCtxSuccess = serverSpan->getSpanContext(retrievedSpanCtxAttributes, false);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Unexpected getSpanContext failure detected", true, getSpanCtxSuccess);
}

void testTraceDisableConfig()
{
Owned<IPropertyTree> testTree = createPTreeFromYAMLString(disableTracingYaml, ipt_none, ptr_ignoreWhiteSpace, nullptr);
Expand Down

0 comments on commit 8a8f7ec

Please sign in to comment.