Corrected the merging compile errors...

--HG--
rename : g2log/src/crashhandler.h => g2log/src/crashhandler.hpp
rename : g2log/src/g2logmessage.h => g2log/src/g2logmessage.hpp
rename : g2log/src/g2time.h => g2log/src/g2time.hpp
This commit is contained in:
KjellKod 2013-07-29 22:43:33 -06:00
parent 05018e389a
commit ab07e5978d
18 changed files with 350 additions and 175 deletions

View File

@ -99,7 +99,7 @@ ENDIF(MSVC)
# GENERIC STEPS # GENERIC STEPS
file(GLOB SRC_FILES ${LOG_SRC}/*.h ${LOG_SRC}/*.hpp ${LOG_SRC}/*.cpp) file(GLOB SRC_FILES ${LOG_SRC}/*.h ${LOG_SRC}/*.hpp ${LOG_SRC}/*.cpp ${LOG_SRC}/*.ipp)
if(MSVC) if(MSVC)
list(REMOVE_ITEM SRC_FILES ${LOG_SRC}/crashhandler_unix.cpp) list(REMOVE_ITEM SRC_FILES ${LOG_SRC}/crashhandler_unix.cpp)
else() else()

View File

@ -4,7 +4,7 @@
* strings attached and no restrictions or obligations. * strings attached and no restrictions or obligations.
* ============================================================================*/ * ============================================================================*/
#include "crashhandler.h" #include "crashhandler.hpp"
#include "g2log.h" #include "g2log.h"
#include <csignal> #include <csignal>

View File

@ -4,7 +4,7 @@
* strings attached and no restrictions or obligations. * strings attached and no restrictions or obligations.
* ============================================================================*/ * ============================================================================*/
#include "crashhandler.h" #include "crashhandler.hpp"
#include "g2log.h" #include "g2log.h"
#include <csignal> #include <csignal>

99
g2log/src/g2filesink.cpp Normal file
View File

@ -0,0 +1,99 @@
#include "g2filesink.hpp"
#include "g2filesinkhelper.ipp"
#include <cassert>
namespace g2 {
using namespace internal;
g2FileSink::g2FileSink(const std::string& log_prefix, const std::string& log_directory)
: _log_file_with_path(log_directory)
, _log_prefix_backup(log_prefix)
, _outptr(new std::ofstream)
, _steady_start_time(std::chrono::steady_clock::now()) // TODO: ha en timer function steadyTimer som har koll på start
{
_log_prefix_backup = prefixSanityFix(log_prefix);
if (!isValidFilename(_log_prefix_backup)) {
std::cerr << "g2log: forced abort due to illegal log prefix [" << log_prefix << "]" << std::endl;
abort();
}
std::string file_name = createLogFileName(_log_prefix_backup);
_log_file_with_path = pathSanityFix(_log_file_with_path, file_name);
_outptr = createLogFile(_log_file_with_path);
if (!_outptr) {
std::cerr << "Cannot write log file to location, attempting current directory" << std::endl;
_log_file_with_path = file_name;
_outptr = createLogFile(_log_file_with_path);
}
assert(_outptr && "cannot open log file at startup");
addLogFileHeader();
}
g2FileSink::~g2FileSink() {
std::ostringstream ss_exit;
ss_exit << "\n\t\tg2log g2FileSink shutdown at: " << localtime_formatted(systemtime_now(), internal::time_formatted);
filestream() << ss_exit.str() << std::flush;
ss_exit << "\nLog file at: [" << _log_file_with_path << "]\n" << std::endl;
std::cerr << ss_exit << std::flush;
}
void g2FileSink::fileWrite(internal::LogEntry message) {
std::ofstream & out(filestream());
auto system_time = systemtime_now();
auto steady_time = std::chrono::steady_clock::now();
out << "\n" << localtime_formatted(system_time, date_formatted);
out << " " << localtime_formatted(system_time, time_formatted); // TODO: time kommer från LogEntry
out << "." << std::chrono::duration_cast<std::chrono::microseconds>(steady_time - _steady_start_time).count();
out << "\t" << message << std::flush;
}
// void g2FileSink::backgroundExitFatal(internal::FatalMessage fatal_message) {
//
// backgroundFileWrite(fatal_message.message_);
// backgroundFileWrite("Log flushed successfully to disk \nExiting");
// std::cerr << "g2log exiting after receiving fatal event" << std::endl;
// std::cerr << "Log file at: [" << log_file_with_path_ << "]\n" << std::endl << std::flush;
// filestream().close();
// exitWithDefaultSignalHandler(fatal_message.signal_id_);
// perror("g2log exited after receiving FATAL trigger. Flush message status: "); // should never reach this point
// }
std::string g2FileSink::changeLogFile(const std::string& directory) {
std::string file_name = createLogFileName(_log_prefix_backup);
std::string prospect_log = directory + file_name;
std::unique_ptr<std::ofstream> log_stream = createLogFile(prospect_log);
if (nullptr == log_stream) {
fileWrite("Unable to change log file. Illegal filename or busy? Unsuccessful log name was:" + prospect_log);
return ""; // no success
}
addLogFileHeader();
std::ostringstream ss_change;
ss_change << "\n\tChanging log file from : " << _log_file_with_path;
ss_change << "\n\tto new location: " << prospect_log << "\n";
fileWrite(ss_change.str().c_str());
ss_change.str("");
std::string old_log = _log_file_with_path;
_log_file_with_path = prospect_log;
_outptr = std::move(log_stream);
ss_change << "\n\tNew log file. The previous log file was at: ";
ss_change << old_log;
fileWrite(ss_change.str());
return _log_file_with_path;
}
std::string g2FileSink::fileName() {
return _log_file_with_path;
}
void g2FileSink::addLogFileHeader() {
filestream() << header();
}
} // g2

64
g2log/src/g2filesink.hpp Normal file
View File

@ -0,0 +1,64 @@
#ifndef PRIVATE_G2_FILE_SINK_H_
#define PRIVATE_G2_FILE_SINK_H_
//struct g2FileSink {
// g2FileSink(const std::string& log_prefix, const std::string& log_directory) {
// std::string lg = log_prefix;
// lg.append(": directory->");
// lg.append(log_directory);
// std::cout << lg << std::endl;
// }
//
// template<typename Arg>
// void writeToFile(Arg arg) {
// std::cout << arg << std::endl;
// }
//
// std::string logFileName() { return ""; }
//};
//
#include <string>
#include <memory>
#include "g2logmessage.hpp" // TODO refactoring, should include message instead
#include "g2time.hpp"
namespace g2 {
struct g2FileSink {
g2FileSink(const std::string& log_prefix, const std::string& log_directory);
virtual ~g2FileSink();
void fileWrite(internal::LogEntry message);
std::string changeLogFile(const std::string& directory);
std::string fileName();
private:
//void backgroundExitFatal(internal::FatalMessage fatal_message);
void addLogFileHeader();
std::string _log_file_with_path;
std::string _log_prefix_backup; // needed in case of future log file changes of directory
std::unique_ptr<std::ofstream> _outptr;
g2::steady_time_point _steady_start_time;
g2FileSink& operator=(const g2FileSink&); // c++11 feature not yet in vs2010 = delete;
g2FileSink(const g2FileSink& other); // c++11 feature not yet in vs2010 = delete;
std::ofstream & filestream() {
return *(_outptr.get());
}
};
} // g2
#endif // pimple

View File

@ -27,7 +27,7 @@
#include <mutex> #include <mutex>
#include "g2logworker.h" #include "g2logworker.h"
#include "crashhandler.h" #include "crashhandler.hpp"
#include <signal.h> #include <signal.h>
#include <thread> #include <thread>

View File

@ -25,7 +25,7 @@
#include <iostream> #include <iostream>
#include <cstdarg> #include <cstdarg>
#include <chrono> #include <chrono>
#include "g2logmessage.h" #include "g2logmessage.hpp"
class g2LogWorker; class g2LogWorker;

View File

@ -1,98 +1,109 @@
/** ========================================================================== /** ==========================================================================
* 2011 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes * 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 * with no warranties. This code is yours to share, use and modify with no
* strings attached and no restrictions or obligations. * strings attached and no restrictions or obligations.
* ============================================================================ * ============================================================================
* Filename:g2LogWorker.cpp Framework for Logging and Design By Contract * Filename:g2LogWorker.cpp Framework for Logging and Design By Contract
* Created: 2011 by Kjell Hedström * Created: 2011 by Kjell Hedström
* *
* PUBLIC DOMAIN and Not under copywrite protection. First published at KjellKod.cc * PUBLIC DOMAIN and Not under copywrite protection. First published at KjellKod.cc
* ********************************************* */ * ********************************************* */
#include "g2logworker.h" #include "g2logworker.h"
#include <fstream>
#include <sstream>
#include <cassert> #include <cassert>
#include <algorithm>
#include <string>
#include <chrono>
#include <future>
#include <functional> #include <functional>
#include "active.h" #include "active.h"
#include "g2log.h" #include "g2log.h"
#include "crashhandler.h" #include "g2time.hpp"
#include "g2time.h"
#include "g2future.h" #include "g2future.h"
#include "g2filesink.h" #include "crashhandler.hpp"
#include "std2_make_unique.hpp"
using namespace g2; using namespace g2;
using namespace g2::internal; using namespace g2::internal;
struct g2LogWorkerImpl struct g2LogWorkerImpl {
{ typedef std::shared_ptr<g2::internal::SinkWrapper> SinkWrapperPtr;
typedef std::shared_ptr<g2::internal::SinkWrapper> SinkWrapperPtr;
g2LogWorkerImpl(){}
~g2LogWorkerImpl(){ _bg.reset(); _sinks.clear(); }
std::unique_ptr<kjellkod::Active> _bg; std::unique_ptr<kjellkod::Active> _bg;
std::vector<SinkWrapperPtr> _sinks; std::vector<SinkWrapperPtr> _sinks;
std::shared_ptr<g2::SinkHandle<g2FileSink>> _default_sink_handle;
g2LogWorkerImpl() : _bg(kjellkod::Active::createActive()) { }
~g2LogWorkerImpl() {
_bg.reset();
_sinks.clear();
}
void bgSave(g2::internal::LogEntry msg) { void bgSave(g2::internal::LogEntry msg) {
for(auto& sink : _sinks) { for (auto& sink : _sinks) {
sink->send(msg); sink->send(msg);
} }
if (_sinks.empty()) {
std::ostringstream err_msg;
err_msg << "g2logworker has no sinks. Message: [" << msg << "]" << std::endl;
std::cerr << err_msg.str();
}
} }
void bgFatal(g2::internal::FatalMessage fatal_message){ void bgFatal(g2::internal::FatalMessage fatal_message) {
auto entry = fatal_message.message_; auto entry = fatal_message.message_;
bgSave(entry); bgSave(entry);
std::ostringstream end_message;
end_message << "Exiting after fatal event. Log flushed sucessfully t disk.\n";
bgSave(end_message.str());
std::cerr << "g2log sinks are flushed. Now exiting after receiving fatal event" << std::endl;
_sinks.clear(); // flush all queues _sinks.clear(); // flush all queues
exitWithDefaultSignalHandler(fatal_message.signal_id_); exitWithDefaultSignalHandler(fatal_message.signal_id_);
// should never reach this point
perror("g2log exited after receiving FATAL trigger. Flush message status: ");
} }
}; };
// Default constructor will have one sink: g2filesink. // Default constructor will have one sink: g2filesink.
g2LogWorker::g2LogWorker(const std::string& log_prefix, const std::string& log_directory)
: _pimpl(std2::make_unique<g2LogWorkerImpl>())
{
// auto unique = std::unique_ptr<g2FileSink>(new g2FileSink(log_prefix, log_directory));
// auto handle = addSink<g2FileSink>(std::move(unique), &g2FileSink::writeToFile);
// _pimpl._file_handle.reset(handle.release());
}
g2LogWorker::~g2LogWorker() g2LogWorker::g2LogWorker()
{ : _pimpl(std2::make_unique<g2LogWorkerImpl>()) {
_pimpl.reset();
} }
void g2LogWorker::save(g2::internal::LogEntry msg) g2LogWorker::~g2LogWorker() { _pimpl.reset(); }
{
_pimpl->_bg->send([this, msg]{ _pimpl->bgSave(msg); }); void g2LogWorker::save(g2::internal::LogEntry msg) {
//std::bind(&g2LogWorkerImpl::backgroundFileWrite, _pimpl.get(), msg)); _pimpl->_bg->send([this, msg] { _pimpl->bgSave(msg); });
} }
void g2LogWorker::fatal(g2::internal::FatalMessage fatal_message) void g2LogWorker::fatal(g2::internal::FatalMessage fatal_message) {
{ _pimpl->_bg->send([this, fatal_message] {_pimpl->bgFatal(fatal_message); });
_pimpl->_bg->send([this, fatal_message]{ _pimpl->bgFatal(fatal_message); }); //OR: td::bind(&g2LogWorkerImpl::backgroundExitFatal, _pimpl.get(), fatal_message));
//std::bind(&g2LogWorkerImpl::backgroundExitFatal, _pimpl.get(), fatal_message));
} }
void g2LogWorker::addWrappedSink(std::shared_ptr<g2::internal::SinkWrapper> sink) { void g2LogWorker::addWrappedSink(std::shared_ptr<g2::internal::SinkWrapper> sink) {
auto bg_addsink_call = [this, sink] { _pimpl->_sinks.push_back(sink); }; auto bg_addsink_call = [this, sink] { _pimpl->_sinks.push_back(sink); };
auto token_done = g2::spawn_task(bg_addsink_call, _pimpl->_bg.get()); auto token_done = g2::spawn_task(bg_addsink_call, _pimpl->_bg.get());
token_done.wait(); token_done.wait();
} }
std::shared_ptr<g2::SinkHandle<g2FileSink>> g2LogWorker::getFileSinkHandle() g2LogWorker::DefaultWorkerPair g2LogWorker::createWithDefaultFileSink(const std::string& log_prefix, const std::string& log_directory)
{ {
return _pimpl->_default_sink_handle; auto logger = g2LogWorker::createWithNoSink();
auto handle = logger->addSink(std2::make_unique<g2::g2FileSink>(log_prefix, log_directory), &g2FileSink::fileWrite);
auto pair = std::pair<std::unique_ptr<g2LogWorker>, std::unique_ptr<g2::SinkHandle<g2FileSink>> >(std::move(logger), std::move(handle));
return pair;
}
std::unique_ptr<g2LogWorker> g2LogWorker::createWithNoSink()
{
std::unique_ptr<g2LogWorker> logger(new g2LogWorker());
return logger;
} }

View File

@ -1,39 +1,47 @@
#ifndef G2_LOG_WORKER_H_ #ifndef G2_LOG_WORKER_H_
#define G2_LOG_WORKER_H_ #define G2_LOG_WORKER_H_
/** ========================================================================== /** ==========================================================================
* 2011 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes * 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 * with no warranties. This code is yours to share, use and modify with no
* strings attached and no restrictions or obligations. * strings attached and no restrictions or obligations.
* ============================================================================ * ============================================================================
* Filename:g2logworker.h Framework for Logging and Design By Contract * Filename:g2logworker.h Framework for Logging and Design By Contract
* Created: 2011 by Kjell Hedström * Created: 2011 by Kjell Hedström
* *
* PUBLIC DOMAIN and Not copywrited. First published at KjellKod.cc * PUBLIC DOMAIN and Not copywrited. First published at KjellKod.cc
* ********************************************* */ * ********************************************* */
#include <memory> #include <memory>
#include <future> #include <future>
#include <string> #include <string>
#include "std2_make_unique.hpp" #include <utility>
#include "g2log.h" #include "g2log.h"
#include "g2sinkwrapper.h" #include "g2sinkwrapper.h"
#include "g2sinkhandle.h" #include "g2sinkhandle.h"
#include "g2filesink.hpp"
#include "std2_make_unique.hpp"
struct g2LogWorkerImpl; struct g2LogWorkerImpl;
struct g2FileSink;
/** class g2LogWorker {
* \param log_prefix is the 'name' of the binary, this give the log name 'LOG-'name'-... g2LogWorker(); // Create only through factory
* \param log_directory gives the directory to put the log files */ void addWrappedSink(std::shared_ptr<g2::internal::SinkWrapper> wrapper);
class g2LogWorker
{ std::unique_ptr<g2LogWorkerImpl> _pimpl;
g2LogWorker(const g2LogWorker&); // c++11 feature not yet in vs2010 = delete;
g2LogWorker& operator=(const g2LogWorker&); // c++11 feature not yet in vs2010 = delete;
public: public:
g2LogWorker(const std::string& log_prefix, const std::string& log_directory);
virtual ~g2LogWorker(); virtual ~g2LogWorker();
typedef std::pair<std::unique_ptr<g2LogWorker>, std::unique_ptr<g2::SinkHandle<g2::g2FileSink>> > DefaultWorkerPair;
static DefaultWorkerPair createWithDefaultFileSink(const std::string& log_prefix, const std::string& log_directory);
static std::unique_ptr<g2LogWorker> createWithNoSink();
/// pushes in background thread (asynchronously) input messages to log file /// pushes in background thread (asynchronously) input messages to log file
void save(g2::internal::LogEntry entry); void save(g2::internal::LogEntry entry);
@ -43,35 +51,14 @@ public:
void fatal(g2::internal::FatalMessage fatal_message); void fatal(g2::internal::FatalMessage fatal_message);
template<typename T, typename DefaultLogCall> template<typename T, typename DefaultLogCall>
std::unique_ptr<g2::SinkHandle<T>> addSink(std::unique_ptr<T> real_sink, DefaultLogCall call) std::unique_ptr<g2::SinkHandle<T >> addSink(std::unique_ptr<T> real_sink, DefaultLogCall call) {
{
using namespace g2; using namespace g2;
using namespace g2::internal; using namespace g2::internal;
auto shared_sink = std::shared_ptr<T>(real_sink.release()); auto shared_sink = std::shared_ptr<T>(real_sink.release());
auto sink = std::make_shared<Sink<T>>(shared_sink, call); auto sink = std::make_shared < Sink < T >> (shared_sink, call);
auto add_result = addWrappedSink(sink); addWrappedSink(sink);
return std2::make_unique<SinkHandle<T>>(sink); return std2::make_unique < SinkHandle < T >> (sink);
} }
/// DEPRECATED - SHOULD BE Called through a sink handler instead
/// Attempt to change the current log file to another name/location.
/// returns filename with full path if successful, else empty string
//std::future<std::string> changeLogFile(const std::string& log_directory);
/// Probably only needed for unit-testing or specific log management post logging
/// request to get log name is processed in FIFO order just like any other background job.
//std::future<std::string> logFileName();
std::shared_ptr<g2::SinkHandle<g2FileSink>> getFileSinkHandle();
private:
void addWrappedSink(std::shared_ptr<g2::internal::SinkWrapper> wrapper);
std::unique_ptr<g2LogWorkerImpl> _pimpl;
g2LogWorker(const g2LogWorker&); // c++11 feature not yet in vs2010 = delete;
g2LogWorker& operator=(const g2LogWorker&); // c++11 feature not yet in vs2010 = delete;
}; };

View File

@ -8,7 +8,7 @@
#ifndef G2SINKWRAPPER_IPP #ifndef G2SINKWRAPPER_IPP
#define G2SINKWRAPPER_IPP #define G2SINKWRAPPER_IPP
#include "g2logmessage.h" #include "g2logmessage.hpp"
namespace g2 { namespace g2 {
namespace internal { namespace internal {

View File

@ -1,79 +1,84 @@
/** ========================================================================== /** ==========================================================================
* 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes * 2012 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 * with no warranties. This code is yours to share, use and modify with no
* strings attached and no restrictions or obligations. * strings attached and no restrictions or obligations.
* ============================================================================ * ============================================================================
* Filename:g2time.cpp cross-platform, thread-safe replacement for C++11 non-thread-safe * Filename:g2time.cpp cross-platform, thread-safe replacement for C++11 non-thread-safe
* localtime (and similar) * localtime (and similar)
* Created: 2012 by Kjell Hedström * Created: 2012 by Kjell Hedström
* *
* PUBLIC DOMAIN and Not under copywrite protection. First published for g2log at KjellKod.cc * PUBLIC DOMAIN and Not under copywrite protection. First published for g2log at KjellKod.cc
* ********************************************* */ * ********************************************* */
#include "g2time.h" #include "g2time.hpp"
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#include <ctime> #include <ctime>
#include <cassert>
#include <iomanip> #include <iomanip>
namespace g2 { namespace internal { namespace g2 {
// This mimics the original "std::put_time(const std::tm* tmb, const charT* fmt)" namespace internal {
// This is needed since latest version (at time of writing) of gcc4.7 does not implement this library function yet. // This mimics the original "std::put_time(const std::tm* tmb, const charT* fmt)"
// return value is SIMPLIFIED to only return a std::string // This is needed since latest version (at time of writing) of gcc4.7 does not implement this library function yet.
std::string put_time(const struct tm* tmb, const char* c_time_format) // return value is SIMPLIFIED to only return a std::string
{
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(__MINGW32__) std::string put_time(const struct tm* tmb, const char* c_time_format) {
std::ostringstream oss; #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
oss.fill('0'); std::ostringstream oss;
oss << std::put_time(const_cast<struct tm*>(tmb), c_time_format); // BOGUS hack done for VS2012: C++11 non-conformant since it SHOULD take a "const struct tm* " oss.fill('0');
return oss.str(); // BOGUS hack done for VS2012: C++11 non-conformant since it SHOULD take a "const struct tm* "
oss << std::put_time(const_cast<struct tm*> (tmb), c_time_format);
return oss.str();
#else // LINUX #else // LINUX
const size_t size = 1024; const size_t size = 1024;
char buffer[size]; // IMPORTANT: check now and then for when gcc will implement std::put_time finns. char buffer[size]; // IMPORTANT: check now and then for when gcc will implement std::put_time.
// ... also ... This is way more buffer space then we need // ... also ... This is way more buffer space then we need
auto success = std::strftime(buffer, size, c_time_format, tmb);
if (0 == success) auto success = std::strftime(buffer, size, c_time_format, tmb);
return c_time_format; // For this hack it is OK but in case of more permanent we really should throw here, or even assert if (0 == success)
return buffer; {
assert((0 != success) && "strftime fails with illegal formatting");
return c_time_format;
}
return buffer;
#endif #endif
}
} // internal
} // g2
namespace g2 {
std::time_t systemtime_now() {
system_time_point system_now = std::chrono::system_clock::now();
return std::chrono::system_clock::to_time_t(system_now);
} }
} // internal
} // g2
tm localtime(const std::time_t& time) {
struct tm tm_snapshot;
namespace g2 #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) && !defined(__GNUC__))
{ localtime_s(&tm_snapshot, &time); // windsows
std::time_t systemtime_now()
{
system_time_point system_now = std::chrono::system_clock::now();
return std::chrono::system_clock::to_time_t(system_now);
}
tm localtime(const std::time_t& time)
{
struct tm tm_snapshot;
#if !(defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
localtime_r(&time, &tm_snapshot); // POSIX
#else #else
localtime_s(&tm_snapshot, &time); // windsows localtime_r(&time, &tm_snapshot); // POSIX
#endif #endif
return tm_snapshot; return tm_snapshot;
} }
/// returns a std::string with content of time_t as localtime formatted by input format string /// returns a std::string with content of time_t as localtime formatted by input format string
/// * format string must conform to std::put_time /// * format string must conform to std::put_time
/// This is similar to std::put_time(std::localtime(std::time_t*), time_format.c_str()); /// This is similar to std::put_time(std::localtime(std::time_t*), time_format.c_str());
std::string localtime_formatted(const std::time_t& time_snapshot, const std::string& time_format)
{ std::string localtime_formatted(const std::time_t& time_snapshot, const std::string& time_format) {
std::tm t = localtime(time_snapshot); // could be const, but cannot due to VS2012 is non conformant for C++11's std::put_time (see above) std::tm t = localtime(time_snapshot); // could be const, but cannot due to VS2012 is non conformant for C++11's std::put_time (see above)
std::stringstream buffer; std::stringstream buffer;
buffer << g2::internal::put_time(&t, time_format.c_str()); // format example: //"%Y/%m/%d %H:%M:%S"); buffer << g2::internal::put_time(&t, time_format.c_str()); // format example: //"%Y/%m/%d %H:%M:%S");
return buffer.str(); return buffer.str();
} }
} // g2 } // g2

View File

@ -1,5 +1,5 @@
#ifndef G2_TIME_H_ #ifndef G2_TIME_HPP_
#define G2_TIME_H_ #define G2_TIME_HPP_
/** ========================================================================== /** ==========================================================================
* 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes * 2012 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 * with no warranties. This code is yours to share, use and modify with no
@ -22,6 +22,12 @@
namespace g2 namespace g2
{ {
namespace internal
{
static const std::string date_formatted = "%Y/%m/%d";
static const std::string time_formatted = "%H:%M:%S";
}
typedef std::chrono::steady_clock::time_point steady_time_point; typedef std::chrono::steady_clock::time_point steady_time_point;
typedef std::chrono::time_point<std::chrono::system_clock> system_time_point; typedef std::chrono::time_point<std::chrono::system_clock> system_time_point;
typedef std::chrono::milliseconds milliseconds; typedef std::chrono::milliseconds milliseconds;

View File

@ -13,7 +13,7 @@
#include <exception> #include <exception>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include "g2time.h" #include "g2time.hpp"
#include "g2future.h" #include "g2future.h"
TEST(Configuration, LOG) TEST(Configuration, LOG)

View File

@ -51,13 +51,15 @@
// std::string changeDirectoryOrName(std::string new_file_to_create) { // std::string changeDirectoryOrName(std::string new_file_to_create) {
// static std::mutex m; // static std::mutex m;
// static int count; // static int count;
// std::string add_count;
// std::lock_guard<std::mutex> lock(m); // std::lock_guard<std::mutex> lock(m);
// { // {
// std::string add_count = std::to_string(++count) + "_"; // add_count = std::to_string(++count) + "_";
// auto new_log = g_logger_ptr->changeLogFile(new_file_to_create + add_count).get(); // auto new_log = g_logger_ptr->changeLogFile(new_file_to_create + add_count).get();
// if (!new_log.empty()) g_cleaner_ptr->addLogToClean(new_log); // if (!new_log.empty()) g_cleaner_ptr->addLogToClean(new_log);
// return new_log; // return new_log;
// } // }
// return add_count;
// } // }
//} // anonymous //} // anonymous
// //

View File

@ -11,7 +11,7 @@
#include "g2sink.h" #include "g2sink.h"
#include "g2sinkwrapper.h" #include "g2sinkwrapper.h"
#include "g2sinkhandle.h" #include "g2sinkhandle.h"
#include "g2logmessage.h" #include "g2logmessage.hpp"
using namespace std; using namespace std;

View File

@ -3,7 +3,7 @@
#include "testing_helpers.h" #include "testing_helpers.h"
#include "g2log.h" #include "g2log.h"
#include "g2logworker.h" #include "g2logworker.h"
#include "g2filesink.h" #include "g2filesink.hpp"
#include "std2_make_unique.hpp" #include "std2_make_unique.hpp"
using namespace std; using namespace std;
@ -21,14 +21,15 @@ ScopedCout::~ScopedCout() {
} }
RestoreLogger::RestoreLogger(std::string directory) RestoreLogger::RestoreLogger(std::string directory)
: logger_(std2::make_unique<g2LogWorker>("UNIT_TEST_LOGGER", directory)) { : logger_(g2LogWorker::createWithNoSink()) {
using namespace g2;
auto filehandler = logger_->addSink(std2::make_unique<g2FileSink>("UNIT_TEST_LOGGER", directory), &g2FileSink::fileWrite);
oldworker = g2::shutDownLogging(); oldworker = g2::shutDownLogging();
g2::initializeLogging(logger_.get()); initializeLogging(logger_.get());
g2::internal::changeFatalInitHandlerForUnitTesting(); internal::changeFatalInitHandlerForUnitTesting();
auto filehandler = logger_->getFileSinkHandle(); auto filename = filehandler->call(&g2FileSink::fileName);
auto filename = filehandler->call(&g2FileSink::logFileName);
if (!filename.valid()) ADD_FAILURE(); if (!filename.valid()) ADD_FAILURE();
log_file_ = filename.get(); log_file_ = filename.get();
} }