Skip to content

Commit ab4bb56

Browse files
committed
Insert logging of file, line and function
Update readme Slightly documentation fixes Some readability fixes
1 parent 072e4c8 commit ab4bb56

File tree

14 files changed

+232
-63
lines changed

14 files changed

+232
-63
lines changed

3rdparty/source_location.hpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#ifndef NOSTD_SOURCE_LOCATION_HPP
2+
#define NOSTD_SOURCE_LOCATION_HPP
3+
4+
#pragma once
5+
6+
#include <cstdint>
7+
8+
namespace nostd {
9+
struct source_location {
10+
public:
11+
#if defined(__clang__) and (__clang_major__ >= 9)
12+
static constexpr source_location current(const char* fileName = __builtin_FILE(),
13+
const char* functionName = __builtin_FUNCTION(),
14+
const uint_least32_t lineNumber = __builtin_LINE(),
15+
const uint_least32_t columnOffset = __builtin_COLUMN()) noexcept
16+
#elif defined(__GNUC__) and (__GNUC__ > 4 or (__GNUC__ == 4 and __GNUC_MINOR__ >= 8))
17+
static constexpr source_location current(const char* fileName = __builtin_FILE(),
18+
const char* functionName = __builtin_FUNCTION(),
19+
const uint_least32_t lineNumber = __builtin_LINE(),
20+
const uint_least32_t columnOffset = 0) noexcept
21+
#else
22+
static constexpr source_location current(const char* fileName = "unsupported",
23+
const char* functionName = "unsupported",
24+
const uint_least32_t lineNumber = 0,
25+
const uint_least32_t columnOffset = 0) noexcept
26+
#endif
27+
{
28+
return source_location(fileName, functionName, lineNumber, columnOffset);
29+
}
30+
31+
source_location(const source_location&) = default;
32+
source_location(source_location&&) = default;
33+
34+
constexpr const char* file_name() const noexcept
35+
{
36+
return fileName;
37+
}
38+
39+
constexpr const char* function_name() const noexcept
40+
{
41+
return functionName;
42+
}
43+
44+
constexpr uint_least32_t line() const noexcept
45+
{
46+
return lineNumber;
47+
}
48+
49+
constexpr std::uint_least32_t column() const noexcept
50+
{
51+
return columnOffset;
52+
}
53+
54+
private:
55+
constexpr source_location(const char* _fileName, const char* _functionName, const uint_least32_t _lineNumber,
56+
const uint_least32_t _columnOffset) noexcept
57+
: fileName(_fileName)
58+
, functionName(_functionName)
59+
, lineNumber(_lineNumber)
60+
, columnOffset(_columnOffset)
61+
{
62+
}
63+
64+
const char* fileName;
65+
const char* functionName;
66+
const std::uint_least32_t lineNumber;
67+
const std::uint_least32_t columnOffset;
68+
};
69+
} // namespace nostd
70+
71+
#endif

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# modern.cpp.logger
2-
Modern C++ logger classes for logging functions in most native and modern C++17.
2+
Modern C++ logger classes for logging functions (thread-safe) in most native and modern C++17.
3+
4+
## Features
5+
- Log a message to /dev/null, stdout, file and file as xml.
6+
- Log a message with severity of Verbose, Debug, Info, Warning, Error and Fatal.
7+
- Log thread-safe from whole application.
8+
- Use compile flag to avoid level below a specified level. Default is LOGGINGINFO.
9+
- Log automatically file, line and function name from logging position (except Visual Studio builds)
310

411
## Build
512
```bash

examples/logger/main.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434

3535
/* modern.cpp.logger */
3636
//#include <FileLogger.h>
37-
//#include <LoggerFactory.h>
37+
#include <LoggerFactory.h>
3838
//#include <Logger.h>
3939
//#include <StdLogger.h>
40-
#include <XmlFileLogger.h>
40+
//#include <XmlFileLogger.h>
4141

4242
using namespace vx;
4343

@@ -62,7 +62,7 @@ constexpr auto logMessage = "This is a log message";
6262
int main() {
6363

6464
/* configure logging, if you dont it defaults to standard out logging with colors */
65-
// vx::configure({ {"type", "file"}, {"filename", "test2.log"}, {"reopen_interval", "1"} });
65+
// vx::configureLogger({ {"type", "file"}, {"filename", "test2.log"}, {"reopen_interval", "1"} });
6666

6767
/* start up some threads */
6868
/* std::vector<std::shared_ptr<std::thread>> threads( std::thread::hardware_concurrency() );
@@ -85,22 +85,22 @@ int main() {
8585
logger.log( logMessage, Severity::Fatal ); */
8686

8787
/* Log to stdout */
88-
/* std::unordered_map<std::string, std::string> configuration = { { "color", "" } };
89-
StdLogger logger( configuration );
90-
logger.log( logMessage, Severity::Fatal ); */
88+
// std::unordered_map<std::string, std::string> configuration = { { "color", "" } };
89+
// StdLogger logger( configuration );
90+
// logger.log( logMessage, Severity::Fatal );
9191

9292
/* Log to file */
9393
/* std::unordered_map<std::string, std::string> configuration = { { "color", "" }, {"filename", "logger.log"} };
9494
FileLogger logger( configuration );
9595
logger.log( logMessage, Severity::Fatal ); */
9696

9797
/* Log to file */
98-
std::unordered_map<std::string, std::string> configuration = { { "color", "" }, {"filename", "logger.xml"} };
99-
XmlFileLogger logger( configuration );
100-
logger.log( logMessage, Severity::Fatal );
98+
// std::unordered_map<std::string, std::string> configuration = { { "color", "" }, {"filename", "logger.xml"} };
99+
// XmlFileLogger logger( configuration );
100+
// logger.log( logMessage, Severity::Fatal );
101101

102102
/* Log with logging factory */
103-
// vx::LogFatal( logMessage );
103+
LogFatal( logMessage );
104104

105105
return EXIT_SUCCESS;
106106
}

source/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ add_library(${PROJECT_NAME}
3737
../README.md
3838
../3rdparty/magic_enum.hpp
3939
../3rdparty/Singleton.h
40+
../3rdparty/source_location.hpp
4041
FileLogger.cpp
4142
FileLogger.h
4243
Logger.cpp

source/FileLogger.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@
4040

4141
namespace vx {
4242

43+
/**
44+
* @brief Reserved overhead for new log entry.
45+
*/
46+
const int overhead = 64;
47+
48+
/**
49+
* @brief Default reopen interval.
50+
*/
51+
const int reopenInterval = 300;
52+
4353
FileLogger::FileLogger( const std::unordered_map<std::string, std::string> &_config )
4454
: Logger( _config ) {
4555

@@ -52,7 +62,7 @@ namespace vx {
5262
m_filename = name->second;
5363

5464
/* if we specify an interval */
55-
m_reopenInterval = std::chrono::seconds( 300 );
65+
m_reopenInterval = std::chrono::seconds( reopenInterval );
5666
auto interval = _config.find( "reopen_interval" );
5767
if ( interval != _config.end() ) {
5868

@@ -70,22 +80,34 @@ namespace vx {
7080
reopen();
7181
}
7282

73-
void FileLogger::log( const std::string &_message, const Severity _severity ) {
83+
void FileLogger::log( const std::string &_message,
84+
const Severity _severity,
85+
const nostd::source_location &_location ) {
7486

75-
if ( avoidLogAbove > _severity ) {
87+
if ( avoidLogBelow > _severity ) {
7688

7789
return;
7890
}
7991

8092
std::string output;
81-
output.reserve( _message.length() + 64 );
93+
output.reserve( _message.size() + overhead );
8294
output.append( timestamp() );
8395

8496
std::string severity = std::string( magic_enum::enum_name( _severity ) );
8597
std::transform( severity.begin(), severity.end(), severity.begin(), []( unsigned char c ) { return ::toupper( c ); } );
8698
output.append( " [" + severity + "] " );
99+
if ( std::string( _location.file_name() ) != "unsupported" ) {
100+
101+
output.append( _location.file_name() );
102+
output.push_back( ':' );
103+
output.append( std::to_string( _location.line() ) );
104+
output.push_back( ' ' );
105+
output.append( _location.function_name() );
106+
output.push_back( ' ' );
107+
}
87108
output.append( _message );
88109
output.push_back( '\n' );
110+
89111
log( output );
90112
}
91113

source/FileLogger.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,11 @@ namespace vx {
6666
* @brief Build the log message.
6767
* @param _message Message to log.
6868
* @param _severity Severity level of the message.
69+
* @param _location Source location information.
6970
*/
70-
virtual void log( const std::string &_message, const Severity _severity ) override;
71+
virtual void log( const std::string &_message,
72+
const Severity _severity,
73+
const nostd::source_location &_location = nostd::source_location::current() ) override;
7174

7275
/**
7376
* @brief Output the log message.
@@ -95,11 +98,11 @@ namespace vx {
9598
/**
9699
* @brief Interval for reopening the log file.
97100
*/
98-
std::chrono::seconds m_reopenInterval;
101+
std::chrono::seconds m_reopenInterval {};
99102

100103
/**
101104
* @brief Timestamp of last reopen activity.
102105
*/
103-
std::chrono::system_clock::time_point m_lastReopen;
106+
std::chrono::system_clock::time_point m_lastReopen {};
104107
};
105108
}

source/Logger.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ namespace vx {
3535

3636
Logger::Logger( [[maybe_unused]] const std::unordered_map<std::string, std::string> &_configuration ) {}
3737

38-
void Logger::log( [[maybe_unused]] const std::string &_message, [[maybe_unused]] const Severity _severity ) { /* /dev/null logger */ }
38+
void Logger::log( [[maybe_unused]] const std::string &_message,
39+
[[maybe_unused]] const Severity _severity,
40+
[[maybe_unused]] const nostd::source_location &_location ) { /* /dev/null logger */ }
3941

4042
void Logger::log( [[maybe_unused]] const std::string &_message ) { /* /dev/null logger */ }
4143
}

source/Logger.h

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
/* stl header */
3434
#include <chrono>
3535
#include <iomanip>
36+
#include <source_location.hpp>
3637
#include <sstream>
3738
#include <string>
3839
#include <unordered_map>
@@ -56,19 +57,19 @@ namespace vx {
5657
};
5758

5859
#if defined(LOGGINGALL) || defined(LOGGINGVERBOSE)
59-
constexpr Severity avoidLogAbove = Severity::Verbose;
60+
constexpr Severity avoidLogBelow = Severity::Verbose;
6061
#elif defined(LOGGINGDEBUG)
61-
constexpr Severity avoidLogAbove = Severity::Debug;
62+
constexpr Severity avoidLogBelow = Severity::Debug;
6263
#elif defined(LOGGINGWARNING)
63-
constexpr Severity avoidLogAbove = Severity::Warning;
64+
constexpr Severity avoidLogBelow = Severity::Warning;
6465
#elif defined(LOGGINGERROR)
65-
constexpr Severity avoidLogAbove = Severity::Error;
66+
constexpr Severity avoidLogBelow = Severity::Error;
6667
#elif defined(LOGGINGFATAL)
67-
constexpr Severity avoidLogAbove = Severity::Fatal;
68+
constexpr Severity avoidLogBelow = Severity::Fatal;
6869
#elif defined(LOGGINGNONE)
69-
constexpr Severity avoidLogAbove = Severity::Fatal + 1;
70+
constexpr Severity avoidLogBelow = Severity::Fatal + 1;
7071
#else
71-
constexpr Severity avoidLogAbove = Severity::Info;
72+
constexpr Severity avoidLogBelow = Severity::Info;
7273
#endif
7374

7475
/**
@@ -84,9 +85,9 @@ namespace vx {
8485
const auto nowMs = std::chrono::duration_cast<std::chrono::microseconds>( now.time_since_epoch() ) % 1000000;
8586

8687
#ifdef _WIN32
87-
localtime_s(&currentLocalTime, &nowAsTimeT);
88+
localtime_s( &currentLocalTime, &nowAsTimeT );
8889
#else
89-
localtime_r(&nowAsTimeT, &currentLocalTime);
90+
localtime_r( &nowAsTimeT, &currentLocalTime );
9091
#endif
9192

9293
std::ostringstream nowSs;
@@ -100,16 +101,6 @@ namespace vx {
100101
return result;
101102
}
102103

103-
// TODO: Currently not used
104-
/* inline std::string threadId() {
105-
106-
std::ostringstream s;
107-
s << " [" << std::this_thread::get_id() << "]";
108-
s.flush();
109-
std::string result = s.str();
110-
return result;
111-
} */
112-
113104
/**
114105
* @brief The Logger class.
115106
* @note Not pure virtual to use as /dev/null logger.
@@ -138,8 +129,11 @@ namespace vx {
138129
* @brief Build the log message.
139130
* @param _message Message to log.
140131
* @param _severity Severity level of the message.
132+
* @param _location Source location information.
141133
*/
142-
virtual void log( const std::string &_message, const Severity _severity );
134+
virtual void log( const std::string &_message,
135+
const Severity _severity,
136+
const nostd::source_location &_location = nostd::source_location::current() );
143137

144138
/**
145139
* @brief Output the log message.

source/LoggerFactory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ namespace vx {
6464
}
6565

6666
/* couldn't get a logger */
67-
throw std::invalid_argument( "Couldn't produce logger for type: " + type->second );
67+
throw std::invalid_argument( "Couldn't produce logger of type: " + type->second );
6868
}
6969
}

0 commit comments

Comments
 (0)