Line data Source code
1 : #include "source/common/tracing/tracer_manager_impl.h" 2 : 3 : #include "source/common/config/utility.h" 4 : 5 : namespace Envoy { 6 : namespace Tracing { 7 : 8 : SINGLETON_MANAGER_REGISTRATION(tracer_manager); 9 : 10 : TracerManagerImpl::TracerManagerImpl(Server::Configuration::TracerFactoryContextPtr factory_context) 11 96 : : factory_context_(std::move(factory_context)) {} 12 : 13 : TracerSharedPtr 14 0 : TracerManagerImpl::getOrCreateTracer(const envoy::config::trace::v3::Tracing_Http* config) { 15 0 : if (!config) { 16 0 : return null_tracer_; 17 0 : } 18 : 19 0 : const auto cache_key = MessageUtil::hash(*config); 20 0 : const auto it = tracers_.find(cache_key); 21 0 : if (it != tracers_.end()) { 22 0 : auto tracer = it->second.lock(); 23 0 : if (tracer) { // Tracer might have been released since it's a weak reference 24 0 : return tracer; 25 0 : } 26 0 : } 27 : 28 : // Free memory held by expired weak references. 29 : // 30 : // Given that: 31 : // 32 : // * Tracer is obtained only once per listener lifecycle 33 : // * in a typical case, all listeners will have identical tracing configuration and, consequently, 34 : // will share the same Tracer instance 35 : // * amount of memory held by an expired weak reference is minimal 36 : // 37 : // it seems reasonable to avoid introducing an external sweeper and only reclaim memory at 38 : // the moment when a new Tracer instance is about to be created. 39 0 : removeExpiredCacheEntries(); 40 : 41 : // Initialize a new tracer. 42 0 : ENVOY_LOG(info, "instantiating a new tracer: {}", config->name()); 43 : 44 : // Now see if there is a factory that will accept the config. 45 0 : auto& factory = 46 0 : Envoy::Config::Utility::getAndCheckFactory<Server::Configuration::TracerFactory>(*config); 47 0 : ProtobufTypes::MessagePtr message = Envoy::Config::Utility::translateToFactoryConfig( 48 0 : *config, factory_context_->messageValidationVisitor(), factory); 49 : 50 0 : TracerSharedPtr tracer = 51 0 : std::make_shared<Tracing::TracerImpl>(factory.createTracerDriver(*message, *factory_context_), 52 0 : factory_context_->serverFactoryContext().localInfo()); 53 0 : tracers_.emplace(cache_key, tracer); // cache a weak reference 54 0 : return tracer; 55 0 : } 56 : 57 0 : void TracerManagerImpl::removeExpiredCacheEntries() { 58 0 : absl::erase_if(tracers_, [](const std::pair<const std::size_t, std::weak_ptr<Tracer>>& entry) { 59 0 : return entry.second.expired(); 60 0 : }); 61 0 : } 62 : 63 : std::shared_ptr<TracerManager> 64 140 : TracerManagerImpl::singleton(Server::Configuration::FactoryContext& context) { 65 140 : return context.serverFactoryContext().singletonManager().getTyped<Tracing::TracerManagerImpl>( 66 140 : SINGLETON_MANAGER_REGISTERED_NAME(tracer_manager), [&context] { 67 96 : return std::make_shared<Tracing::TracerManagerImpl>( 68 96 : std::make_unique<Tracing::TracerFactoryContextImpl>( 69 96 : context.serverFactoryContext(), context.messageValidationVisitor())); 70 96 : }); 71 140 : } 72 : 73 : } // namespace Tracing 74 : } // namespace Envoy