ndmspc  v1.2.0-0.1.rc3
Ndmspc::NLogger Class Reference

Thread-safe singleton logger with per-thread file output. More...

#include <NLogger.h>

Public Member Functions

 NLogger ()
 Constructs a new NLogger instance.
 
virtual ~NLogger ()
 Destroys the NLogger instance.
 
 NLogger (const NLogger &)=delete
 
NLoggeroperator= (const NLogger &)=delete
 

Static Public Member Functions

static NLoggerInstance ()
 Returns the singleton instance of NLogger. More...
 
static std::string SeverityToString (logs::Severity level)
 Converts a logs::Severity enum value to its string representation. More...
 
static logs::Severity GetSeverityFromString (const std::string &severity_str)
 Parses a string to obtain the corresponding logs::Severity enum value. More...
 
static void Log (const char *file, int line, logs::Severity level, const char *format,...)
 Logs a formatted message with the specified severity level. More...
 
static void SetMinSeverity (logs::Severity level)
 Sets the minimum severity level for logging. More...
 
static logs::Severity GetMinSeverity ()
 Gets the current minimum severity level for logging. More...
 
static void SetLogDirectory (const std::string &dir)
 Sets the directory where log files will be stored. More...
 
static void SetConsoleOutput (bool enable)
 Enables or disables logging output to the console. More...
 
static void SetFileOutput (bool enable)
 Enables or disables logging output to a file. More...
 
static void SetProcessName (const std::string &name)
 Sets the name of the current process. More...
 
static std::string GetProcessName ()
 Retrieves the name of the current process. More...
 
static void SetThreadName (const std::string &name, std::thread::id thread_id=std::this_thread::get_id())
 Sets the name of a thread. More...
 
static std::string GetThreadName ()
 Retrieves the name of the current thread. More...
 
static bool GetConsoleOutput ()
 Get console output flag.
 
static bool GetFileOutput ()
 Get file output flag.
 
static std::string GetLogDirectory ()
 Get log directory path.
 
static std::mutex & GetLoggerMutex ()
 Get logger mutex reference.
 

Private Member Functions

void Init ()
 Initializes the logger.
 
void Cleanup ()
 Cleans up logger resources.
 
std::ofstream & GetThreadStream ()
 Retrieves the thread-local output file stream for logging. More...
 
void CloseThreadStream (std::thread::id thread_id)
 Closes and removes the output file stream associated with a specific thread. More...
 
std::string GetThreadIdentifier ()
 Get thread name or ID as string.
 

Private Attributes

std::mutex fStreamMapMutex
 
std::unordered_map< std::thread::id, std::unique_ptr< std::ofstream > > fThreadStreams
 Map storing unique output file streams for each thread. More...
 
std::unordered_map< std::thread::id, std::string > fThreadNames
 Map of thread IDs to custom thread names.
 

Static Private Attributes

static std::mutex fgLoggerMutex
 Mutex for thread-safe singleton access.
 
static logs::Severity fgMinSeverity = logs::Severity::kInfo
 Minimum severity level for logging.
 
static std::string fgLogDirectory = "/tmp/.ndmspc/logs"
 Directory for log files.
 
static bool fgConsoleOutput = true
 Flag for console output.
 
static bool fgFileOutput = false
 Flag for file output.
 
static std::string fgProcessName = ""
 Process name prefix for log files.
 
static std::unique_ptr< NLoggerfgLogger
 Singleton instance.
 

Detailed Description

Thread-safe singleton logger with per-thread file output.

NLogger provides a thread-safe logging system where each thread can write to its own log file. Supports multiple severity levels, console and file output, and custom naming for processes and threads.

Author
Martin Vala mvala.nosp@m.@cer.nosp@m.n.ch
Example Usage:
// Configure logger
// Log messages
NLogInfo("Application started");
NLogDebug("Debug info: value=%d", 42);
static void SetProcessName(const std::string &name)
Sets the name of the current process.
Definition: NLogger.cxx:126
static void SetFileOutput(bool enable)
Enables or disables logging output to a file.
Definition: NLogger.h:521
Thread Safety:
All methods are thread-safe. Each thread gets its own file stream.
Environment Variables:
  • NDMSPC_LOG_LEVEL: Set minimum severity
  • NDMSPC_LOG_FILE: Enable file output (1/true/TRUE)
  • NDMSPC_LOG_CONSOLE: Enable console output (0/1/false/true)
  • NDMSPC_LOG_DIR: Set log directory
  • NDMSPC_PROCESS_NAME: Set process name
  • NDMSPC_MAIN_THREAD_NAME: Set main thread name

Introduction

NLogger is a thread-safe logging system for C++ applications with per-thread log files, configurable severity levels, and flexible output options.

Key Features

  • Thread-safe logging: Multiple threads can log simultaneously without conflicts
  • Per-thread log files: Each thread writes to its own dedicated log file
  • Configurable severity levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL
  • Multiple output modes: Console only, file only, both, or neither
  • Custom naming: Set process names and thread names
  • Environment variable configuration: Configure without code changes
  • Millisecond-precision timestamps

Quick Start

Basic Usage

#include "NLogger.h"
int main() {
// Simple logging (console by default)
NLogInfo("Application started");
NLogDebug("Debug: value = %d", 42);
NLogWarning("Warning message");
NLogError("Error: %s", error_msg);
return 0;
}

Multi-threaded Example

void worker(int id) {
Ndmspc::NLogger::SetThreadName("Worker_" + std::to_string(id));
NLogInfo("Worker %d started", id);
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join();
t2.join();
return 0;
}
static void SetThreadName(const std::string &name, std::thread::id thread_id=std::this_thread::get_id())
Sets the name of a thread.
Definition: NLogger.cxx:132
static void SetLogDirectory(const std::string &dir)
Sets the directory where log files will be stored.
Definition: NLogger.cxx:113

Logging Macros

Available Macros

Macro Level Description
NLogTrace(format, ...) TRACE Detailed trace information
NLogDebug(format, ...) DEBUG Debug info (includes file:line)
NLogInfo(format, ...) INFO Informational messages
NLogWarning(format, ...) WARN Warning messages
NLogError(format, ...) ERROR Error messages
NLogFatal(format, ...) FATAL Fatal error messages

Generic Macro

NLog(level, format, ...)
// Example:
NLog(Ndmspc::logs::Severity::kDebug, "Custom: %d", value);

Severity Levels

Each level has 4 variants (e.g., TRACE, TRACE2, TRACE3, TRACE4):

TRACE (most verbose) → DEBUG → INFO (default) → WARN → ERROR → FATAL (least verbose)

// Set minimum severity
Ndmspc::NLogger::SetMinSeverity(Ndmspc::logs::Severity::kDebug);
static void SetMinSeverity(logs::Severity level)
Sets the minimum severity level for logging.
Definition: NLogger.h:497

Configuration API

Process and Thread Naming

// Set process name (prefix for all log files)
// Set thread name for current thread
// Get names
std::string proc = Ndmspc::NLogger::GetProcessName();
std::string thread = Ndmspc::NLogger::GetThreadName();
static std::string GetThreadName()
Retrieves the name of the current thread.
Definition: NLogger.cxx:138
static std::string GetProcessName()
Retrieves the name of the current process.
Definition: NLogger.h:533

Output Configuration

Ndmspc::NLogger::SetFileOutput(true); // default: false
Ndmspc::NLogger::SetConsoleOutput(true); // default: true
Ndmspc::NLogger::SetLogDirectory("./logs"); // default: "./logs"
Ndmspc::NLogger::SetMinSeverity(Ndmspc::logs::Severity::kDebug);
static void SetConsoleOutput(bool enable)
Enables or disables logging output to the console.
Definition: NLogger.h:515

Environment Variables

Variable Default Description
NDMSPC_LOG_LEVEL INFO Minimum severity (TRACE/DEBUG/INFO/WARN/ERROR/FATAL)
NDMSPC_LOG_FILE false Enable file output (1/true/TRUE)
NDMSPC_LOG_CONSOLE true Enable console output (0/1/false/true)
NDMSPC_LOG_DIR ./logs Log directory path
NDMSPC_PROCESS_NAME pid_<PID> Process name prefix
NDMSPC_MAIN_THREAD_NAME MainThread Main thread name

Environment Variable Examples

# Enable file logging with DEBUG level
NDMSPC_LOG_FILE=1 NDMSPC_LOG_LEVEL=DEBUG ./my_app
# File only, no console
NDMSPC_LOG_FILE=1 NDMSPC_LOG_CONSOLE=0 ./my_app
# Full configuration
NDMSPC_PROCESS_NAME=DataProcessor \
NDMSPC_LOG_LEVEL=DEBUG \
NDMSPC_LOG_FILE=1 \
NDMSPC_LOG_DIR=/var/log/myapp \
./my_app

Log File Naming

Pattern: <LogDirectory>/<ProcessName>_<ThreadName>.log

Examples:

  • ./logs/MyApp_MainThread.log
  • ./logs/MyApp_Worker_1.log
  • ./logs/pid_12345_DatabaseThread.log

Log Format

Standard format:

[YYYY-MM-DD HH:MM:SS.mmm] [LEVEL] Message

Debug format (includes file:line):

[YYYY-MM-DD HH:MM:SS.mmm] [DEBUG] [main.cpp:42] Message

Each log file starts with:

=== Log started at Mon Dec 16 17:30:45 2024
=== Process: MyApplication (PID: 12345)
=== Thread: WorkerThread
static void Log(const char *file, int line, logs::Severity level, const char *format,...)
Logs a formatted message with the specified severity level.
Definition: NLogger.cxx:253

Common Use Cases

Console Only (Default)

NLogInfo("Simple console logging");

File Only

Multi-threaded with Named Threads

void processor(int id) {
Ndmspc::NLogger::SetThreadName("Processor_" + std::to_string(id));
NLogInfo("Processing started");
// ... work ...
NLogInfo("Processing complete");
}
int main() {
std::thread t1(processor, 1);
std::thread t2(processor, 2);
t1.join();
t2.join();
}

Creates:

  • DataPipeline_MainThread.log
  • DataPipeline_Processor_1.log
  • DataPipeline_Processor_2.log

Best Practices

  1. Set severity appropriately: Use DEBUG/TRACE for development, INFO+ for production
  2. Name your threads: Easier debugging and log analysis
  3. Avoid tight loops: Don't log in high-frequency loops
  4. Use environment variables: Easy configuration without recompilation
// Good
void worker_thread() {
Ndmspc::NLogger::SetThreadName("Worker"); // Set once
for (int i = 0; i < 1000000; ++i) {
if (i % 10000 == 0) NLogDebug("Progress: %d", i); // Periodic
}
}
// Bad
for (int i = 0; i < 1000000; ++i) {
NLogTrace("Processing %d", i); // Too much overhead!
}

Troubleshooting

No log files created

Ndmspc::NLogger::SetFileOutput(true); // Ensure enabled

Or:

NDMSPC_LOG_FILE=1 ./my_app

No console output

Or:

NDMSPC_LOG_CONSOLE=1 NDMSPC_LOG_LEVEL=TRACE ./my_app`

Too verbose

Ndmspc::NLogger::SetMinSeverity(Ndmspc::logs::Severity::kWarn);

Or:

NDMSPC_LOG_LEVEL=ERROR ./my_app`

Definition at line 446 of file NLogger.h.

Member Function Documentation

◆ CloseThreadStream()

void Ndmspc::NLogger::CloseThreadStream ( std::thread::id  thread_id)
private

Closes and removes the output file stream associated with a specific thread.

Parameters
thread_idThe ID of the thread whose stream should be closed.

Definition at line 223 of file NLogger.cxx.

References fStreamMapMutex, fThreadNames, and fThreadStreams.

◆ GetMinSeverity()

static logs::Severity Ndmspc::NLogger::GetMinSeverity ( )
inlinestatic

Gets the current minimum severity level for logging.

Returns
The current minimum severity level.

Definition at line 503 of file NLogger.h.

References fgMinSeverity.

Referenced by Log().

◆ GetProcessName()

static std::string Ndmspc::NLogger::GetProcessName ( )
inlinestatic

Retrieves the name of the current process.

Returns
The process name as a string.

Definition at line 533 of file NLogger.h.

References fgProcessName.

◆ GetSeverityFromString()

logs::Severity Ndmspc::NLogger::GetSeverityFromString ( const std::string &  severity_str)
static

Parses a string to obtain the corresponding logs::Severity enum value.

Parameters
severity_strThe string representation of the severity.
Returns
The corresponding logs::Severity value.

Definition at line 243 of file NLogger.cxx.

Referenced by Init().

◆ GetThreadName()

std::string Ndmspc::NLogger::GetThreadName ( )
static

Retrieves the name of the current thread.

Returns
The thread name as a string.

Definition at line 138 of file NLogger.cxx.

References fStreamMapMutex, fThreadNames, and Instance().

◆ GetThreadStream()

std::ofstream & Ndmspc::NLogger::GetThreadStream ( )
private

Retrieves the thread-local output file stream for logging.

Ensures that each thread has its own output file stream for writing log messages, creating a new stream if one does not already exist for the current thread.

Returns
Reference to the thread's std::ofstream.

Definition at line 170 of file NLogger.cxx.

References fgLogDirectory, fgProcessName, fStreamMapMutex, fThreadStreams, and GetThreadIdentifier().

◆ Instance()

NLogger * Ndmspc::NLogger::Instance ( )
static

Returns the singleton instance of NLogger.

Returns
Pointer to the singleton NLogger.

Definition at line 36 of file NLogger.cxx.

Referenced by GetThreadName(), Log(), and SetThreadName().

◆ Log()

void Ndmspc::NLogger::Log ( const char *  file,
int  line,
logs::Severity  level,
const char *  format,
  ... 
)
static

Logs a formatted message with the specified severity level.

Parameters
fileThe name of the source file where the log is generated.
lineThe line number in the source file where the log is generated.
levelThe severity level of the log message.
formatThe printf-style format string for the log message.
...Additional arguments for the format string.

Definition at line 253 of file NLogger.cxx.

References GetMinSeverity(), Instance(), and SeverityToString().

◆ SetConsoleOutput()

static void Ndmspc::NLogger::SetConsoleOutput ( bool  enable)
inlinestatic

Enables or disables logging output to the console.

Parameters
enableTrue to enable console output, false to disable.

Definition at line 515 of file NLogger.h.

References fgConsoleOutput.

◆ SetFileOutput()

static void Ndmspc::NLogger::SetFileOutput ( bool  enable)
inlinestatic

Enables or disables logging output to a file.

Parameters
enableTrue to enable file output, false to disable.

Definition at line 521 of file NLogger.h.

References fgFileOutput.

◆ SetLogDirectory()

void Ndmspc::NLogger::SetLogDirectory ( const std::string &  dir)
static

Sets the directory where log files will be stored.

Parameters
dirThe path to the log directory.

Definition at line 113 of file NLogger.cxx.

References fgFileOutput, and fgLogDirectory.

◆ SetMinSeverity()

static void Ndmspc::NLogger::SetMinSeverity ( logs::Severity  level)
inlinestatic

Sets the minimum severity level for logging.

Parameters
levelThe minimum severity level to be set.

Definition at line 497 of file NLogger.h.

References fgMinSeverity.

◆ SetProcessName()

void Ndmspc::NLogger::SetProcessName ( const std::string &  name)
static

Sets the name of the current process.

Parameters
nameThe name to assign to the process.

Definition at line 126 of file NLogger.cxx.

References fgLoggerMutex, and fgProcessName.

◆ SetThreadName()

void Ndmspc::NLogger::SetThreadName ( const std::string &  name,
std::thread::id  thread_id = std::this_thread::get_id() 
)
static

Sets the name of a thread.

Parameters
nameThe name to assign to the thread.
thread_idThe ID of the thread to name (defaults to current thread).

Definition at line 132 of file NLogger.cxx.

References fStreamMapMutex, fThreadNames, and Instance().

Referenced by Ndmspc::NDimensionalExecutor::ExecuteParallel().

◆ SeverityToString()

std::string Ndmspc::NLogger::SeverityToString ( logs::Severity  level)
static

Converts a logs::Severity enum value to its string representation.

Parameters
levelThe severity level to convert.
Returns
The string representation of the severity level.

Definition at line 230 of file NLogger.cxx.

Referenced by Log().

Member Data Documentation

◆ fStreamMapMutex

std::mutex Ndmspc::NLogger::fStreamMapMutex
private

Mutex for synchronizing access to the thread stream map.

Definition at line 589 of file NLogger.h.

Referenced by Cleanup(), CloseThreadStream(), GetThreadName(), GetThreadStream(), and SetThreadName().

◆ fThreadStreams

std::unordered_map<std::thread::id, std::unique_ptr<std::ofstream> > Ndmspc::NLogger::fThreadStreams
private

Map storing unique output file streams for each thread.

Maps thread IDs to their corresponding std::ofstream instances.

Definition at line 596 of file NLogger.h.

Referenced by Cleanup(), CloseThreadStream(), and GetThreadStream().


The documentation for this class was generated from the following files: