Commit 0ae66b5b authored by gabime's avatar gabime

support for external fmtlib

parent f702dce6
...@@ -13,96 +13,112 @@ ...@@ -13,96 +13,112 @@
void async_example(); void async_example();
void syslog_example(); void syslog_example();
void user_defined_example();
namespace spd = spdlog; namespace spd = spdlog;
int main(int, char*[]) int main(int, char*[])
{ {
try try {
{ // Multithreaded color console
// Multithreaded color console auto console = spd::stdout_logger_mt("console", true);
auto console = spd::stdout_logger_mt("console", true); console->info("Welcome to spdlog!");
console->info("Welcome to spdlog!"); console->error("An info message example {}..", 1);
console->error("An info message example {}..", 1);
// Formatting examples
// Formatting examples console->warn("Easy padding in numbers like {:08d}", 12);
console->warn("Easy padding in numbers like {:08d}", 12); console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); console->info("Support for floats {:03.2f}", 1.23456);
console->info("Support for floats {:03.2f}", 1.23456); console->info("Positional args are {1} {0}..", "too", "supported");
console->info("Positional args are {1} {0}..", "too", "supported");
console->info("{:<30}", "left aligned");
console->info("{:<30}", "left aligned"); console->info("{:>30}", "right aligned");
console->info("{:>30}", "right aligned"); console->info("{:^30}", "centered");
console->info("{:^30}", "centered");
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
// Runtime log levels
// Runtime log levels spd::set_level(spd::level::info); //Set global log level to info
spd::set_level(spd::level::info); //Set global log level to info console->debug("This message shold not be displayed!");
console->debug("This message shold not be displayed!"); console->set_level(spd::level::debug); // Set specific logger's log level
console->set_level(spd::level::debug); // Set specific logger's log level console->debug("This message shold be displayed..");
console->debug("This message shold be displayed..");
// Create basic file logger (not rotated)
// Create basic file logger (not rotated) auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt");
auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt"); my_logger->info("Some log message");
my_logger->info("Some log message");
// Create a file rotating logger with 5mb size max and 3 rotated files
// Create a file rotating logger with 5mb size max and 3 rotated files auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3);
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3); for (int i = 0; i < 10; ++i)
for (int i = 0; i < 10; ++i) rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);
rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);
// Create a daily logger - a new file is created every day on 2:30am
// Create a daily logger - a new file is created every day on 2:30am auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30);
auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30); daily_logger->info(123.44);
daily_logger->info(123.44);
// Customize msg format for all messages
// Customize msg format for all messages spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); rotating_logger->info("This is another message with custom format");
rotating_logger->info("This is another message with custom format");
// Compile time debug or trace macros.
// Compile time debug or trace macros. // Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON
// Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
// Asynchronous logging is very fast..
// Asynchronous logging is very fast.. // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous.. async_example();
async_example();
// syslog example. linux/osx only..
// syslog example. linux/osx only.. syslog_example();
syslog_example();
// log user-defined types example..
user_defined_example();
// Release and close all loggers
spdlog::drop_all();
} // Release and close all loggers
spdlog::drop_all();
catch (const spd::spdlog_ex& ex) }
{
std::cout << "Log failed: " << ex.what() << std::endl; catch (const spd::spdlog_ex& ex) {
return EXIT_FAILURE; std::cout << "Log failed: " << ex.what() << std::endl;
} return EXIT_FAILURE;
return EXIT_SUCCESS; }
return EXIT_SUCCESS;
} }
void async_example() void async_example()
{ {
size_t q_size = 4096; //queue size must be power of 2 size_t q_size = 4096; //queue size must be power of 2
spdlog::set_async_mode(q_size); spdlog::set_async_mode(q_size);
auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt"); auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
async_file->info("Async message #{}", i); async_file->info("Async message #{}", i);
} }
//syslog example (linux/osx only) //syslog example (linux/osx only)
void syslog_example() void syslog_example()
{ {
#if defined (__linux__) || defined(__APPLE__) #if defined (__linux__) || defined(__APPLE__)
std::string ident = "spdlog-example"; std::string ident = "spdlog-example";
auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID); auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!"); syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!");
#endif #endif
} }
// user defined types logging by implementing operator<<
struct my_type
{
int i;
template<typename OStream>
friend OStream& operator<<(OStream& os, const my_type &c) {return os << "[my_type i="<<c.i << "]";}
};
#include <spdlog/fmt/ostr.h> // must be included
void user_defined_example()
{
spd::get("console")->info("user defined type: {}", my_type{ 14 });
}
...@@ -11,9 +11,8 @@ ...@@ -11,9 +11,8 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\include\spdlog\fmt\format.cc"> <ClInclude Include="..\include\spdlog\fmt\fmtlib\format.cc" />
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ClInclude Include="..\include\spdlog\fmt\fmtlib\ostream.cc" />
</None>
<ClCompile Include="example.cpp" /> <ClCompile Include="example.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
...@@ -30,7 +29,11 @@ ...@@ -30,7 +29,11 @@
<ClInclude Include="..\include\spdlog\details\pattern_formatter_impl.h" /> <ClInclude Include="..\include\spdlog\details\pattern_formatter_impl.h" />
<ClInclude Include="..\include\spdlog\details\registry.h" /> <ClInclude Include="..\include\spdlog\details\registry.h" />
<ClInclude Include="..\include\spdlog\details\spdlog_impl.h" /> <ClInclude Include="..\include\spdlog\details\spdlog_impl.h" />
<ClInclude Include="..\include\spdlog\fmt\format.h" /> <ClInclude Include="..\include\spdlog\fmt\fmt.h" />
<ClInclude Include="..\include\spdlog\fmt\fmtlib\format.h" />
<ClInclude Include="..\include\spdlog\fmt\fmtlib\ostream.h" />
<ClInclude Include="..\include\spdlog\fmt\fmtlib\printf.h" />
<ClInclude Include="..\include\spdlog\fmt\ostr.h" />
<ClInclude Include="..\include\spdlog\formatter.h" /> <ClInclude Include="..\include\spdlog\formatter.h" />
<ClInclude Include="..\include\spdlog\logger.h" /> <ClInclude Include="..\include\spdlog\logger.h" />
<ClInclude Include="..\include\spdlog\sinks\android_sink.h" /> <ClInclude Include="..\include\spdlog\sinks\android_sink.h" />
...@@ -51,6 +54,7 @@ ...@@ -51,6 +54,7 @@
<ProjectGuid>{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}</ProjectGuid> <ProjectGuid>{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>.</RootNamespace> <RootNamespace>.</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
...@@ -116,6 +120,8 @@ ...@@ -116,6 +120,8 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#define DEPRECATED #define DEPRECATED
#endif #endif
#include <spdlog/fmt/fmt.h>
namespace spdlog namespace spdlog
{ {
...@@ -70,9 +73,9 @@ typedef enum ...@@ -70,9 +73,9 @@ typedef enum
off = 6 off = 6
} level_enum; } level_enum;
static const char* level_names[] { "trace", "debug", "info", "warning", "error", "critical", "off"}; static const char* level_names[] { "trace", "debug", "info", "warning", "error", "critical", "off" };
static const char* short_level_names[] { "T", "D", "I", "W", "E", "C", "O"}; static const char* short_level_names[] { "T", "D", "I", "W", "E", "C", "O" };
inline const char* to_str(spdlog::level::level_enum l) inline const char* to_str(spdlog::level::level_enum l)
{ {
...@@ -106,10 +109,11 @@ namespace os ...@@ -106,10 +109,11 @@ namespace os
std::string errno_str(int err_num); std::string errno_str(int err_num);
} }
} }
class spdlog_ex : public std::exception class spdlog_ex: public std::exception
{ {
public: public:
spdlog_ex(const std::string& msg) :_msg(msg) {} spdlog_ex(const std::string& msg):_msg(msg)
{}
spdlog_ex(const std::string& msg, int last_errno) spdlog_ex(const std::string& msg, int last_errno)
{ {
_msg = msg + ": " + details::os::errno_str(last_errno); _msg = msg + ": " + details::os::errno_str(last_errno);
...@@ -132,4 +136,5 @@ using filename_t = std::wstring; ...@@ -132,4 +136,5 @@ using filename_t = std::wstring;
using filename_t = std::string; using filename_t = std::string;
#endif #endif
} //spdlog } //spdlog
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
#pragma once #pragma once
#include <spdlog/common.h> #include <spdlog/common.h>
#include <spdlog/fmt/format.h>
#include <spdlog/details/os.h> #include <spdlog/details/os.h>
#include <string> #include <string>
#include <utility> #include <utility>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <spdlog/formatter.h> #include <spdlog/formatter.h>
#include <spdlog/details/log_msg.h> #include <spdlog/details/log_msg.h>
#include <spdlog/details/os.h> #include <spdlog/details/os.h>
#include <spdlog/fmt/format.h> #include <spdlog/fmt/fmt.h>
#include <chrono> #include <chrono>
#include <ctime> #include <ctime>
......
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
// The next 2 lines where commented out by spdlog // Commented out by spdlog to use header only
//#include "fmt/format.h" // #include "fmt/format.h"
//#include "fmt/printf.h" // #include "fmt/printf.h"
#include <string.h> #include <string.h>
...@@ -522,8 +522,7 @@ template void internal::FixedBuffer<char>::grow(std::size_t); ...@@ -522,8 +522,7 @@ template void internal::FixedBuffer<char>::grow(std::size_t);
template void internal::ArgMap<char>::init(const ArgList &args); template void internal::ArgMap<char>::init(const ArgList &args);
template void internal::PrintfFormatter<char>::format( template void PrintfFormatter<char>::format(CStringRef format);
BasicWriter<char> &writer, CStringRef format);
template int internal::CharTraits<char>::format_float( template int internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format, char *buffer, std::size_t size, const char *format,
...@@ -539,8 +538,7 @@ template void internal::FixedBuffer<wchar_t>::grow(std::size_t); ...@@ -539,8 +538,7 @@ template void internal::FixedBuffer<wchar_t>::grow(std::size_t);
template void internal::ArgMap<wchar_t>::init(const ArgList &args); template void internal::ArgMap<wchar_t>::init(const ArgList &args);
template void internal::PrintfFormatter<wchar_t>::format( template void PrintfFormatter<wchar_t>::format(WCStringRef format);
BasicWriter<wchar_t> &writer, WCStringRef format);
template int internal::CharTraits<wchar_t>::format_float( template int internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format, wchar_t *buffer, std::size_t size, const wchar_t *format,
...@@ -556,4 +554,4 @@ template int internal::CharTraits<wchar_t>::format_float( ...@@ -556,4 +554,4 @@ template int internal::CharTraits<wchar_t>::format_float(
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(pop) # pragma warning(pop)
#endif #endif
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
Formatting library for C++ - std::ostream support
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
// Commented out by spdlog to use header only
// #include "fmt/ostream.h"
// #include "fmt/printf.h"
namespace fmt {
namespace {
// Write the content of w to os.
void write(std::ostream &os, Writer &w) {
const char *data = w.data();
typedef internal::MakeUnsigned<std::streamsize>::Type UnsignedStreamSize;
UnsignedStreamSize size = w.size();
UnsignedStreamSize max_size =
internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
do {
UnsignedStreamSize n = size <= max_size ? size : max_size;
os.write(data, static_cast<std::streamsize>(n));
data += n;
size -= n;
} while (size != 0);
}
}
FMT_FUNC void print(std::ostream &os, CStringRef format_str, ArgList args) {
MemoryWriter w;
w.write(format_str, args);
write(os, w);
}
FMT_FUNC int fprintf(std::ostream &os, CStringRef format, ArgList args) {
MemoryWriter w;
printf(w, format, args);
write(os, w);
return static_cast<int>(w.size());
}
} // namespace fmt
/*
Formatting library for C++ - std::ostream support
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
// Commented out by spdlog to use header only
// #include "fmt/format.h"
#include <ostream>
namespace fmt {
namespace internal {
template <class Char>
class FormatBuf : public std::basic_streambuf<Char> {
private:
typedef typename std::basic_streambuf<Char>::int_type int_type;
typedef typename std::basic_streambuf<Char>::traits_type traits_type;
Buffer<Char> &buffer_;
Char *start_;
public:
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) {
this->setp(start_, start_ + buffer_.capacity());
}
int_type overflow(int_type ch = traits_type::eof()) {
if (!traits_type::eq_int_type(ch, traits_type::eof())) {
size_t buf_size = size();
buffer_.resize(buf_size);
buffer_.reserve(buf_size * 2);
start_ = &buffer_[0];
start_[buf_size] = traits_type::to_char_type(ch);
this->setp(start_+ buf_size + 1, start_ + buf_size * 2);
}
return ch;
}
size_t size() const {
return to_unsigned(this->pptr() - start_);
}
};
Yes &convert(std::ostream &);
struct DummyStream : std::ostream {
DummyStream(); // Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
void operator<<(Null<>);
};
No &operator<<(std::ostream &, int);
template<typename T>
struct ConvertToIntImpl<T, true> {
// Convert to int only if T doesn't have an overloaded operator<<.
enum {
value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No)
};
};
} // namespace internal
// Formats a value.
template <typename Char, typename ArgFormatter, typename T>
void format(BasicFormatter<Char, ArgFormatter> &f,
const Char *&format_str, const T &value) {
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
internal::FormatBuf<Char> format_buf(buffer);
std::basic_ostream<Char> output(&format_buf);
output << value;
BasicStringRef<Char> str(&buffer[0], format_buf.size());
typedef internal::MakeArg< BasicFormatter<Char> > MakeArg;
format_str = f.format(format_str, MakeArg(str));
}
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
print(cerr, "Don't {}!", "panic");
\endrst
*/
FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args);
FMT_VARIADIC(void, print, std::ostream &, CStringRef)
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fprintf(cerr, "Don't %s!", "panic");
\endrst
*/
FMT_API int fprintf(std::ostream &os, CStringRef format_str, ArgList args);
FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef)
} // namespace fmt
#ifdef FMT_HEADER_ONLY
# include "ostream.cc"
#endif
#endif // FMT_OSTREAM_H_
This diff is collapsed.
//
// Copyright(c) 2016 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
//
// Include a bundled header-only copy of fmtlib or an external one.
// By default spdlog include its own copy.
//
#if !defined(SPDLOG_FMT_EXTERNAL)
#ifndef FMT_HEADER_ONLY
#define FMT_HEADER_ONLY
#endif
#ifndef FMT_USE_WINDOWS_H
#define FMT_USE_WINDOWS_H 0
#endif
#include <spdlog/fmt/bundled/format.h>
#else //external fmtlib
#include <fmt/format.h>
#endif
This diff is collapsed.
//
// Copyright(c) 2016 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
// include external or bundled copy of fmtlib's ostream support
//
#if !defined(SPDLOG_FMT_EXTERNAL)
#include <spdlog/fmt/fmt.h>
#include <spdlog/fmt/bundled/ostream.h>
#else
#include <fmt/ostream.h>
#endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <spdlog/sinks/base_sink.h> #include <spdlog/sinks/base_sink.h>
#include <spdlog/details/null_mutex.h> #include <spdlog/details/null_mutex.h>
#include <spdlog/details/file_helper.h> #include <spdlog/details/file_helper.h>
#include <spdlog/fmt/format.h> #include <spdlog/fmt/fmt.h>
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// Edit this file to squeeze every last drop of performance out of spdlog. // Edit this file to squeeze more performance, and to customize supported features
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
...@@ -81,5 +81,14 @@ ...@@ -81,5 +81,14 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Uncomment to override default eol ("\n" or "\r\n" under Linux/Windows) // Uncomment to override default eol ("\n" or "\r\n" under Linux/Windows)
//
// #define SPDLOG_EOL ";-)\n" // #define SPDLOG_EOL ";-)\n"
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Uncomment to use your own copy of the fmt library instead of spdlog's copy.
// In this case spdlog will try to include <fmt/format.h> so set your -I flag accordingly.
//
// #define SPDLOG_FMT_EXTERNAL
///////////////////////////////////////////////////////////////////////////////
[2016-07-15 18:30:57.643] [logger] [info] Test message 0
[2016-07-15 18:30:57.643] [logger] [info] Test message 1
[2016-07-15 18:30:57.643] [logger] [info] Test message 2
[2016-07-15 18:30:57.643] [logger] [info] Test message 3
[2016-07-15 18:30:57.643] [logger] [info] Test message 4
[2016-07-15 18:30:57.643] [logger] [info] Test message 5
[2016-07-15 18:30:57.643] [logger] [info] Test message 6
[2016-07-15 18:30:57.643] [logger] [info] Test message 7
[2016-07-15 18:30:57.643] [logger] [info] Test message 8
[2016-07-15 18:30:57.643] [logger] [info] Test message 9
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment