| // Copyright 2026 Google LLC | |
| // | |
| // 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 | |
| // | |
| // https://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 "tracing/tracer_factory.h" | |
| #include <memory> | |
| #include <utility> | |
| #include "absl/base/attributes.h" | |
| #include "absl/base/const_init.h" | |
| #include "absl/base/nullability.h" | |
| #include "absl/strings/string_view.h" | |
| #include "absl/synchronization/mutex.h" | |
| #include "async/async_context.h" | |
| #include "tracing/noop_tracing.h" | |
| #include "tracing/tracer.h" | |
| namespace credentio_tracing { | |
| namespace { | |
| ABSL_CONST_INIT absl::Mutex g_factory_mutex(absl::kConstInit); | |
| // Returns a reference to the global heap-allocated shared_ptr holding the | |
| // registered TracerFactory instance. Defaults to NoopTracerFactory. | |
| std::shared_ptr<TracerFactory>& GlobalFactoryStorage() { | |
| static auto* factory = | |
| new std::shared_ptr<TracerFactory>(std::make_shared<NoopTracerFactory>()); | |
| return *factory; | |
| } | |
| // Returns a reference to the calling thread's factory, which is null unless | |
| // one has been installed. | |
| // | |
| // Unlike the global storage above, this is held by value so that it is released | |
| // when the thread exits; a heap allocation here would be reported as a leak by | |
| // every thread that installs a factory. | |
| std::shared_ptr<TracerFactory>& ThreadLocalFactoryStorage() { | |
| static thread_local std::shared_ptr<TracerFactory> factory; | |
| return factory; | |
| } | |
| } // namespace | |
| void TracerFactory::RegisterGlobalFactory( | |
| absl_nullable std::shared_ptr<TracerFactory> factory) { | |
| absl::MutexLock lock(g_factory_mutex); | |
| if (factory == nullptr) { | |
| factory = std::make_shared<NoopTracerFactory>(); | |
| } | |
| GlobalFactoryStorage() = std::move(factory); | |
| } | |
| absl_nonnull std::shared_ptr<TracerFactory> TracerFactory::GetGlobalFactory() { | |
| absl::MutexLock lock(g_factory_mutex); | |
| return GlobalFactoryStorage(); | |
| } | |
| void TracerFactory::SetThreadLocalFactory( | |
| absl_nullable std::shared_ptr<TracerFactory> factory) { | |
| ThreadLocalFactoryStorage() = std::move(factory); | |
| } | |
| absl_nullable std::shared_ptr<TracerFactory> | |
| TracerFactory::GetThreadLocalFactory() { | |
| return ThreadLocalFactoryStorage(); | |
| } | |
| absl_nonnull std::shared_ptr<TracerFactory> TracerFactory::Get() { | |
| if (std::shared_ptr<TracerFactory> factory = ThreadLocalFactoryStorage(); | |
| factory != nullptr) { | |
| return factory; | |
| } | |
| return GetGlobalFactory(); | |
| } | |
| absl_nonnull std::shared_ptr<TracerFactory> ResolveTracerFactory( | |
| const credentio::AsyncContext& context) { | |
| if (std::shared_ptr<TracerFactory> factory = | |
| context.GetExtension<TracerFactory>(); | |
| factory != nullptr) { | |
| return factory; | |
| } | |
| return TracerFactory::Get(); | |
| } | |
| absl_nonnull std::shared_ptr<Tracer> GetTracer( | |
| absl::string_view tracer_name, const credentio::AsyncContext& context) { | |
| return ResolveTracerFactory(context)->GetTracer(tracer_name); | |
| } | |
| absl_nonnull std::shared_ptr<Tracer> GetTracer(absl::string_view tracer_name) { | |
| return TracerFactory::Get()->GetTracer(tracer_name); | |
| } | |
| } // namespace credentio_tracing |