|
|
|
|
@ -59,6 +59,11 @@
|
|
|
|
|
|
|
|
|
|
#include <cpp-httplib/httplib.h> |
|
|
|
|
|
|
|
|
|
#ifdef ZT_OTEL_EXPORTER |
|
|
|
|
#include "opentelemetry/exporters/otlp/otlp_grpc_exporter.h" |
|
|
|
|
#include "opentelemetry/sdk/resource/resource.h" |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if ZT_SSO_ENABLED |
|
|
|
|
#include <zeroidc.h> |
|
|
|
|
#endif |
|
|
|
|
@ -912,6 +917,12 @@ class OneServiceImpl : public OneService {
|
|
|
|
|
RedisConfig* _rc; |
|
|
|
|
std::string _ssoRedirectURL; |
|
|
|
|
|
|
|
|
|
#ifdef ZT_OPENTELEMETRY_ENABLED |
|
|
|
|
nostd::shared_ptr<sdktrace::TracerProvider> _traceProvider; |
|
|
|
|
std::string _exporterEndpoint; |
|
|
|
|
double _exporterSampleRate; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// end member variables ----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
OneServiceImpl(const char* hp, unsigned int port) |
|
|
|
|
@ -955,6 +966,11 @@ class OneServiceImpl : public OneService {
|
|
|
|
|
, _run(true) |
|
|
|
|
, _rc(NULL) |
|
|
|
|
, _ssoRedirectURL() |
|
|
|
|
#ifdef ZT_OPENTELEMETRY_ENABLED |
|
|
|
|
, _traceProvider(nullptr) |
|
|
|
|
, _exporterEndpoint() |
|
|
|
|
, _exporterSampleRate(1.0) |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
_ports[0] = 0; |
|
|
|
|
_ports[1] = 0; |
|
|
|
|
@ -1018,6 +1034,58 @@ class OneServiceImpl : public OneService {
|
|
|
|
|
bool pinning = _cpuPinningEnabled; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef ZT_OPENTELEMETRY_ENABLED |
|
|
|
|
void initTracing() |
|
|
|
|
{ |
|
|
|
|
if (! _exporterEndpoint.empty() && _exporterSampleRate > 0.0) { |
|
|
|
|
// Set up OpenTelemetry exporter and tracer provider
|
|
|
|
|
opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts; |
|
|
|
|
opts.endpoint = _exporterEndpoint + "/v1/traces"; |
|
|
|
|
auto exporter = std::unique_ptr<opentelemetry::exporter::otlp::OtlpGrpcExporter>(new opentelemetry::exporter::otlp::OtlpGrpcExporter(opts)); |
|
|
|
|
auto processor = std::unique_ptr<opentelemetry::sdk::trace::SpanProcessor>(new opentelemetry::sdk::trace::SimpleSpanProcessor(std::move(exporter))); |
|
|
|
|
|
|
|
|
|
char buf[16]; |
|
|
|
|
auto versionString = std::stringstream(); |
|
|
|
|
versionString << ZEROTIER_ONE_VERSION_MAJOR << "." << ZEROTIER_ONE_VERSION_MINOR << "." << ZEROTIER_ONE_VERSION_REVISION; |
|
|
|
|
auto resource_attributes = opentelemetry::sdk::resource::ResourceAttributes { { "service.name", "zerotier-one" }, |
|
|
|
|
{ "service.version", versionString.str() }, |
|
|
|
|
{ "service.node_id", _node->identity().address().toString(buf) }, |
|
|
|
|
{ "service.namespace", "com.zerotier.zerotier-one" } }; |
|
|
|
|
auto resource = std::unique_ptr<opentelemetry::sdk::resource::Resource>(new opentelemetry::sdk::resource::Resource(resource_attributes)); |
|
|
|
|
auto sampler = std::unique_ptr<sdktrace::TraceIdRatioBasedSampler>(new sdktrace::TraceIdRatioBasedSampler(_exporterSampleRate)); |
|
|
|
|
auto tracer_context = std::make_shared<sdktrace::TracerContext>(std::move(processor), resource, std::move(sampler)); |
|
|
|
|
_traceProvider = nostd::shared_ptr<sdktrace::TracerProvider>(new sdktrace::TracerProvider(tracer_context)); |
|
|
|
|
opentelemetry::trace::Provider::SetTracerProvider(_traceProvider); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void initMetrics() |
|
|
|
|
{ |
|
|
|
|
if (! _exporterEndpoint.empty()) { |
|
|
|
|
// Set up OpenTelemetry metrics exporter
|
|
|
|
|
opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts; |
|
|
|
|
opts.endpoint = _exporterEndpoint + "/v1/metrics"; |
|
|
|
|
auto exporter = std::unique_ptr<opentelemetry::exporter::otlp::OtlpGrpcExporter>(new opentelemetry::exporter::otlp::OtlpGrpcExporter(opts)); |
|
|
|
|
auto processor = std::unique_ptr<opentelemetry::sdk::metrics::MetricReader>(new opentelemetry::sdk::metrics::PeriodicExportingMetricReader(std::move(exporter), std::chrono::seconds(5))); |
|
|
|
|
auto meter_provider = nostd::shared_ptr<sdkmetrics::MeterProvider>(new sdkmetrics::MeterProvider(std::move(processor))); |
|
|
|
|
opentelemetry::metrics::Provider::SetMeterProvider(meter_provider); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void initLogging() |
|
|
|
|
{ |
|
|
|
|
if (! _exporterEndpoint.empty()) { |
|
|
|
|
// Set up OpenTelemetry logging exporter
|
|
|
|
|
opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts; |
|
|
|
|
opts.endpoint = _exporterEndpoint + "/v1/logs"; |
|
|
|
|
auto exporter = std::unique_ptr<opentelemetry::exporter::otlp::OtlpGrpcExporter>(new opentelemetry::exporter::otlp::OtlpGrpcExporter(opts)); |
|
|
|
|
auto processor = std::unique_ptr<opentelemetry::sdk::logs::LogRecordProcessor>(new opentelemetry::sdk::logs::SimpleLogRecordProcessor(std::move(exporter))); |
|
|
|
|
auto logger_provider = nostd::shared_ptr<sdklogs::LoggerProvider>(new sdklogs::LoggerProvider(std::move(processor))); |
|
|
|
|
opentelemetry::logs::Provider::SetLoggerProvider(logger_provider); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
virtual ReasonForTermination run() |
|
|
|
|
{ |
|
|
|
|
try { |
|
|
|
|
@ -1081,6 +1149,12 @@ class OneServiceImpl : public OneService {
|
|
|
|
|
readLocalSettings(); |
|
|
|
|
applyLocalConfig(); |
|
|
|
|
|
|
|
|
|
#ifdef ZT_OPENTELEMETRY_ENABLED |
|
|
|
|
initTracing(); |
|
|
|
|
initMetrics(); |
|
|
|
|
initLogging(); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// Save original port number to show it if bind error
|
|
|
|
|
const int _configuredPort = _primaryPort; |
|
|
|
|
|
|
|
|
|
@ -1201,6 +1275,7 @@ class OneServiceImpl : public OneService {
|
|
|
|
|
int64_t lastCleanedPeersDb = 0; |
|
|
|
|
int64_t lastLocalConfFileCheck = OSUtils::now(); |
|
|
|
|
int64_t lastOnline = lastLocalConfFileCheck; |
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
|
_run_m.lock(); |
|
|
|
|
if (! _run) { |
|
|
|
|
@ -1516,6 +1591,17 @@ class OneServiceImpl : public OneService {
|
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef ZT_OPENTELEMETRY_ENABLED |
|
|
|
|
json& otel = settings["otel"]; |
|
|
|
|
if (otel.is_object()) { |
|
|
|
|
_exporterEndpoint = OSUtils::jsonString(otel["exporterEndpoint"], ""); |
|
|
|
|
_exporterSampleRate = OSUtils::jsonDouble(otel["exporterSampleRate"], 1.0f); |
|
|
|
|
if (_exporterEndpoint.empty()) { |
|
|
|
|
fprintf(stderr, "WARNING: OpenTelemetry exporter endpoint is not set. Metrics will not be exported." ZT_EOL_S); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// Bind to wildcard instead of to specific interfaces (disables full tunnel capability)
|
|
|
|
|
json& bind = settings["bind"]; |
|
|
|
|
if (bind.is_array()) { |
|
|
|
|
|