forked from KjellKod/g3log
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogworker.hpp
118 lines (91 loc) · 4.6 KB
/
logworker.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#pragma once
/** ==========================================================================
* 2011 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
* with no warranties. This code is yours to share, use and modify with no
* strings attached and no restrictions or obligations.
*
* For more information see g3log/LICENSE or refer refer to http://unlicense.org
* ============================================================================
* Filename:g3logworker.h Framework for Logging and Design By Contract
* Created: 2011 by Kjell Hedström
*
* PUBLIC DOMAIN and Not copywrited. First published at KjellKod.cc
* ********************************************* */
#include "g3log/g3log.hpp"
#include "g3log/sinkwrapper.hpp"
#include "g3log/sinkhandle.hpp"
#include "g3log/filesink.hpp"
#include "g3log/logmessage.hpp"
#include "g3log/std2_make_unique.hpp"
#include <memory>
#include <string>
#include <vector>
namespace g3 {
class LogWorker;
struct LogWorkerImpl;
using FileSinkHandle = g3::SinkHandle<g3::FileSink>;
/// Background side of the LogWorker. Internal use only
struct LogWorkerImpl final {
typedef std::shared_ptr<g3::internal::SinkWrapper> SinkWrapperPtr;
std::vector<SinkWrapperPtr> _sinks;
std::unique_ptr<kjellkod::Active> _bg; // do not change declaration order. _bg must be destroyed before sinks
LogWorkerImpl();
~LogWorkerImpl() = default;
void bgSave(g3::LogMessagePtr msgPtr);
void bgFatal(FatalMessagePtr msgPtr);
LogWorkerImpl(const LogWorkerImpl&) = delete;
LogWorkerImpl& operator=(const LogWorkerImpl&) = delete;
};
/// Front end of the LogWorker. API that is usefule is
/// addSink( sink, default_call ) which returns a handle to the sink. See below and REAME for usage example
/// save( msg ) : internal use
/// fatal ( fatal_msg ) : internal use
class LogWorker final {
LogWorker() = default;
void addWrappedSink(std::shared_ptr<g3::internal::SinkWrapper> wrapper);
LogWorkerImpl _impl;
LogWorker(const LogWorker&) = delete;
LogWorker& operator=(const LogWorker&) = delete;
public:
~LogWorker();
/// Creates the LogWorker with no sinks. See exampel below on @ref addSink for how to use it
/// if you want to use the default file logger then see below for @ref addDefaultLogger
static std::unique_ptr<LogWorker> createLogWorker();
/**
A convenience function to add the default g3::FileSink to the log worker
@param log_prefix that you want
@param log_directory where the log is to be stored.
@return a handle for API access to the sink. See the README for example usage
@verbatim
Example:
using namespace g3;
std::unique_ptr<LogWorker> logworker {LogWorker::createLogWorker()};
auto handle = addDefaultLogger("my_test_log", "/tmp");
initializeLogging(logworker.get()); // ref. g3log.hpp
std::future<std::string> log_file_name = sinkHandle->call(&FileSink::fileName);
std::cout << "The filename is: " << log_file_name.get() << std::endl;
// something like: /tmp/my_test_log.g3log.20150819-100300.log
*/
std::unique_ptr<FileSinkHandle> addDefaultLogger(const std::string& log_prefix, const std::string& log_directory, const std::string& default_id = "g3log");
/// Adds a sink and returns the handle for access to the sink
/// @param real_sink unique_ptr ownership is passed to the log worker
/// @param call the default call that should receive either a std::string or a LogMessageMover message
/// @return handle to the sink for API access. See usage example below at @ref addDefaultLogger
template<typename T, typename DefaultLogCall>
std::unique_ptr<g3::SinkHandle<T>> addSink(std::unique_ptr<T> real_sink, DefaultLogCall call) {
using namespace g3;
using namespace g3::internal;
auto sink = std::make_shared<Sink<T>> (std::move(real_sink), call);
addWrappedSink(sink);
return std2::make_unique<SinkHandle<T>> (sink);
}
/// internal:
/// pushes in background thread (asynchronously) input messages to log file
void save(LogMessagePtr entry);
/// internal:
// pushes a fatal message on the queue, this is the last message to be processed
/// this way it's ensured that all existing entries were flushed before 'fatal'
/// Will abort the application!
void fatal(FatalMessagePtr fatal_message);
};
} // g3