Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Jaeger exporter #534

Merged
merged 41 commits into from
May 11, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
7cd462f
Initial commit of Jaeger exporter
ThomsonTan Jan 21, 2021
62746e5
Export spans to thrift
ThomsonTan Jan 26, 2021
9fd15a4
Add thrift generated files to repo
ThomsonTan Jan 26, 2021
2081396
Fix CMake script
ThomsonTan Jan 27, 2021
fcb82b7
Add WITH_JAEGER as CMake option
ThomsonTan Jan 28, 2021
eacbe0b
Merge branch 'main' into JaegerExporter
ThomsonTan Jan 28, 2021
5c09997
Merge branch 'main' into JaegerExporter
ThomsonTan Feb 11, 2021
02b3bbd
Merge branch 'main' into JaegerExporter
ThomsonTan Feb 17, 2021
a3a08ad
Merge branch 'main' into JaegerExporter
ThomsonTan Feb 22, 2021
5d8140b
Fix build
ThomsonTan Feb 24, 2021
ca66fed
Format changed files
ThomsonTan Feb 24, 2021
8a7fa9f
Merge branch 'main' into JaegerExporter
ThomsonTan Apr 1, 2021
f7f6d79
Merge branch 'main' into JaegerExporter
ThomsonTan Apr 2, 2021
64672ba
Tmp change
ThomsonTan Apr 5, 2021
dbed4aa
Merge branch 'main' into JaegerExporter
ThomsonTan Apr 5, 2021
4bde77a
Add TUDPTransport
ThomsonTan Apr 8, 2021
0a64e80
Add max UDP packet size check
ThomsonTan Apr 8, 2021
6cbffcf
Move exception handling close to emitBatch in AgentClient
ThomsonTan Apr 8, 2021
d09aa9b
Merge remote-tracking branch 'origin' into JaegerExporter
ThomsonTan Apr 8, 2021
fd3d26f
Add example_jaeger
ThomsonTan Apr 8, 2021
04581ee
Initialize winsock
ThomsonTan Apr 8, 2021
0d74fac
Remove Jaeger IDL from submodule list which is no longer necessary
ThomsonTan Apr 8, 2021
f337341
Add CleanSocket call
ThomsonTan Apr 8, 2021
e58b00b
Add mutex to avoid race condition in Jaeger exporter
ThomsonTan Apr 9, 2021
843e2c6
Update readme.txt
ThomsonTan Apr 9, 2021
accce34
Fix format
ThomsonTan Apr 9, 2021
05a7f42
Disable build Jaeger exporter/example in bazel build
ThomsonTan Apr 9, 2021
adb49c4
Remove boost dependence
ThomsonTan Apr 13, 2021
b443819
Merge branch 'main' into JaegerExporter
ThomsonTan Apr 20, 2021
8e6c3a1
Address feedback and rebase to latest main
ThomsonTan Apr 20, 2021
9a980ad
Merge branch 'main' into JaegerExporter
ThomsonTan Apr 23, 2021
aeadf81
Add README.md for Jaeger exporter
ThomsonTan Apr 23, 2021
e1b93df
Merge branch 'main' into JaegerExporter
ThomsonTan May 5, 2021
3d9597d
Add resource and instrumentation library to jaeger exporter
ThomsonTan May 5, 2021
d7c3498
Populate resource to Jaeger service name
ThomsonTan May 5, 2021
2027eb9
Format markdown README
ThomsonTan May 5, 2021
ec6ee47
Clang-format
ThomsonTan May 5, 2021
6d09836
Flush batch and remove lock on Jaeger exporter sender.
ThomsonTan May 5, 2021
c962561
Fix Linux build
ThomsonTan May 6, 2021
3f2ef72
Merge branch 'main' into JaegerExporter
lalitb May 10, 2021
e38dec6
Merge branch 'main' into JaegerExporter
lalitb May 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@
path = third_party/nlohmann-json
url = https://github.com/nlohmann/json
branch = master
[submodule "third_party/jaeger-idl"]
path = third_party/jaeger-idl
url = https://github.com/jaegertracing/jaeger-idl
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK"
option(WITH_ELASTICSEARCH
"Whether to include the Elasticsearch Client in the SDK" OFF)

option(WITH_JAEGER "Whether to include the Jaeger exporter" OFF)

option(BUILD_TESTING "Whether to enable tests" ON)
if(WIN32)
option(WITH_ETW "Whether to include the ETW Exporter in the SDK" ON)
Expand Down
4 changes: 4 additions & 0 deletions exporters/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ endif()
if(WITH_ETW)
add_subdirectory(etw)
endif()

if(WITH_JAEGER)
add_subdirectory(jaeger)
endif()
35 changes: 35 additions & 0 deletions exporters/jaeger/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2020, OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include_directories(include)

find_package(Boost REQUIRED)
find_package(thrift REQUIRED)

set(JAEGER_THRIFT_GENCPP_SOURCES
thrift-gen/Agent.cpp
thrift-gen/jaeger_types.cpp
thrift-gen/Collector.cpp
)

add_library(jaeger_trace_exporter ${JAEGER_THRIFT_GENCPP_SOURCES})
target_link_libraries(jaeger_trace_exporter PRIVATE thrift::thrift Boost::boost)

if(BUILD_TESTING)
# add_executable(jaeger_exporter_test )
# target_link_libraries(jaeger_exporter_test ${GTEST_BOTH_LIBRARIES})
# ${CMAKE_THREAD_LIBS_INIT} jaeger_trace_exporter)
#
# gtest_add_tests()
endif() # BUILD_TESTING
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2020, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <opentelemetry/sdk/trace/exporter.h>
#include <memory>

OPENTELEMETRY_BEGIN_NANESPACE
namespace exporter
{
namespace jaeger
{
enum class TransportType
{
THRIFT_UDP,
};

/**
* Struct to hold Jaeger exporter options.
*/
struct JaegerExporterOptions
{
// The endpoint to export to.
std::string server_addr = "localhost";
uint16_t server_port = 9090;
TransportType transport_type = THRIFT_UDP;
};

namespace trace_sdk = opentelemetry::sdk::trace;

class JaegerExporter final : public trace_sdk::SpanExporter
{
public:
/**
* Create a JaegerExporter using all default options.
*/
JaegerExporter();

/**
* Export a batch of spans.
* @param spans a span of unique pointers to span recordables.
*/
trace_sdk::ExportResult Export(
const nostd::span<std::unique_ptr<trace_sdk::Recordable>> &spans) noexcept override;

/**
* Shutdown the exporter.
* @param timeout an option timeout, default to max.
*/
bool Shutdown(
std::chrono::microseconds timeout = std::chrono::microseconds::max() noexcept override;)
{
return true;
}

private:
void InitializeEndpoint();

private:
// The configuration options associated with this exporter.
bool is_shutdown_ = false;
JaegerExporterOptions options_;
std::unique_ptr<ThriftSender> sender_;
};

} // namespace jaeger
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2020, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <opentelemetry/sdk/trace/recordable.h>
#include <opentelemetry/version.h>
#include <thrift-gen/cpp/jaeger_types.h>

OPENTELEMETRY_BEGIN_NANESPACE
namespace exporter
{
namespace jaeger
{
class Recordable final : public sdk::trace::Recordable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Not something which needs immediate attention, but probably we should have recordable names after transport types - eg TUDPRecordable. This is an issue with Zipkin exporter too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. I logged the same comment for ETW exporter. I think we could create a task for the cleanup for all the exporters? I'll try the renaming anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created issue #735 for this.

{
public:
const thrift::Span &span() const noexcept { return span_; }

voiid SetIds(trace::TraceId trace_id,
trace::SpanId span_id,
trace::SpanId parent_span_id) noexcept override;

void SetAttribute(nostd::string_view key,
const opentelemetry::common::AttributeValue &value) noexcept override;

void AddEvent(nostd::string_view key,
core::SystemTimestamp timestamp,
const common::KeyValueIterable &attributes) noexcept override;

void AddLink(const opentelemetry::trace::SpanContext &span_context const common::KeyValueIterable
&attributes) noexcept override;

void SetStatus(trace::CanonicalCode code, nostd::string_view description) noexcept override;

void SetName(nostd::string_view name) noexcept override;

void SetStartTime(opentelemetry::core::SystemTimestamp start_time) noexcept override;

void SetSpanKind(opentelemtry::trace::SpanKind span_kind) noexcept override;

private:
thrift::Span span_;
};
} // namespace jaeger
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2020, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <thrift-gen/cpp/agent.h>
#include <vector>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace jaeger
{

class ThriftSender
{
public:
ThriftSender();
~ThriftSender();

int Append(std::shared_ptr<thrift::Span> span);
int Flush();

private:
std::vector<thrift::Span> _spanBuffer;
};

} // namespace jaeger
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2020, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <thrift-gen/cpp/jaeger_types.h>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace jaeger
{

class Transport
{
public:
Transport() = default;
virtual ~Transport() = default;

virtual void EmitBatch(const thrift::Batch &batch) = 0;
};

} // namespace jaeger
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@

// Copyright 2020, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "transport.h"

#include <thrift-gen/cpp/agent.h>
#include <thrift/transport/TSocket.h>
#include <memory>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace jaeger
{

namespace AgentClient = jagertracing::agent::thrift::AgentClient;

class UDPTransport : public Transport
{
pubilc : UDPTransport(const std::string &addr, uint16_t port);
~UDPTransport();

void EmitBatch(const thrift::Batch &batch) override;

private:
std::unique_ptr<AgentClient> agent_;
std::shared_ptr<TTransport> socket_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these shared_ptr?

There's ref-counting overhead vs. unique_ptr. Are these actually shared?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Josh. Yes, I also prefer unique_ptr if possible. For the cases of using shared_ptr, that would be needed as it is required to be passed to other functions as shared_ptr, so I just created it as shared_ptr in the first place.

std::shared_ptr<TTransport> transport_;
std::shared_ptr<TTransport> protocol_;
};

} // namespace jaeger
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
71 changes: 71 additions & 0 deletions exporters/jaeger/src/jaeger_exporter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright 2020, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <opentelemetry/exporters/jaeger/jaeger_exporter.h>
#include <opentelemetry/exporters/jaeger/recordable.h>
#include <thrift-gen/cpp/agent_types.h>

#include <vector>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace jaeger
{

JaegerExporter::JaegerExporter(const JaegerExporterOptions &options) : options_(options)
{
InitializeEndpoint();
}

JaegerExporter::JaegerExporter() : JaegerExporter(JaegerExporterOptions()) {}

std::unique_ptr<std::trace::Recordable> JaegerExporter::MakeRecordable() noexcept
{
return std::unique_ptr<sdk::trace::Recordable>(new (nothrow) Recordable);
}

std::trace::ExportResult JaegerExporter::Export(
const nostd::span<std::unique_ptr<std::trace::Recordable>> &spans) noexcept
{
if (is_shutdown_)
{
return sdk::trace::ExportResult::kFailuer;
}
std::vector<thrift::Span> spans{spans};

thrift::Batch batch;
// batch.__set_process(_process);
batch.__set_spans(_spanBuffer);

sender_.EmitBatch(batch);

return sdk::trace::ExportResult::kSuccess;
}

void JaegerExporter::InitializeEndpoint()
{
if (options.transport_type == THRIFT_UDP)
{
sender_ =
std::unique_ptr<ThriftSender>(new ThriftSender(options.server_addr, options.server_port));
}
else
{
static_assert(false, "Unsupported transport type");
}
}

} // namespace jaeger
} // namespace exporter
Loading