2014-01-17 07:34:53 +01:00
# G3log : Asynchronous logger with Dynamic Sinks
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
## EXAMPLE USAGE
#### Optional to use either streaming or printf-like syntax
```
LOG(INFO) < < "streaming API is as easy as ABC or " < < 123 ;
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
LOGF(WARNING, "Printf-style syntax is also %s", "available");
```
#### Conditional logging
2012-10-18 07:35:09 +02:00
int less = 1; int more = 2
2012-10-18 15:52:08 +02:00
LOG_IF(INFO, (less< more ) ) < < " If [ true ] , then this text will be logged " ;
// or with printf-like syntax
2012-10-18 07:35:09 +02:00
LOGF_IF(INFO, (less< more ) , " if % d < % d then this text will be logged " , less , more ) ;
2013-12-18 07:37:12 +01:00
#### Design-by-Contract
*CHECK(false)* will trigger a "fatal" message. It will be logged, and then the
application will exit.
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
```
CHECK(less != more); // not FATAL
2014-01-17 08:44:00 +01:00
CHECK(less > more) < < "CHECK(false) triggers a FATAL message";
2013-12-18 07:37:12 +01:00
```
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
## What G3Log is:
2014-01-17 07:34:53 +01:00
* ***G3log*** is the acting name for the third version of g2log and it stands for **g2log with dynamic sinks**
* G3log is an asynchronous, "crash-safe" logger. You can read more about it here [[g2log version]](
2013-12-18 07:37:12 +01:00
http://www.codeproject.com/Articles/288827/g2log-An-efficient-asynchronous-logger-using-Cplus)
2014-01-17 08:44:00 +01:00
* You can choose to use the default log receiver which saves all LOG calls to file, **or** you can choose to use your own custom made log receiver(s), **or** both, **or** as many sinks as you need.
2014-01-17 08:26:38 +01:00
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
## Benefits you get when using G3log ##
2014-01-17 09:06:11 +01:00
1. Easy to use, clean syntax and a blazing fast logger.
2012-10-18 07:35:09 +02:00
2014-01-17 08:04:51 +01:00
2. All the slow log I/O disk access is done in a background thread. This ensures that the LOG caller can immediately continue with other tasks and do not have to wait for the LOG call to finish.
2012-10-18 07:39:21 +02:00
2013-12-18 07:37:12 +01:00
3. G3log provides logging, Design-by-Contract [#CHECK], and flush of log to file at
shutdown. Buffered logs will be written to the sink before the application shuts down.
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
4. It is thread safe, so using it from multiple threads is completely fine.
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
5. It is *CRASH SAFE* . It will save the made logs to the sink before it shuts down.
The logger will catch certain fatal signals, so if your application crashes due to, say a segmentation fault, *SIGSEGV* , or some other fatal signal it will log and save the crash and all previously buffered log
2012-10-18 15:52:08 +02:00
entries before exiting.
2012-10-18 07:39:21 +02:00
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
6. It is cross platform. Tested and used by me or by clients on OSX, Windows, Ubuntu, CentOS
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
7. On *Nix* systems a caught fatal signal will generate a stack dump to the log. A Beta version exist on Windows and can be released on request.
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
8. G2log is used world wide in commercial products as well as hobby projects since early 2011.
2012-10-18 15:52:08 +02:00
The code is given for free as public domain. This gives the option to change, use,
and do whatever with it, no strings attached.
2012-10-18 07:35:09 +02:00
2013-12-18 07:37:12 +01:00
9. Three versions of g2log exist.
2014-02-26 07:14:50 +01:00
* This version: *[g3log](https://bitbucket.org/KjellKod/g3log)* : which is made to facilitate easy adding of custom log receivers. Its tested on at least the following platforms with Linux(Clang/gcc), Windows (mingw, visual studio 2013)
2014-01-17 07:34:53 +01:00
* *[g2log](https://bitbucket.org/KjellKod/g2log)*: The original. Simple, easy to modify and with the most OS support. Clients use g2log on environments such as OSX/Clang, Ubuntu, CentOS, Windows/mingw, Windows/Visual Studio.
2014-02-26 07:14:50 +01:00
* [g2log-dev ](https://bitbucket.org/KjellKod/g2log-dev )*: Acting as feature try-out and playground.
2014-01-17 07:34:53 +01:00
2012-10-18 07:35:09 +02:00
2014-01-17 07:34:53 +01:00
# G3log with sinks
2014-01-17 08:44:00 +01:00
[Sinks ](http://en.wikipedia.org/wiki/Sink_(computing )) are receivers of LOG calls. G3log comes with a default sink (*the same as G2log uses*) that can be used to save log to file. A sink can be of *any* class type without restrictions as long as it can either receive a LOG message as a *std::string* **or** as a *g2::LogMessageMover* .
2012-10-18 07:40:49 +02:00
2014-01-17 08:44:00 +01:00
The *std::string* comes pre-formatted. The *g2::LogMessageMover* is a wrapped struct that contains the raw data for custom handling in your own sink.
A sink is *owned* by the G3log and is added to the logger inside a ```std::unique_ptr```. The sink can be called though its public API through a *handler* which will asynchronously forward the call to the receiving sink.
2014-01-17 08:46:15 +01:00
```
auto sinkHandle = logworker->addSink(std2::make_unique< CustomSink > (),
&CustomSink::ReceiveLogMessage);
```
2014-01-17 08:15:40 +01:00
2014-01-17 08:47:01 +01:00
#Code Examples
2014-01-17 08:15:40 +01:00
Example usage where a custom sink is added. A function is called though the sink handler to the actual sink object.
2014-01-17 08:04:51 +01:00
```
// main.cpp
#include<g2log.hpp>
#include<g2logworker.hpp>
#include <std2_make_unique.hpp>
#include "CustomSink.h"
int main(int argc, char**argv) {
using namespace g2;
std::unique_ptr< LogWorker > logworker{ LogWorker::createWithNoSink() };
2014-01-17 08:15:40 +01:00
auto sinkHandle = logworker->addSink(std2::make_unique< CustomSink > (),
&CustomSink::ReceiveLogMessage);
2014-01-17 08:04:51 +01:00
2014-01-17 08:15:40 +01:00
// initialize the logger before it can receive LOG calls
2014-01-17 08:04:51 +01:00
initializeLogging(logworker.get());
LOG(WARNING) < < "This log call, may or may not happend before"
2014-01-17 08:15:40 +01:00
< < "the sinkHandle->call below";
2014-01-17 08:04:51 +01:00
// You can call in a thread safe manner public functions on your sink
// The call is asynchronously executed on your custom sink.
2014-01-17 08:20:14 +01:00
std::future< void > received = sinkHandle->call(& CustomSink::Foo,
param1, param2);
2014-01-17 08:04:51 +01:00
// before exiting you can always call g2::ShutdownLogging to avoid
2014-01-17 08:15:40 +01:00
// LOG calls from static entities that goes out of scope later.
2014-01-17 08:04:51 +01:00
g2::shutDownLogging();
}
// some_file.cpp : To show how easy it is to get the logger to work
// in other parts of your software
#include <g2log.hpp>
void SomeFunction() {
...
LOG(INFO) < < "Hello World";
}
```
Example usage where a the default file logger is used **and** a custom sink is added
```
// main.cpp
#include<g2log.hpp>
#include<g2logworker.hpp>
#include <std2_make_unique.hpp>
#include "CustomSink.h"
int main(int argc, char**argv) {
using namespace g2;
2014-01-17 08:20:14 +01:00
auto defaultHandler = LogWorker::createWithDefaultLogger(argv[0],
path_to_log_file);
2014-01-17 08:04:51 +01:00
// logger is initialized
g2::initializeLogging(defaultHandler.worker.get());
LOG(DEBUG) < < "Make log call, then add another sink";
2014-01-17 08:20:14 +01:00
defaultHandler.worker->addSink(std2::make_unique< CustomSink > (),
&CustomSink::ReceiveLogMessage);
2014-01-17 08:04:51 +01:00
...
}
```
2012-10-14 01:54:56 +02:00
2014-02-26 07:16:59 +01:00
# BUILDING g3log:
2011-11-05 17:36:07 +01:00
-----------
2012-06-02 22:04:28 +02:00
The default is to build an example binary 'g2log-FATAL'
2011-11-17 11:47:52 +01:00
I suggest you start with that, run it and view the created log also.
If you are interested in the performance or unit tests then you can
2012-10-18 15:52:08 +02:00
enable the creation of them in the g2log/CMakeLists.txt file. See that file for
more details
2011-11-17 11:47:52 +01:00
2014-01-17 08:15:40 +01:00
2014-01-17 08:20:14 +01:00
```
cd g2log
2011-11-05 17:36:07 +01:00
mkdir build
2014-01-17 08:20:14 +01:00
cd build
```
2014-01-17 08:15:40 +01:00
2014-02-26 07:18:18 +01:00
** Building on Linux **
2014-01-17 08:15:40 +01:00
```
cmake -DCMAKE_BUILD_TYPE=Release ..
2014-01-17 08:17:18 +01:00
make
```
2011-11-05 17:36:07 +01:00
2014-02-26 07:18:18 +01:00
** Building on Windows **
2014-01-28 17:19:58 +01:00
Please use the Visual Studio 12 (2013) command prompt "Developer command prompt"
2014-01-17 08:15:40 +01:00
```
2014-01-28 17:19:58 +01:00
cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 12" ..
2012-06-02 22:04:28 +02:00
msbuild g2log_by_kjellkod.sln /p:Configuration=Release
2014-01-17 08:15:40 +01:00
```
2011-11-05 17:36:07 +01:00
2014-02-26 07:16:59 +01:00
** Building on *nix with Clang: * *
2014-01-17 08:15:40 +01:00
```
cmake -DCMAKE_CXX_COMPILER=clang++ .. -DCMAKE_BUILD_TYPE=Release ..
make
```
2011-11-05 17:36:07 +01:00
2012-10-18 15:58:11 +02:00
2014-01-17 09:01:28 +01:00
2014-01-17 08:15:40 +01:00
#Enjoy
If you like this logger (or not) it would be nice with some feedback. That way I can improve g3log and g2log and it is also nice to see if someone is using it.
2011-11-05 17:36:07 +01:00
2014-01-17 08:15:40 +01:00
If you have ANY questions or problems please do not hesitate in contacting me on my blog
http://kjellkod.wordpress.com/2011/11/17/kjellkods-g2log-vs-googles-glog-are-asynchronous-loggers-taking-over/ or at < Hedstrom at KjellKod dot cc >
2011-11-05 17:36:07 +01:00
2011-11-17 11:57:37 +01:00
Good luck :)
Cheers
Kjell (a.k.a. KjellKod)