spdlog Source Location Tracking: A Complete Guide to __FILE__, __LINE__, and Function Names
spdlog automatically captures source file paths, line numbers, and function names using the __FILE__, __LINE__, and __func__ macros, storing them in a lightweight source_loc struct that pattern formatters can render with %s or %# flags.
The spdlog logging library provides built-in source location tracking that attaches debugging metadata to every log entry without manual instrumentation. This feature leverages C++ preprocessor macros and optional C++20 std::source_location support to pinpoint exactly where each message originates in your codebase.
The source_loc Data Structure
At the heart of spdlog's location tracking is the source_loc struct defined in include/spdlog/common.h. This lightweight constexpr-capable container stores three essential pointers:
struct source_loc {
constexpr source_loc() = default;
constexpr source_loc(const char *filename_in, int line_in, const char *funcname_in)
: filename{filename_in}, line{line_in}, funcname{funcname_in} {}
constexpr bool empty() const noexcept { return line <= 0; }
const char *filename{nullptr};
int line{0};
const char *funcname{nullptr};
};
The empty() method allows the library to detect when source tracking is disabled or unavailable, ensuring formatters skip rendering location data rather than printing null pointers.
How Macros Inject Source Locations
The library automatically injects location data through the SPDLOG_LOGGER_CALL macro found in include/spdlog/spdlog.h. When you call spdlog::info() or SPDLOG_INFO(), the macro expands to pass a source_loc instance constructed from the current translation unit's __FILE__, __LINE__, and SPDLOG_FUNCTION (which maps to __func__ or __FUNCTION__ depending on your compiler):
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
(logger)->log(SPDLOG_NAMESPACE::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)
This macro feeds into the logger class's overloaded log() methods in include/spdlog/logger.h, specifically the variants accepting a source_loc parameter. The location data ultimately resides in the log_msg structure's source member before reaching sinks and formatters.
Pattern Formatters for Source Output
Once captured, location data is rendered through specialized formatter classes in include/spdlog/pattern_formatter-inl.h. You control the output format using specific pattern flags:
%s– Renders the full location viasource_location_formatter(format:filename:line:funcname)%#– Displays filename and line only via the same formatter (format:filename:line)%t– Filename only viasource_filename_formatter- Additional flags – Line numbers (
%#) and function names (%!) viasource_linenum_formatterandsource_funcname_formatterrespectively
Formatters check msg.source.empty() before writing, ensuring clean output when tracking is disabled.
Practical Usage Examples
Basic Logging with Automatic Location
Simply use standard logging macros; the location attaches automatically:
#include <spdlog/spdlog.h>
int main() {
spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %s:%# %v");
spdlog::info("Application started");
spdlog::error("Failed to open {}", "config.txt");
}
Output:
[2026-07-12 14:23:41.123] [info] main.cpp:5 Application started
[2026-07-12 14:23:41.124] [error] main.cpp:6 Failed to open config.txt
Displaying Only Filename and Line
Use the %# flag to omit function names and print concise file:line references:
spdlog::set_pattern("[%l] %s:%# %v");
C++20 std::source_location Support
If your compiler supports C++20, spdlog accepts std::source_location directly, converting it internally to source_loc:
#include <spdlog/spdlog.h>
#include <source_location>
void log_with_loc(const std::source_location& loc = std::source_location::current()) {
spdlog::log(loc, spdlog::level::info, "Message from helper");
}
int main() {
log_with_loc(); // Prints the call site location, not the helper's location
}
Zero-Cost Disable
Define SPDLOG_DISABLE_SOURCE_LOC before including headers to eliminate all runtime overhead. Macros then pass an empty source_loc{}, and pattern formatters render nothing for location flags:
#define SPDLOG_DISABLE_SOURCE_LOC
#include <spdlog/spdlog.h>
System-Specific Integration
Certain sinks utilize location data beyond text formatting. The systemd_sink in include/spdlog/sinks/systemd_sink.h extracts msg.source to populate structured journal fields (CODE_FILE, CODE_LINE, CODE_FUNC), enabling precise filtering in systemd journal viewers.
Summary
- Location storage: The
source_locstruct ininclude/spdlog/common.hholdsfilename,line, andfuncnameasconst char*andint. - Automatic injection: The
SPDLOG_LOGGER_CALLmacro ininclude/spdlog/spdlog.hpasses__FILE__,__LINE__, andSPDLOG_FUNCTIONtologger::log()overloads. - Pattern control: Use
%sfor full location,%#for file:line, or specific flags like%tfor filename only ininclude/spdlog/pattern_formatter-inl.h. - C++20 support: Pass
std::source_location::current()directly to logging functions. - Zero-cost opt-out: Define
SPDLOG_DISABLE_SOURCE_LOCto compile out all location tracking overhead.
Frequently Asked Questions
How do I show the function name in spdlog output?
Use the %s pattern flag in your formatter, which renders filename:line:funcname. Alternatively, use %! for just the function name. The source_funcname_formatter class in include/spdlog/pattern_formatter-inl.h handles this specific conversion.
Can I use spdlog source location tracking without macros?
Yes. When using C++20, you can pass std::source_location::current() directly to spdlog::log() or logger methods. The library converts this to its internal source_loc type automatically, bypassing the macro layer while maintaining the same metadata.
What is the performance cost of source location tracking?
When enabled, the cost is minimal—only three pointer/size_t copies per log entry. However, you can eliminate all overhead by defining SPDLOG_DISABLE_SOURCE_LOC before including headers. This causes macros to pass empty source_loc{} instances, making the feature zero-cost at runtime.
Why does my output show nothing for %s or %# flags?
This occurs when source location tracking is disabled via SPDLOG_DISABLE_SOURCE_LOC, or when using logging methods that bypass the macros (like direct logger->log() calls without passing a source_loc). Ensure you use the standard SPDLOG_INFO, spdlog::info(), or equivalent macro-based calls to populate the location data.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →