Skip to content

Commit

Permalink
Gimesketvirtadien's time requested changes (#104)
Browse files Browse the repository at this point in the history
* Added "removeSink" method and related functionality to LogWorker API

* Added a new API for plugging in custom Timestamp generator.

* Revert "Added "removeSink" method and related functionality to LogWorker API"

This reverts commit c9cee5d.

* Dropping shared_ptr<Timestamp> in log messages and using regular vars

* Moving to standard timespec struct from custom Timestamp

* Wiring timespec timestamps with formating routine

* Falling back to clock_gettime

* Reverting g3 API changes

* Optimizing format string generation

* Removed _microseconds from LogMessage

* Implemented sec fractional format key

* Optimization of format string generation

* Adjusting comments

* Refining localtime_formatted by introducing two helper functions

* refactored and simplified code

* fixed up some commented away unit tests

* refactoring message specifics tests to it's own test

* Use gcc 4.9

* C++14 for Linux

* Update .travis.yml

* Update buildAndRunTests.sh

* lower case in `-std=c++14`

* -lrt flag for gcc

* Added support for high precision clock on Linux/gcc (already there now for OSX). Windows is still missing

* intermediate comments

* Clarified for some code readers the mysterious use of assert in an expression that is always true

* refactored + renamed functions and constants. Added unit test for retrieving fractional type

* committing changes previously fixed - finished unit testing for g3::internal::time::GetFractional(..)

* added unit test for fractional to string

* added missing unit tests for localtime_formatted

* fixed? nano / microsec functionality to timer

* test
  • Loading branch information
Kjell Hedström authored Aug 11, 2016
1 parent ff72216 commit 86473c6
Show file tree
Hide file tree
Showing 14 changed files with 488 additions and 218 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ before_install:
sudo apt-get update -qq;
sudo apt-get install python-software-properties;
sudo apt-get update;
sudo apt-get install gcc-4.8 g++-4.8;
sudo apt-get install gcc-5 g++-5;
sudo add-apt-repository --yes ppa:kalakris/cmake;
sudo apt-get update -qq;
sudo apt-get install cmake;
fi

install:
# gcc 4.8
- if [ "$CXX" == "g++" ]; then sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 10; fi
- if [ "$CXX" == "g++" ]; then sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 10; fi
# gcc 5
- if [ "$CXX" == "g++" ]; then sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 10; fi
- if [ "$CXX" == "g++" ]; then sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 10; fi

# clang 3.4
- if [ "$CXX" == "clang++" ]; then sudo apt-get install --allow-unauthenticated -qq clang-3.4; fi
Expand Down
2 changes: 1 addition & 1 deletion Build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ ELSEIF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "-Wall -Wunused -std=c++11 -pthread -D_GLIBCXX_USE_NANOSLEEP -D_GLIBCXX_USE_SCHED_YIELD")
ELSE()
set(PLATFORM_LINK_LIBRIES rt)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -rdynamic -Wunused -std=c++11 -pthread -D_GLIBCXX_USE_NANOSLEEP -D_GLIBCXX_USE_SCHED_YIELD")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -rdynamic -Wunused -std=c++11 -pthread -lrt -D_GLIBCXX_USE_NANOSLEEP -D_GLIBCXX_USE_SCHED_YIELD")
ENDIF()
ENDIF()

Expand Down
9 changes: 6 additions & 3 deletions example/Example.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#
# ==============================================================

IF (MSVC OR MINGW)
set(EXAMPLE_PLATFORM_LINK_LIBRIES dbghelp)
ENDIF()

set(DIR_EXAMPLE ${g3log_SOURCE_DIR}/example)
option (ADD_FATAL_EXAMPLE "Fatal (fatal-crashes/contract) examples " ON)
Expand All @@ -34,9 +37,9 @@
add_executable(g3log-FATAL-sigsegv ${DIR_EXAMPLE}/main_sigsegv.cpp)
add_executable(g3log-FATAL-choice ${DIR_EXAMPLE}/main_fatal_choice.cpp)

target_link_libraries(g3log-FATAL-contract ${G3LOG_LIBRARY})
target_link_libraries(g3log-FATAL-sigsegv ${G3LOG_LIBRARY})
target_link_libraries(g3log-FATAL-choice ${G3LOG_LIBRARY})
target_link_libraries(g3log-FATAL-contract ${G3LOG_LIBRARY} ${EXAMPLE_PLATFORM_LINK_LIBRIES})
target_link_libraries(g3log-FATAL-sigsegv ${G3LOG_LIBRARY} ${EXAMPLE_PLATFORM_LINK_LIBRIES})
target_link_libraries(g3log-FATAL-choice ${G3LOG_LIBRARY} ${EXAMPLE_PLATFORM_LINK_LIBRIES})
ELSE()
MESSAGE("-DADD_SIMPLE_EXAMPLE=OFF")
ENDIF (ADD_FATAL_EXAMPLE)
72 changes: 42 additions & 30 deletions scripts/buildAndRunTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,49 @@ set -ev
unzip -o 3rdParty/gtest/gtest-1.7.0.zip -d 3rdParty/gtest


if [ "$CXX" = "g++" ]; then export CXX=g++-4.8; fi
if [ "$CXX" = "clang++" ]; then export CXX=clang++-3.4; fi
echo $TRAVIS_OS_NAME
echo $CXX
#if [ "$CXX" = "g++" ]; then export CXX=g++-5; fi
#if [ "$CXX" = "clang++" ]; then export CXX=clang++-3.4; fi
#echo $TRAVIS_OS_NAME
#echo $CXX


mkdir -p build_travis
cd build_travis

if [[ $CXX == *"g++"* ]]
then
echo "Testing with g++"
cmake -DUSE_DYNAMIC_LOGGING_LEVELS=ON -DADD_G3LOG_UNIT_TEST=ON ..
make -j
./test_concept_sink
./test_configuration
./test_dynamic_loaded_shared_lib
./test_filechange
./test_io
./test_sink
fi

if [ "$CXX" = "clang++-3.4" ]
then
echo "Testing with Clang++"
cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS=-std=gnu++11 -DUSE_G3LOG_UNIT_TEST=ON ..
make -j
./test_concept_sink
./test_configuration
#./test_dynamic_loaded_shared_lib
./test_filechange
./test_io
./test_sink
fi
# OSX: cmake -DCMAKE_CXX_FLAGS=-std=gnu++11 -DADD_G3LOG_UNIT_TEST=ON ..
cmake -DCMAKE_CXX_FLAGS=-std=c++14 -DADD_G3LOG_UNIT_TEST=ON ..
make -j
./test_concept_sink && \
./test_cpp_future_concepts && \
./test_dynamic_loaded_shared_lib | true && \
./test_filechange && \
./test_io && \
./test_sink && \
./test_message




#if [[ $CXX == *"g++"* ]]
#then
# echo "Testing with g++"
# cmake -DUSE_DYNAMIC_LOGGING_LEVELS=ON -DADD_G3LOG_UNIT_TEST=ON ..
# make -j
# ./test_concept_sink
# ./test_cpp_future_concepts
# ./test_dynamic_loaded_shared_lib
# ./test_filechange
# ./test_io
# ./test_sink
#else
#if [ "$CXX" = "clang++-3.4" ]
#then
# echo "Testing with Clang++"
# cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS=-std=gnu++11 -DADD_G3LOG_UNIT_TEST=ON ..
# make -j
# ./test_concept_sink
# ./test_cpp_future_concepts
# ./test_dynamic_loaded_shared_lib
# ./test_filechange
# ./test_io
# ./test_sink
# fi
2 changes: 1 addition & 1 deletion src/filesinkhelper.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ namespace g3 {
// Day Month Date Time Year: is written as "%a %b %d %H:%M:%S %Y" and formatted output as : Wed Sep 19 08:28:16 2012
ss_entry << "\t\tg3log created log at: " << g3::localtime_formatted(g3::systemtime_now(), "%a %b %d %H:%M:%S %Y") << "\n";
ss_entry << "\t\tLOG format: [YYYY/MM/DD hh:mm:ss uuu* LEVEL FILE->FUNCTION:LINE] message";
ss_entry << "\t\t(uuu*: microsecond counter since initialization of log worker)\n\n";
ss_entry << "\t\t(uuu*: microseconds fractions of the seconds value)\n\n";
return ss_entry.str();
}

Expand Down
3 changes: 0 additions & 3 deletions src/g3log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ namespace g3 {
}





namespace internal {

bool isLoggingInitialized() {
Expand Down
8 changes: 1 addition & 7 deletions src/g3log/logmessage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ namespace g3 {
/// use a different format string to get a different look on the time.
// default look is Y/M/D H:M:S
std::string timestamp(const std::string& time_format = {internal::date_formatted + " " + internal::time_formatted}) const;
std::string microseconds() const {
return std::to_string(_microseconds);
}

std::string message() const {
return _message;
Expand Down Expand Up @@ -87,9 +84,8 @@ namespace g3 {
// Complete access to the raw data in case the helper functions above
// are not enough.
//
std::time_t _timestamp;
timespec _timestamp;
std::thread::id _call_thread_id;
int64_t _microseconds;
std::string _file;
int _line;
std::string _function;
Expand All @@ -103,7 +99,6 @@ namespace g3 {
using std::swap;
swap(first._timestamp, second._timestamp);
swap(first._call_thread_id, second._call_thread_id);
swap(first._microseconds, second._microseconds);
swap(first._file, second._file);
swap(first._line, second._line);
swap(first._function, second._function);
Expand All @@ -116,7 +111,6 @@ namespace g3 {




/** Trigger for flushing the message queue and exiting the application
* A thread that causes a FatalMessage will sleep forever until the
* application has exited (after message flush) */
Expand Down
35 changes: 27 additions & 8 deletions src/g3log/time.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,50 @@
// namespace g3::internal ONLY in g3time.cpp
// std::string put_time(const struct tm* tmb, const char* c_time_format)

namespace g3
{
namespace internal
{
namespace g3 {
namespace internal {
enum class Fractional {Millisecond, Microsecond, Nanosecond, NanosecondDefault};
Fractional getFractional(const std::string& format_buffer, size_t pos);
std::string to_string(const timespec& time_snapshot, Fractional fractional);
static const std::string date_formatted = "%Y/%m/%d";
static const std::string time_formatted = "%H:%M:%S";
}
// %f: fractions of seconds (%f is nanoseconds)
// %f3: milliseconds, 3 digits: 001
// %6: microseconds: 6 digits: 000001 --- default for the time_format
// %f9, %f: nanoseconds, 9 digits: 000000001
static const std::string time_formatted = "%H:%M:%S %f6";
} // internal

typedef std::chrono::time_point<std::chrono::system_clock> system_time_point;
typedef std::chrono::milliseconds milliseconds;
typedef std::chrono::microseconds microseconds;



// wrap for std::chrono::system_clock::now()
std::time_t systemtime_now();

// OSX, Windows needed wrapper for std::timespec_get(struct timespec *ts, int base)
// OSX and Windows also lacks the POSIX clock_gettime(int base, struct timespec *ts)
// so for that reason we go with the std::timespec_get(...) but wrap it
int timespec_get(struct timespec* ts/*, int base*/);

// This mimics the original "std::put_time(const std::tm* tmb, const charT* fmt)"
// This is needed since latest version (at time of writing) of gcc4.7 does not implement this library function yet.
// return value is SIMPLIFIED to only return a std::string
std::string put_time(const struct tm* tmb, const char* c_time_format);

/** return time representing POD struct (ref ctime + wchar) that is normally
* retrieved with std::localtime. g3::localtime is threadsafe which std::localtime is not.
* g3::localtime is probably used together with @ref g3::systemtime_now */
tm localtime(const std::time_t &time);
tm localtime(const std::time_t& time);

/** format string must conform to std::put_time's demands.
* WARNING: At time of writing there is only so-so compiler support for
* std::put_time. A possible fix if your c++11 library is not updated is to
* modify this to use std::strftime instead */
std::string localtime_formatted(const std::time_t &time_snapshot, const std::string &time_format) ;
std::string localtime_formatted(const timespec& time_snapshot, const std::string& time_format) ;
std::string localtime_formatted(const std::time_t& time_snapshot, const std::string& time_format) ;
}



34 changes: 13 additions & 21 deletions src/logmessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@
#include <mutex>

namespace {
std::once_flag g_start_time_flag;
std::chrono::steady_clock::time_point g_start_time;

int64_t microsecondsCounter() {
std::call_once(g_start_time_flag, []() {
g_start_time = std::chrono::steady_clock::now();
});
auto now = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(now - g_start_time).count();
}

std::string splitFileName(const std::string& str) {
size_t found;
found = str.find_last_of("(/\\");
Expand All @@ -38,7 +27,7 @@ namespace g3 {
// helper for setting the normal log details in an entry
std::string LogDetailsToString(const LogMessage& msg) {
std::string out;
out.append("\n" + msg.timestamp() + " " + msg.microseconds() + "\t"
out.append("\n" + msg.timestamp() + "\t"
+ msg.level() + " [" + msg.file() + "->" + msg.function() + ":" + msg.line() + "]\t");
return out;
}
Expand All @@ -54,7 +43,7 @@ namespace g3 {
// helper for fatal signal
std::string fatalSignalToString(const LogMessage& msg) {
std::string out; // clear any previous text and formatting
out.append("\n" + msg.timestamp() + "." + msg.microseconds()
out.append("\n" + msg.timestamp()
+ "\n\n***** FATAL SIGNAL RECEIVED ******* \n"
+ '"' + msg.message() + '"');
return out;
Expand All @@ -64,7 +53,7 @@ namespace g3 {
// helper for fatal exception (windows only)
std::string fatalExceptionToString(const LogMessage& msg) {
std::string out; // clear any previous text and formatting
out.append("\n" + msg.timestamp() + "." + msg.microseconds()
out.append("\n" + msg.timestamp()
+ "\n\n***** FATAL EXCEPTION RECEIVED ******* \n"
+ '"' + msg.message() + '"');
return out;
Expand Down Expand Up @@ -122,7 +111,7 @@ namespace g3 {


std::string LogMessage::timestamp(const std::string& time_look) const {
return localtime_formatted(_timestamp, time_look);
return g3::localtime_formatted(_timestamp, time_look);
}


Expand All @@ -136,14 +125,17 @@ namespace g3 {

LogMessage::LogMessage(const std::string& file, const int line,
const std::string& function, const LEVELS& level)
: _timestamp(g3::systemtime_now())
, _call_thread_id(std::this_thread::get_id())
, _microseconds(microsecondsCounter())
: _call_thread_id(std::this_thread::get_id())
, _file(splitFileName(file))
, _line(line)
, _function(function)
, _level(level)
{}
{
g3::timespec_get(&_timestamp/*, TIME_UTC*/);
// Another possibility could be to Falling back to clock_gettime as TIME_UTC
// is not recognized by travis CI.
// i.e. clock_gettime(CLOCK_REALTIME, &_timestamp);
}


LogMessage::LogMessage(const std::string& fatalOsSignalCrashMessage)
Expand All @@ -154,7 +146,6 @@ namespace g3 {
LogMessage::LogMessage(const LogMessage& other)
: _timestamp(other._timestamp)
, _call_thread_id(other._call_thread_id)
, _microseconds(other._microseconds)
, _file(other._file)
, _line(other._line)
, _function(other._function)
Expand All @@ -166,7 +157,6 @@ namespace g3 {
LogMessage::LogMessage(LogMessage &&other)
: _timestamp(other._timestamp)
, _call_thread_id(other._call_thread_id)
, _microseconds(other._microseconds)
, _file(std::move(other._file))
, _line(other._line)
, _function(std::move(other._function))
Expand All @@ -183,6 +173,8 @@ namespace g3 {
return oss.str();
}



FatalMessage::FatalMessage(const LogMessage& details, g3::SignalType signal_id)
: LogMessage(details), _signal_id(signal_id) { }

Expand Down
Loading

0 comments on commit 86473c6

Please sign in to comment.