diff --git a/libs/main/application/pilog.cpp b/libs/main/application/pilog.cpp new file mode 100644 index 00000000..7a47a462 --- /dev/null +++ b/libs/main/application/pilog.cpp @@ -0,0 +1,128 @@ +/* + PIP - Platform Independent Primitives + High-level log + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "pilog.h" + +#include "pidir.h" +#include "piliterals_time.h" +#include "pitime.h" + + +//! \class PILog pilog.h +//! \details +//! \~english \section PILog_sec0 Synopsis +//! \~russian \section PILog_sec0 Краткий обзор +//! \~english +//! This class provide handy parsing of command-line arguments. First you should add +//! arguments to %PICLI with function \a addArgument(). Then you can check if there +//! is some argument in application command-line with function \a hasArgument(), +//! or obtain argument value by \a argumentValue(). +//! +//! \~russian +//! Этот класс предоставляет удобный механизм для разбора аргументов командной строки. +//! Сперва необходимо добавить аргументы в %PICLI с помощью методов \a addArgument(). +//! Далее можно проверять аргументы на наличие в командной строке методом \a hasArgument(), +//! а также получать их значения при помощи \a argumentValue(). +//! +//! \~english \section PICLI_sec1 Example +//! \~russian \section PICLI_sec1 Пример +//! \~\code +//! int main(int argc, char ** argv) { +//! PICLI cli(argc, argv); +//! cli.addArgument("console"); +//! cli.addArgument("debug"); +//! cli.addArgument("Value", "v", "value", true); +//! if (cli.hasArgument("console")) +//! piCout << "console active"; +//! if (cli.hasArgument("debug")) +//! piCout << "debug active"; +//! piCout << "Value =" << cli.argumentValue("Value"); +//! return 0; +//! } +//! \endcode +//! +//! \~english These executions are similar: +//! \~russian Эти вызовы будут идентичны: +//! +//! \~\code +//! a.out -cd -v 10 +//! a.out --value 10 -dc +//! a.out -c -v 10 -d +//! a.out --console -d -v 10 +//! a.out --debug -c --value 10 +//! \endcode +//! + + +PILog::PILog(): PIThread(), log_ts(&log_file) { + split_time = 8_h; +} + + +PILog::~PILog() { + stopAndWait(); +} + + +void PILog::setDir(const PIString & d) { + stopAndWait(); + log_dir = d; + PIDir::make(log_dir); + newFile(); + start(); +} + + +void PILog::enqueue(const PIString & msg) { + if (log_file.isClosed()) return; + auto cur_dt = PIDateTime::fromSystemTime(PISystemTime::current()); + PIMutexLocker ml(log_mutex); + queue.enqueue(cur_dt.toString("hh:mm:ss.zzz") + " - " + msg); +} + + +void PILog::newFile() { + log_file.open(log_dir + "/" + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss__p" + PIString::fromNumber(++part_number) + ".txt"), + PIIODevice::ReadWrite); +} + + +void PILog::run() { + if (split_tm.elapsed() >= split_time) { + split_tm.reset(); + newFile(); + } + log_mutex.lock(); + if (queue.isEmpty()) { + log_mutex.unlock(); + piMSleep(20); + return; + } + log_mutex.unlock(); + while (true) { + log_mutex.lock(); + if (queue.isEmpty()) { + log_mutex.unlock(); + return; + } + auto qi = queue.dequeue(); + log_mutex.unlock(); + log_ts << qi << "\n"; + } +} diff --git a/libs/main/application/pilog.h b/libs/main/application/pilog.h new file mode 100644 index 00000000..14445ef3 --- /dev/null +++ b/libs/main/application/pilog.h @@ -0,0 +1,66 @@ +/*! \file pilog.h + * \ingroup Application + * \~\brief + * \~english High-level log + * \~russian Высокоуровневый лог + */ +/* + PIP - Platform Independent Primitives + High-level log + Ivan Pelipenko peri4ko@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef PIlog_H +#define PIlog_H + +#include "pifile.h" +#include "piiostream.h" +#include "pithread.h" + +//! \ingroup Application +//! \~\brief +//! \~english High-level log +//! \~russian Высокоуровневый лог +class PIP_EXPORT PILog: public PIThread { + PIOBJECT_SUBCLASS(PILog, PIThread) + +public: + PILog(); + ~PILog(); + + PIString dir() const { return log_dir; } + void setDir(const PIString & d); + + PISystemTime splitTime() const { return split_time; } + void setSplitTime(PISystemTime st) { split_time = st; } + + void enqueue(const PIString & msg); + +private: + void newFile(); + void run() override; + + PIMutex log_mutex; + PIFile log_file; + PIIOTextStream log_ts; + PITimeMeasurer split_tm; + PISystemTime split_time; + PIString log_dir; + PIQueue queue; + int part_number = -1; +}; + +#endif diff --git a/libs/main/pip.h b/libs/main/pip.h index a5018103..297f31d6 100644 --- a/libs/main/pip.h +++ b/libs/main/pip.h @@ -20,6 +20,7 @@ #ifndef PIP_H #define PIP_H +#include "piapplicationmodule.h" #include "picloudmodule.h" #include "piconsolemodule.h" #include "picontainersmodule.h" diff --git a/libs/main/types/pisystemtime.cpp b/libs/main/types/pisystemtime.cpp index abf8c258..eaa7f8fc 100644 --- a/libs/main/types/pisystemtime.cpp +++ b/libs/main/types/pisystemtime.cpp @@ -117,6 +117,11 @@ void PISystemTime::toTimespec(void * ts) { } +PISystemTime::Frequency PISystemTime::toFrequency() { + return PISystemTime::Frequency::fromSystemTime(*this); +} + + PIString PISystemTime::toString() const { static const PISystemTime is_abs_thr = 3650._d; // 10 years if ((*this) >= is_abs_thr) return PIDateTime::fromSystemTime((*this)).toString("yyyy-MM-dd hh:mm:ss.zzz"); diff --git a/libs/main/types/pisystemtime.h b/libs/main/types/pisystemtime.h index 0fc0d7d2..e089b4b5 100644 --- a/libs/main/types/pisystemtime.h +++ b/libs/main/types/pisystemtime.h @@ -260,6 +260,10 @@ public: //! \~russian На *nix системах присваивает время к timespec структуре void toTimespec(void * ts); + //! \~english Returns \a Frequency that corresponds this time interval + //! \~russian Возвращает \a Frequency соответствующую этому временному интервалу + PISystemTime::Frequency toFrequency(); + //! \~english Returns "yyyy-MM-dd hh:mm:ss.zzz" for absolute time and " ..." for relative //! \~russian Возвращает "yyyy-MM-dd hh:mm:ss.zzz" для абсолютного времени и " ..." для относительного PIString toString() const;