# How to Get a Named Logger from the spdlog Registry in C++

> Learn how to get a named logger from the spdlog registry in C++ using spdlog::get or direct registry access for fine-grained control. Optimize your logging setup.

- Repository: [Gabi Melman/spdlog](https://github.com/gabime/spdlog)
- Tags: how-to-guide
- Published: 2026-07-19

---

**Use `spdlog::get("logger_name")` to retrieve a `std::shared_ptr<spdlog::logger>` from the global thread-safe registry, or access the underlying singleton directly via `spdlog::details::registry::instance().get("logger_name")` when you need registry-level control.**

The **gabime/spdlog** library maintains a global registry that maps unique logger names to their `std::shared_ptr<spdlog::logger>` instances. Whether you need to share loggers across translation units or retrieve configuration from a centralized setup, knowing how to get a named logger from the spdlog registry is essential for effective logging in C++ applications. The registry operates as a thread-safe singleton, ensuring concurrent access never corrupts the internal map.

## High-Level API: spdlog::get()

The simplest and most common approach uses the public API defined in [[`include/spdlog/spdlog.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog.h)](https://github.com/gabime/spdlog/blob/v1.x/include/spdlog/spdlog.h). At line 49, the `spdlog::get()` function forwards your request to the registry singleton and returns a shared pointer to the requested logger. If no logger exists with the specified name, it returns `nullptr`.

This method is thread-safe and requires minimal boilerplate, making it the preferred choice for most use cases.

```cpp
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>

int main() {
    // Create and register a logger named "file_logger"
    auto file_logger = spdlog::basic_logger_mt("file_logger", "app.log");
    
    // Later in the code, possibly in another translation unit:
    if (auto logger = spdlog::get("file_logger")) {
        logger->info("Logging from a retrieved logger");
    } else {
        // Logger not found – handle the error
        spdlog::error("Logger \"file_logger\" not found");
    }
}

```

## Low-Level Registry Access

For scenarios requiring direct manipulation of registry internals, you can access the underlying singleton explicitly. The `spdlog::details::registry` class defined in [[`include/spdlog/details/registry.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/details/registry.h)](https://github.com/gabime/spdlog/blob/v1.x/include/spdlog/details/registry.h) at line 36 exposes the same `get()` method through its singleton instance.

Use this approach when you need to interact with other registry methods not exposed by the high-level API, such as manually registering or dropping loggers.

```cpp
#include <spdlog/spdlog.h>
#include <spdlog/details/registry.h>

int main() {
    // Assume a logger named "network" was created elsewhere
    auto &reg = spdlog::details::registry::instance();
    std::shared_ptr<spdlog::logger> net_logger = reg.get("network");

    if (net_logger) {
        net_logger->debug("Network logger retrieved via registry");
    } else {
        spdlog::error("Failed to obtain \"network\" logger from registry");
    }
}

```

## Safety Checks and Null Handling

Both the high-level and low-level APIs return `nullptr` if the logger name was never registered via `spdlog::create<>()`, `spdlog::register_logger()`, or `spdlog::set_default_logger()`. Always validate the returned pointer before dereferencing to avoid undefined behavior.

```cpp
#include <spdlog/spdlog.h>

void log_if_exists(const std::string &name, const std::string &msg) {
    if (auto logger = spdlog::get(name)) {
        logger->info(msg);
    } else {
        spdlog::warn("Attempted to log to non-existent logger '{}'", name);
    }
}

```

## Summary

- **`spdlog::get("name")`** provides the simplest, thread-safe way to retrieve a named logger from the registry defined in [`include/spdlog/spdlog.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog.h).
- **`spdlog::details::registry::instance().get("name")`** offers direct access to the underlying singleton for advanced registry manipulation.
- Both methods return a `std::shared_ptr<spdlog::logger>` or `nullptr` if the logger does not exist.
- Always check the returned pointer before use to ensure the logger was successfully retrieved.

## Frequently Asked Questions

### What does spdlog::get() return if the logger doesn't exist?

`spdlog::get()` returns a default-constructed `std::shared_ptr<spdlog::logger>` containing `nullptr` if no logger with the specified name exists in the registry. You should always check the result with `if (logger)` or `if (logger != nullptr)` before attempting to log messages.

### Is the spdlog registry thread-safe?

Yes. The registry is implemented as a thread-safe singleton using mutex locks to protect the internal map. Both `spdlog::get()` and `registry::instance().get()` can be called concurrently from multiple threads without corrupting the registry state.

### Can I modify a logger after retrieving it from the registry?

Yes. The returned `std::shared_ptr<spdlog::logger>` allows you to modify the logger's settings, including log levels, formatting patterns, and sinks. These changes will affect all other code that holds a reference to the same logger instance, since the registry stores shared ownership.

### What's the difference between spdlog::get() and using the registry singleton directly?

`spdlog::get()` is a convenience wrapper that forwards to `spdlog::details::registry::instance().get()`. The high-level API is preferred for standard retrieval operations, while direct registry access is useful when you need to perform other registry operations—such as `register_logger()`, `drop()`, or `drop_all()`—that are not exposed through the main `spdlog` namespace.