Giter Club home page Giter Club logo

loguru's Introduction

Loguru: a lightweight and flexible C++ logging library.

Build status

At a glance

Loguru terminal output

Documentation

Documentation can be found at https://emilk.github.io/loguru/index.html.

License

This software is in the public domain. Where that dedication is not recognized, you are granted a perpetual, irrevocable license to copy, modify and distribute it as you see fit.

Loguru is also available under The Unlicense.

That being said, I would appreciate credit! If you find Loguru useful, tweet me at @ernerfeldt mail me at [email protected].

Why another logging library?

I have yet to come across a nice, light-weight logging library for C++ that does everything I want. So I made one!

In particular, I want logging that produces logs that are both human-readable and easily grep:ed. I also want to be able to hook into the logging process to print some of the more severe messages on-screen in my app (for dev-purposes).

Features:

  • Simple integration
    • Just two files: loguru.hpp and loguru.cpp.
    • Either build and link loguru.cpp or just #include <loguru.cpp> in one of your own .cpp files.
  • Small, simple library.
    • Small header with no #includes for fast compile times (see separate heading).
    • No dependencies.
    • Cross-platform
  • Flexible:
    • User can install callbacks for logging (e.g. to draw log messages on screen in a game).
    • User can install callbacks for fatal error (e.g. to pause an attached debugger or throw an exception).
  • Support multiple file outputs, either trunc or append:
    • e.g. a logfile with just the latest run at low verbosity (high readability).
    • e.g. a full logfile at highest verbosity which is appended to on every run.
  • Full featured:
    • Verbosity levels.
    • Supports assertions: CHECK_F(fp != nullptr, "Failed to open '%s'", filename)
    • Supports abort: ABORT_F("Something went wrong, debug value is %d", value).
  • Stack traces printed on abort.
    • Stack traces are cleaned up somewhat.
      • Before cleanup: some_function_name(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)
      • After cleanup: some_function_name(std::vector<std::string> const&)
    • Stack traces are printed the right way:
      • Chronological order with the most relevant at the end.
  • (most) signals writes stack traces.
  • Fast:
    • When configured in unbuffered mode (loguru::g_flush_interval_ms = 0):
      • 6-8 us when logging to stderr + file (rMBP + SSD + Clang).
      • About 25%-75% faster than GLOG on my MacBook Pro (Clang).
      • About the same as GLOG on my Linux Desktop (GCC).
    • With loguru::g_flush_interval_ms set to ~100 ms:
      • 3-5 us when logging to stderr + file (rMBP + SSD + Clang).
      • About twice as fast as GLOG.
  • Drop-in replacement for most of GLOG (except for setup code).
  • Choose between using printf-style or std::cout-style formatting.
  • Compile-time checked printf-formating (on supported compilers).
  • Support for fmtlib formatting.
    • Add #define LOGURU_USE_FMTLIB 1, before including loguru.hpp
    • You also need to set up the fmtlib include directory for building as well as linking against fmtlib, alternatively use the FMT_HEADER_ONLY preprocessor definition.
  • Assertion failures are marked with noreturn for the benefit of the static analyzer and optimizer.
  • All logging also written to stderr.
    • With colors on supported terminals.
  • Thread-safe.
  • Can be configured to either:
    • Flush every loguru::g_flush_interval_ms in a background thread
    • Flushes output on each call so you won't miss anything even on hard crashes (and still faster than buffered GLOG!).
  • Prefixes each log line with:
    • Date and time to millisecond precision.
    • Application uptime to millisecond precision.
    • Thread name or id (you can set the name with loguru::set_thread_name).
    • File and line.
    • Log level.
    • Indentation (see Scopes).
  • Error context:
    • Catch the values of local variables and print them only on a crash (see Error context).
  • Scopes (see Scopes).
  • grep:able logs:
    • Each line has all the info you need (e.g. date).
    • You can easily filter out high verbosity levels after the fact.

Compiling

Just include <loguru.hpp> where you want to use Loguru. Then either compile and link with loguru.cpp or in one .cpp file: #include <loguru.cpp> Make sure you compile with -std=c++11 -lpthread -ldl on relevant environments.

CMake Instructions

Loguru can be added to an existing CMake project in three ways

  1. add_subdirectory()
  2. FetchContent()
  3. find_package()

See CMake example for a demonstration.

Usage

#include <loguru.hpp>

โ€ฆ

// Optional, but useful to time-stamp the start of the log.
// Will also detect verbosity level on command line as -v.
loguru::init(argc, argv);

// Put every log message in "everything.log":
loguru::add_file("everything.log", loguru::Append, loguru::Verbosity_MAX);

// Only log INFO, WARNING, ERROR and FATAL to "latest_readable.log":
loguru::add_file("latest_readable.log", loguru::Truncate, loguru::Verbosity_INFO);

// Only show most relevant things on stderr:
loguru::g_stderr_verbosity = 1;

LOG_SCOPE_F(INFO, "Will indent all log messages within this scope.");
LOG_F(INFO, "I'm hungry for some %.3f!", 3.14159);
LOG_F(2, "Will only show if verbosity is 2 or higher");
VLOG_F(get_log_level(), "Use vlog for dynamic log level (integer in the range 0-9, inclusive)");
LOG_IF_F(ERROR, badness, "Will only show if badness happens");
auto fp = fopen(filename, "r");
CHECK_F(fp != nullptr, "Failed to open file '%s'", filename);
CHECK_GT_F(length, 0); // Will print the value of `length` on failure.
CHECK_EQ_F(a, b, "You can also supply a custom message, like to print something: %d", a + b);

// Each function also comes with a version prefixed with D for Debug:
DCHECK_F(expensive_check(x)); // Only checked #if !NDEBUG
DLOG_F(INFO, "Only written in debug-builds");

// Turn off writing to stderr:
loguru::g_stderr_verbosity = loguru::Verbosity_OFF;

// Turn off writing err/warn in red:
loguru::g_colorlogtostderr = false;

// Throw exceptions instead of aborting on CHECK fails:
loguru::set_fatal_handler([](const loguru::Message& message){
	throw std::runtime_error(std::string(message.prefix) + message.message);
});

If you prefer logging with streams:

#define LOGURU_WITH_STREAMS 1
#include <loguru.hpp>
...
LOG_S(INFO) << "Look at my custom object: " << a.cross(b);
CHECK_EQ_S(pi, 3.14) << "Maybe it is closer to " << M_PI;

For more info, see the official documentation.

Grep:able logs

# Only show warnings, errors and fatal messages:
cat logfile.txt | egrep "[^0-9]\|"

# Ignore verbosity-levels 4 and above:
cat logfile.txt | egrep "[^4-9]\|"

# Only show verbosity-level 6:
cat logfile.txt | egrep "6\|"

# Only show messages from the main thread:
cat logfile.txt | egrep "\[main thread     \]"

No includes in loguru.hpp

I abhor logging libraries that #include's everything from iostream to windows.h into every compilation unit in your project. Logging should be frequent in your source code, and thus as lightweight as possible. Loguru's header has no #includes. This means it will not slow down the compilation of your project.

In a test of a medium-sized project, including loguru.hpp instead of glog/logging.hpp everywhere gave about 10% speedup in compilation times.

Note, however, that this gives you the bare-bones version of Loguru with printf-style logging. If you want std::ostream style logging (or GLOG functionality) you need to #define LOGURU_WITH_STREAMS 1 before #include <loguru.hpp>, and that will make loguru.hpp include <sstream>. No away around it!

Scopes

The library supports scopes for indenting the log-file. Here's an example:

int main(int argc, char* argv[])
{
	loguru::init(argc, argv);
	LOG_SCOPE_FUNCTION(INFO);
	LOG_F(INFO, "Doing some stuff...");
	for (int i=0; i<2; ++i) {
		VLOG_SCOPE_F(1, "Iteration %d", i);
		auto result = some_expensive_operation();
		LOG_IF_F(WARNING, result == BAD, "Bad result");
	}
	LOG_F(INFO, "Time to go!");
	return 0;
}

This will output:

	     loguru.cpp:184      0| arguments:       ./loguru_test test -v1
	     loguru.cpp:185      0| Verbosity level: 1
	     loguru.cpp:186      0| -----------------------------------
	loguru_test.cpp:108      0| { int main_test(int, char **)
	loguru_test.cpp:109      0| .   Doing some stuff...
	loguru_test.cpp:111      1| .   { Iteration 0
	loguru_test.cpp:111      1| .   } 0.133 s: Iteration 0
	loguru_test.cpp:111      1| .   { Iteration 1
	loguru_test.cpp:113      0| .   .   Bad result
	loguru_test.cpp:111      1| .   } 0.134 s: Iteration 1
	loguru_test.cpp:115      0| .   Time to go!
	loguru_test.cpp:108      0| } 0.267 s: int main_test(int, char **)

ERROR_CONTEXT

You can also optionally log things ONLY if there is a crash. This is a very useful feature:

	void process_file(const char* filename)
	{
		ERROR_CONTEXT("filename", filename);
		parse_file(filename); // Only if this crashes will filename be logged.
	}

Streams vs printf

Some logging libraries only supports stream style logging, not printf-style. This means that what in Loguru is:

LOG_F(INFO, "Some float: %+05.3f", number);

in Glog becomes something along the lines of:

LOG(INFO) << "Some float: " << std::setfill('0') << std::setw(5) << std::setprecision(3) << number;

Loguru allows you to use whatever style you prefer.

loguru's People

Contributors

ajkhoury avatar bjoernpollex-sbg avatar bylowerik avatar electronicboy avatar emilk avatar kcgen avatar kkoenig avatar looki avatar maskray avatar mercurysky avatar metab0t avatar mrmagne avatar notjuliee avatar ojake avatar oriolarcas avatar patrickmeehan avatar puzzlepaint avatar raphaelts3 avatar richardhozak avatar ruurdadema avatar scinart avatar sebhub avatar skaravos avatar tan-wei avatar tstenner avatar tusharpm avatar utkarshayachit avatar vedranmiletic avatar vicentebolea avatar zivke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

loguru's Issues

rotating log

Hi, it would be good if loguru supports keep constant log file size,

but update log in the file, like spdlog's rotate logger:

        // 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);
        for (int i = 0; i < 10; ++i)
            rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);

pedantic issues prevent compiling!

.../code/project/include/log/loguru.hpp:1168:69: error: use of non-standard escape character '\e' [-Werror,-Wpedantic]
const char* terminal_black() { return s_terminal_has_color ? "\e[30m" : ""; }

I can't compile with loguru because I get a bazillion errors like these in pedantic mode in clang!

What do I do!?

Support for c standard libraries other than glibc

When trying to compile cquery on Void Linux with musl libc I get the following error.

loguru.hpp:1391:11: fatal error: execinfo.h: No such file or directory
  #include <execinfo.h>  // for backtrace

execinfo.h is glibc specific and prevents compilation when using alternative standard libraries.

Is it possible to restructure loguru so that support doesn't depend on glibc?

Dynamic library

Hey,

I am using your logging system for my custom game engine, great work on the library btw.

But I am running into an issue when I create a dynamic version of my engine library because your log functions are not exported, would it be possible to create some definition to export the function declerations so they can be used outside the library?

ERR and WRN log lines not easily distinguishable because of identical colors

My system: Ubuntu 18.04.1 LTS.

I would like to easily distinguish errors and warnings in the log lines on the terminal. However, ERR and WRN lines now have identical colors.

In loguru, color code 31 is used for warnings and 91 for errors (and fatal). These are the intended colors:
2018-09-13_09h18_52
The colors are distinguishable (although quite similar).

However, the ERR and WRN log lines in loguru not only have a color, they are also printed bold. This is how text is written on my terminal in bold:
2018-09-13_09h23_40
As you can see, the colors now are identical.

My suggestion to solve this problem would be to use a different color for WRN log entries. For me a perfect joice would be terminal_yellow() (color code 33) since this would be derived from the traffic light system and, thus, would be completely intuitive for me.

get_thread_name() conditionally encounters a memory leak (?)

Experienced on a Tegra TK1 running Ubuntu 14.04 32-bit with GCC 4.8 compiler.
With -O2 optimizations turned on, we see a shift in bytes for the arguments passed on to snprintf() called in get_thread_name().

	void get_thread_name(char* buffer, unsigned long long length, bool right_align_hext_id)
	{
		...
			if (right_align_hext_id) {
				snprintf(buffer, length, "%*X", length - 1, static_cast<unsigned>(thread_id));
			} else {
				snprintf(buffer, length, "%X", static_cast<unsigned>(thread_id));
			}
}

The parameter unsigned long long length passed into the function is used in the snprintf() function; The * in the %*X is expecting a type int. This style of va_args may under some conditions be misinterpreted (only the first half of the long long is taken, shoving the rest of the long long into the coming parameter). While later versions of GCC may be smarter about it, it may not always work with all compilers.

Suggested solution: prepare the type cast before the snprintf call. Example:

		void get_thread_name(char* buffer, unsigned long long long_length, bool right_align_hext_id)
		{	
			int length = static_cast<int>(long_length);

Additional details:
(1) Valgrind reports "Conditional jump or move depends on uninitialised value(s)" around the loguru::get_thread_name
(2) Breakpointing and tracing the calls with GDB revealed this (emphasis added):

Breakpoint 2, __GI__IO_padn (fp=fp@entry=0xbeffef38, pad=pad@entry=48, count=1) at iopadn.c:47

Breakpoint 2, __GI__IO_padn (fp=fp@entry=0xbeffef38, pad=32, count=count@entry=1) at iopadn.c:47

Breakpoint 2, __GI__IO_padn (fp=fp@entry=0xbeffef38, pad=pad@entry=32, count=count@entry=14) at iopadn.c:47

Breakpoint 2, __GI__IO_padn (fp=fp@entry=0xbeffef38, pad=pad@entry=32, count=count@entry=3) at iopadn.c:47

// ^ a series of consecutive calls to a glibc function called _IO_padn.
// And then comes this, after the call to get_thread_name:
Breakpoint 2, __GI__IO_padn (fp=fp@entry=0xbeffeef0, pad=pad@entry=32, count=count@entry=1090522931) at iopadn.c:47

Full backtrace:

(gdb) bt
#0  _IO_strn_overflow (fp=0xbeffeef0, c=32) at vsnprintf.c:66
#1  0xb6dfa1ee in __GI__IO_default_xsputn (f=0xbeffeef0, data=<optimized out>, n=16) at genops.c:480
#2  0xb6df238c in __GI__IO_padn (fp=fp@entry=0xbeffeef0, pad=pad@entry=32, count=count@entry=1090522931) at iopadn.c:59
#3  0xb6dddae6 in _IO_vfprintf_internal (s=s@entry=0xbeffeef0, format=format@entry=0x13994 "%*X", ap=..., ap@entry=...) at vfprintf.c:1660
#4  0xb6e47a9e in ___vsnprintf_chk (s=s@entry=0xbefff100 "A         ", maxlen=<optimized out>, maxlen@entry=11, flags=flags@entry=1, slen=slen@entry=4294967295, format=format@entry=0x13994 "%*X", args=...) at vsnprintf_chk.c:63
#5  0xb6e47a40 in ___snprintf_chk (s=s@entry=0xbefff100 "A         ", maxlen=maxlen@entry=11, flags=flags@entry=1, slen=slen@entry=4294967295, format=format@entry=0x13994 "%*X") at snprintf_chk.c:34
#6  0x0000d9a0 in snprintf (__fmt=0x13994 "%*X", __n=11, __s=0xbefff100 "A         ") at /usr/include/arm-linux-gnueabihf/bits/stdio2.h:65
#7  loguru::get_thread_name (buffer=buffer@entry=0xbefff100 "A         ", length=<optimized out>, right_align_hext_id=right_align_hext_id@entry=true) at loguru.hpp:1957
#8  0x0000db22 in loguru::print_preamble (out_buff=out_buff@entry=0xbefff15c "", verbosity=verbosity@entry=-2, file=file@entry=0x13b78 "main.cpp", line=line@entry=9, out_buff_size=128) at loguru.hpp:2113
#9  0x0000d24c in loguru::log_to_everywhere (stack_trace_skip=stack_trace_skip@entry=1, verbosity=verbosity@entry=-2, file=file@entry=0x13b78 "main.cpp", line=line@entry=9, prefix=prefix@entry=0x1378c "", buff=buff@entry=0x244c0 "Something has ceased to work.\n") at loguru.hpp:2257
#10 0x0000dfe6 in loguru::log (verbosity=-2, file=0x13b78 "main.cpp", line=9, format=0x137bc "%s") at loguru.hpp:2267
#11 0x0000e5aa in loguru::StreamLogger::~StreamLogger (this=0xbefff268, __in_chrg=<optimized out>) at loguru.hpp:2381
#12 0x0000ad12 in main () at main.cpp:9

And the address reveal of the va_list argument passed shows that there is a byte alignment issue:

(gdb) x/100dw 0xbeffef60
0xbeffef60:    -1225102064    -1225102868    -1090523232    0
0xbeffef70:    2111285930    -1224842949    -1224761344    -1225100160
0xbeffef80:    -1225102064    -1224741480    -1226257992    -1090523088
0xbeffef90:    0    -1224738620    -1224790084    -1224741480
0xbeffefa0:    0    0    1    119
0xbeffefb0:    -1224756240    -1224753152    36981    -1225096944
0xbeffefc0:    35596    1    -1224756336    -1224738024
0xbeffefd0:    -1224738464    36981    -1090523120    -1090523108
0xbeffefe0:    80276    -1090522880    1    -1224761344
0xbeffeff0:    11    -1226540479    80276    -1090523108
0xbefff000:    -1090522880    -1090523108    -1224761344    10
0xbefff010:    0    55713    80276    -1090522932
0xbefff020:    10    0    -1224761344    802944595

Option to override command line parameter name

I am currently adding loguru to an application that already uses -v for another parameter. It would be very useful to be able to specify a custom parameter name for the verbosity level to loguru. Alternatively, It would be great to get all the features of init without parsing command-line arguments.

customize layout?

loguru has been working great for me (๐Ÿ‘). I'm wondering if you plan to support custom output layout. E.g. Sometimes thread names are not needed.

Bad log messages with LOGURU_USE_FMTLIB enabled

When LOGURU_USE_FMTLIB is set to 1, loguru's internally-generated messages are incorrect.

Example:

date       time         ( uptime  ) [ thread name/id ]                   file:line     v|
2018-01-03 20:54:55.652 (   0.000s) [main thread     ]             loguru.hpp:1828     0| arguments: %s
2018-01-03 20:54:55.653 (   0.001s) [main thread     ]             loguru.hpp:1831     0| Current dir: %s
2018-01-03 20:54:55.653 (   0.001s) [main thread     ]             loguru.hpp:1833     0| stderr verbosity: %d
2018-01-03 20:54:55.653 (   0.001s) [main thread     ]             loguru.hpp:1834     0| -----------------------------------
2018-01-03 20:54:55.654 (   0.001s) [main thread     ]             loguru.hpp:1986     0| Logging to '%s', mode: '%s', verbosity: %d

compile error vs2013

Hi, how to work around this error?

http://stackoverflow.com/questions/24573963/move-constructor-invalid-type-for-defaulted-constructor-vs-2013

loguru.h(452): error C2610: 'loguru::LogScopeRAII::LogScopeRAII(loguru::LogScopeRAII &&)' : is not a special member function which can be defaulted

    // Helper class for LOG_SCOPE_F
    class LogScopeRAII
    {
    public:
        LogScopeRAII() : _file(nullptr) {} // No logging
        LogScopeRAII(Verbosity verbosity, const char* file, unsigned line, LOGURU_FORMAT_STRING_TYPE format, ...) LOGURU_PRINTF_LIKE(5, 6);
        ~LogScopeRAII();

        LogScopeRAII(LogScopeRAII&& other) = default;                       //  here

Clean up stack trace even more

This is a very ugly example:

visualize(std::vector<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::aligned_allocator<Eigen::Matrix<float, 3, 1, 0, 3, 1> > > const&)

The allocators could be removed by matching std::vector<Foo,Bar> where Bar has an equal number of <>. This would give us:

visualize(std::vector<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&)

To cleanup further we could let the Loguru user install hookups for replacing e.g. Eigen::Matrix<float, 3, 1, 0, 3, 1> with Vector3f, which would give us:

visualize(std::vector<Vector3f> const&)

Small memory leaking

loguru::init() leaks a small amount of memory (12 bytes) in every single execution. This can be verified by running
$ valgrind --leak-check=full --show-leak-kinds=all program
I'll see if i can find the problem and push a fix!

Printing Unicode Character on Windows

I'm using Windows with _UNICODE defined and trying to output some %ls with LOG_F(). It went well until a string with non-ASCII characters appeared and then the program aborted with CHECK FAILED: bytes_needed >= 0 Bad string format: '%ls'. It looks like the problem is caused by _vscprintf(), which has a wchar variant but requires a format string with the same type (so I guess it can't be a replacement). I also tried LOG_S(), but it output the address of the string instead of the content (it was using the ostream& operator<< (const void* val ) overload). Any ideas?

Example:

LOG_S(INFO) << L"ๅ“‡r";
LOG_F(INFO, "%ls", L"ๅ“‡r");
...:175      0| 00007FF6D607EA70
...:1668  FATL| CHECK FAILED:  bytes_needed >= 0  Bad string format: '%ls'

VS v140 narrowing conversion

First, thanks for this awesome logging library. This is exactly what I needed. Although it required some manual patching to get the deprecation warnings and ISO C stuff sorted out. (http://pastebin.com/gRSSeuvv), since this is not about the deprecation warnings I left them out and just pastebinned them.

The real "issue" is this error:

error C2398: Element '3': conversion from 'long' to 'unsigned int' requires a narrowing conversion

which originates from here:

#define VLOG_SCOPE_F(verbosity, ...)                                                               \
	loguru::LogScopeRAII LOGURU_ANONYMOUS_VARIABLE(error_context_RAII_) =                          \
	((verbosity) > loguru::current_verbosity_cutoff()) ? loguru::LogScopeRAII() :                  \
	loguru::LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__}

Adding a C Style cast to __LINE__ fixes the problem though.

#define VLOG_SCOPE_F(verbosity, ...)                                                               \
	loguru::LogScopeRAII LOGURU_ANONYMOUS_VARIABLE(error_context_RAII_) =                          \
	((verbosity) > loguru::current_verbosity_cutoff()) ? loguru::LogScopeRAII() :                  \
	loguru::LogScopeRAII{verbosity, __FILE__, (unsigned int)__LINE__, __VA_ARGS__}

compile failed with msys2

../../third_party/loguru\loguru.hpp:1636:16: error: use of undeclared identifier 'vasprintf'; did you mean 'vsprintf'?
int result = vasprintf(&buff, format, vlist);
^
D:\msys64\mingw64\x86_64-w64-mingw32\include\stdio.h:372:5: note: 'vsprintf' declared here
int vsprintf (char *__stream, const char *__format, __builtin_va_list __local_argv)
^
In file included from ../../src/third_party_impl.cc:5:
../../third_party/loguru\loguru.hpp:1636:26: error: cannot initialize a parameter of type 'char *' with an rvalue of type 'char **'
int result = vasprintf(&buff, format, vlist);
^~~~~
D:\msys64\mingw64\x86_64-w64-mingw32\include\stdio.h:372:21: note: passing argument to parameter '__stream' here
int vsprintf (char *__stream, const char *__format, __builtin_va_list __local_argv)
^
In file included from ../../src/third_party_impl.cc:5:
../../third_party/loguru\loguru.hpp:1878:3: error: use of undeclared identifier 'localtime_r'; did you mean 'localtime_s'?
localtime_r(&sec_since_epoch, &time_info);
^
D:\msys64\mingw64\x86_64-w64-mingw32\include\time.h:261:31: note: 'localtime_s' declared here
__forceinline errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); }
^
In file included from ../../src/third_party_impl.cc:5:
../../third_party/loguru\loguru.hpp:1878:15: error: cannot initialize a parameter of type 'struct tm *' with an rvalue of type 'time_t *' (aka 'long long *')
localtime_r(&sec_since_epoch, &time_info);
^~~~~~~~~~~~~~~~
D:\msys64\mingw64\x86_64-w64-mingw32\include\time.h:261:54: note: passing argument to parameter '_Tm' here
__forceinline errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); }
^
In file included from ../../src/third_party_impl.cc:5:
../../third_party/loguru\loguru.hpp:1946:8: error: no matching function for call to 'mkdir'
if (mkdir(file_path, 0755) == -1) {
^~~~~
D:\msys64\mingw64\x86_64-w64-mingw32\include\io.h:280:15: note: candidate function not viable: requires 1 argument, but 2 were provided
int __cdecl mkdir (const char *) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
^
In file included from ../../src/third_party_impl.cc:5:
../../third_party/loguru\loguru.hpp:2311:3: error: use of undeclared identifier 'localtime_r'; did you mean 'localtime_s'?
localtime_r(&sec_since_epoch, &time_info);
^
D:\msys64\mingw64\x86_64-w64-mingw32\include\time.h:261:31: note: 'localtime_s' declared here
__forceinline errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); }
^
In file included from ../../src/third_party_impl.cc:5:
../../third_party/loguru\loguru.hpp:2311:15: error: cannot initialize a parameter of type 'struct tm *' with an rvalue of type 'time_t *' (aka 'long long *')
localtime_r(&sec_since_epoch, &time_info);
^~~~~~~~~~~~~~~~
D:\msys64\mingw64\x86_64-w64-mingw32\include\time.h:261:54: note: passing argument to parameter '_Tm' here
__forceinline errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { return _localtime64_s(_Tm,_Time); }
^
In file included from ../../src/third_party_impl.cc:5:
../../third_party/loguru\loguru.hpp:2805:4: error: "No signal handlers on Win32" [-Werror,-W#warnings]
#warning "No signal handlers on Win32"
^
8 errors generated.

[27/71] Compiling src/clang_translation_unit.cc
Waf: Leaving directory `/d/shaman/cquery/build/release'
Build failed
-> task in 'bin/cquery' failed with exit status 1 (run with -v to display more information)

unicode support

Hi, i want that loguru support unicode.

#define LOG_INFO(...)    LOG_F(INFO, __VA_ARGS__)
void function(const std::wstring& fn)
{
  LOG_INFO(" %s file opened\n", fn);                 // not work
  LOG_INFO(" %s file opened\n", fn.c_str());         // not work
 
  std::string str(fn.begin(), fn.end());
  LOG_INFO(" %s file opened\n", str.c_str());        // work
}

Problems with PATH_MAX

Loguru doesn't compile on Debian Jessie with g++ 4.9.2 because PATH_MAX isn't defined. I have a basic fix here (it has a typo, MAX_PATH instead of PATH_MAX). It also doesn't compile with g++ 5.3 on Mac OS X, because that requires to include limits.h to get PATH_MAX.

I would propose the following solution:

  1. When in a POSIX environment, include limits.h first.
  2. If PATH_MAX is not defined yet, and it is a Linux environment, include linux/limits.h
  3. If that didn't work, manually define PATH_MAX to a reasonable default, e.g. 1024.

The most important point here I think is to have a default to fallback on, because apparently, PATH_MAX is not reliable at all.

Compilation of implentation is slow

This library seems interesting and well designed, but compilation is slow here.
Any idea of where the bottleneck is, and perhaps how it could be trimmed down to compile faster?
Fortunately, compilation time is reduced to ~0.4s when not #define LOGURU_IMPLEMENTATION 1, so the problem should be solved by defining a dedicated compilation unit (cpp file) for that.

Ubuntu 18.04 running on a Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz .
This is obviously not IO-bound (fast SSD, 16GB RAM, files in cache).
System is otherwise idle.

# Compilation options from the `loguru_example/CMakeLists.txt` :
time /usr/bin/c++    -std=c++11 -Werror -Wall -Wextra -pedantic -fsanitize=address -fno-omit-frame-pointer -O2 -g -DNDEBUG   -o main.cpp.o -c main.cpp

# Various runs :

real	0m10,722s
user	0m10,533s
sys	0m0,170s

real	0m11,182s
user	0m11,048s
sys	0m0,132s

real	0m11,360s
user	0m11,176s
sys	0m0,180s

real	0m11,439s
user	0m11,222s
sys	0m0,217s

Errors in the documentation

add_file() with just these two params is not defined. It requires the 3rd verbosity param.

// Put every log message in "everything.log":
loguru::add_file("everything.log", loguru::Append);

Here, loguru::INFO doesn't work but loguru::Verbosity_INFO does.

// Only log INFO, WARNING, ERROR and FATAL to "latest_readable.log":
loguru::add_file("latest_readable.log", loguru::Truncate, loguru::INFO);

Thanks for the library!

Compilation failed on Windows

I tested the demo program on Windows.
It cannot be compiled on this system.

On line 780 of loguru.hpp I have this following error:

fatal error: dlfcn.h: No such file or directory

This kind of error also occurred with pthread.h.
I used MinGW (g++ 4.7.1) on Windows 7. It does not provide these files. But is seems that Cygwin provides them (not tested).

Is there a way to make this library usable on windows with these compilers (g++, Visual C++, ...) without getting any dependencies?

Inherit ERROR_CONTEXT for new threads

The ERROR_CONTEXT information is stored per thread and is not copied to new threads. This makes it harder to debug code with parallelization. I would like to be able to copy/access the error context from the parent thread to/in new threads to make debugging easier.

Linux Thread names

On Linux, the default thread name is the same as the name of the binary. Additionally, any new threads seem to inherit the name of the thread it got forked from. This means in the current form, all threads get the same name in the log by default.

Finding a solution for this is far from trivial. Loguru could have its own thread_id->name map, but that would be invalid if thread_id are reused. Another approach is to use thread_local storage, but compiler support for that is not very good at the moment.

Missing LOG_SCOPE_S() macro ?

I'm using the stream versions of Loguru macros but I can't find a stream version for:

LOG_SCOPE_F(INFO, "some message");

Am I missing something ?

.

.

#define LOGURU_IMPLEMENTATION 1

Hi, can you update your documentation related to usage:
#define LOGURU_IMPLEMENTATION 1
the 1 is missing in the readme, without 1 it will fail to build.

Conan package

Hello,
Do you know about Conan?
Conan is modern dependency manager for C++. And will be great if your library will be available via package manager for other developers.

Here you can find example, how you can create package for the library.

If you have any questions, just ask :-)

Per-output indentation

It is weird that the indentation is based on the highest verbosity level (current_verbosity_cutoff) rather than stderr when reading stderr. But it is also weird to have it based on g_stderr_verbosity when reading the log files.

The cleanest solution is to have different indentation per output.

Custom YYYY field

It will be awesome if the 1900 + time_info.tm_year column can be hidden (via a customization option)

	void write_date_time(char* buff, size_t buff_size)
	{
		auto now = system_clock::now();
		long long ms_since_epoch = duration_cast<milliseconds>(now.time_since_epoch()).count();
		time_t sec_since_epoch = time_t(ms_since_epoch / 1000);
		tm time_info;
		localtime_r(&sec_since_epoch, &time_info);
		snprintf(buff, buff_size, "%04d%02d%02d_%02d%02d%02d.%03lld",
			1900 + time_info.tm_year, 1 + time_info.tm_mon, time_info.tm_mday,
			time_info.tm_hour, time_info.tm_min, time_info.tm_sec, ms_since_epoch % 1000);
	}

@jacobdufault

Scopes do not work properly on windows.

I use the example code on windows (minor tweaks to compile):
image

And here is what outputs:
image

It appears that the LOG_SCOPE_F macro immediately closes the scope while on windows.

Please note that I am using VS2017 to build.

Edit:
It also appears that any scope immediately closes in this build.

Issues compiling on Windows with MingGW

I get the following errors trying to compile on Windows using MinGW version: w64 5.0

loguru.hpp: In function 'loguru::Text loguru::vtextprintf(const char*, va_list)': loguru.hpp:1603:46: error: 'vasprintf' was not declared in this scope int result = vasprintf(&buff, format, vlist);

And

loguru.hpp: In function 'bool loguru::create_directories(const char*)': loguru.hpp:1907:29: error: too many arguments to function 'int mkdir(const char*)' if (mkdir(file_path, 0755) == -1)

Any suggestions?

Improve support for long file names

Sometimes I emit messages from files with long names, and then the log won't be properly aligned anymore. This will look something like this:

2016-09-29 11:51:16.879 (   2.985s) [main thread     ]really_long_source_file_name.cpp:144      0| Some message that is not properly aligned
2016-09-29 11:51:16.879 (   2.985s) [main thread     ]      short.hpp:202              0| Some other message.

Since this is a static property of the project, it would be nice to have a macro to define to control the padding. If you can point me to the relevant part of the source code, I can also have a look at it.

rsyslog support?

Any plans to add rsyslog so that logs are viewable in say Papertrail? It's just sending UDP packets.

Create tags for new releases

It's very helpful for management of submodules to have tags also for minor release. Currently, 1.5.1 is not tagged.

LOG_SCOPE_FUNCTION_F(INFO);

from the readme example, the LOG_SCOPE_FUNCTION_F does not exists.
Should it be LOG_SCOPE_FUNCTION instead?...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.