blob: eaacba93f94967f5ce6a03b80ac100e4e92c9205 [file] [edit]
// 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