UniSet  2.8.0
LogDB.h
1 /*
2  * Copyright (c) 2015 Pavel Vainerman.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, version 2.1.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Lesser Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 // --------------------------------------------------------------------------
20 // --------------------------------------------------------------------------
21 #ifndef LogDB_H_
22 #define LogDB_H_
23 // --------------------------------------------------------------------------
24 #include <queue>
25 #include <memory>
26 #include <mutex>
27 #include <condition_variable>
28 #include <chrono>
29 #include <ev++.h>
30 #include <sigc++/sigc++.h>
31 #include <Poco/JSON/Object.h>
32 #include <Poco/Net/WebSocket.h>
33 #include "UniSetTypes.h"
34 #include "LogAgregator.h"
35 #include "DebugStream.h"
36 #include "SQLiteInterface.h"
37 #include "EventLoopServer.h"
38 #include "UTCPStream.h"
39 #include "LogReader.h"
40 #include "UHttpRequestHandler.h"
41 #include "UHttpServer.h"
42 #include "UTCPCore.h"
43 // -------------------------------------------------------------------------
44 namespace uniset
45 {
46  //------------------------------------------------------------------------------------------
178  class LogDB:
179  public EventLoopServer
180 #ifndef DISABLE_REST_API
181  , public Poco::Net::HTTPRequestHandler
182 #endif
183  {
184  public:
185  LogDB( const std::string& name, int argc, const char* const* argv, const std::string& prefix );
186  virtual ~LogDB();
187 
189  static std::shared_ptr<LogDB> init_logdb( int argc, const char* const* argv, const std::string& prefix = "logdb-" );
190 
192  static void help_print();
193 
194  inline std::shared_ptr<DebugStream> log()
195  {
196  return dblog;
197  }
198 
199  void run( bool async );
200 #ifndef DISABLE_REST_API
201  virtual void handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) override;
202  void onWebSocketSession( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp );
203 #endif
204 
205  protected:
206 
207  class Log;
208  class LogWebSocket;
209 
210  virtual void evfinish() override;
211  virtual void evprepare() override;
212  void onCheckBuffer( ev::timer& t, int revents );
213  void onActivate( ev::async& watcher, int revents ) ;
214  void addLog( Log* log, const std::string& txt );
215  void log2File( Log* log, const std::string& txt );
216 
217  size_t getCountOfRecords( const std::string& logname = "" );
218  size_t getFirstOfOldRecord( size_t maxnum );
219 
220 #ifndef DISABLE_REST_API
221  Poco::JSON::Object::Ptr respError( Poco::Net::HTTPServerResponse& resp, Poco::Net::HTTPResponse::HTTPStatus s, const std::string& message );
222  Poco::JSON::Object::Ptr httpGetRequest( const std::string& cmd, const Poco::URI::QueryParameters& p );
223  Poco::JSON::Object::Ptr httpGetList( const Poco::URI::QueryParameters& p );
224  Poco::JSON::Object::Ptr httpGetLogs( const Poco::URI::QueryParameters& p );
225  Poco::JSON::Object::Ptr httpGetCount( const Poco::URI::QueryParameters& p );
226  void httpWebSocketPage( std::ostream& out, Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp );
227  void httpWebSocketConnectPage( std::ostream& out, Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp, const std::string& logname );
228 
229  // формирование условия where для строки XX[m|h|d|M]
230  // XX m - минут, h-часов, d-дней, M - месяцев
231  static std::string qLast( const std::string& p );
232 
233  // преобразование в дату 'YYYY-MM-DD' из строки 'YYYYMMDD' или 'YYYY/MM/DD'
234  static std::string qDate(const std::string& p , const char sep = '-');
235 
236  // экранирование кавычек (удваивание для sqlite)
237  static std::string qEscapeString( const std::string& s );
238 
239  std::shared_ptr<LogWebSocket> newWebSocket(Poco::Net::HTTPServerRequest* req, Poco::Net::HTTPServerResponse* resp, const std::string& logname );
240  void delWebSocket( std::shared_ptr<LogWebSocket>& ws );
241 #endif
242  std::string myname;
243  std::unique_ptr<SQLiteInterface> db;
244 
245  std::string tmsFormat = { "localtime" };
247  bool activate = { false };
248 
249  typedef std::queue<std::string> QueryBuffer;
250  QueryBuffer qbuf;
251  size_t qbufSize = { 1000 }; // размер буфера сообщений.
252 
253  ev::timer flushBufferTimer;
254  double tmFlushBuffer_sec = { 1.0 };
255  void flushBuffer();
256  void rotateDB();
257 
258  size_t maxdbRecords = { 200 * 1000 };
259  size_t numOverflow = { 0 }; // вычисляется из параметра "overflow factor"(float)
260 
261  ev::sig sigTERM;
262  ev::sig sigQUIT;
263  ev::sig sigINT;
264  void onTerminate( ev::sig& evsig , int revents );
265 
266  ev::async wsactivate; // активация LogWebSocket-ов
267 
268  class Log
269  {
270  public:
271  std::string name;
272  std::string ip;
273  int port = { 0 };
274  std::string cmd;
275  std::string peername;
276  std::string description;
277 
278  std::shared_ptr<DebugStream> dblog;
279  std::shared_ptr<DebugStream> logfile;
280 
281  bool isConnected() const;
282 
283  void set( ev::dynamic_loop& loop );
284  void check( ev::timer& t, int revents );
285  void event( ev::io& watcher, int revents );
286  void read( ev::io& watcher );
287  void write( ev::io& io );
288  void close();
289 
290  typedef sigc::signal<void, Log*, const std::string&> ReadSignal;
291  ReadSignal signal_on_read();
292 
293 
294  void setCheckConnectionTime( double sec );
295  void setReadBufSize( size_t sz );
296 
297  protected:
298  void ioprepare();
299  bool connect() noexcept;
300 
301  private:
302  ReadSignal sigRead;
303  ev::io io;
304  ev::timer iocheck;
305 
306  double checkConnection_sec = { 5.0 };
307 
308  std::shared_ptr<UTCPStream> tcp;
309  std::vector<char> buf; // буфер для чтения сообщений
310 
311  static const size_t reservsize = { 1000 };
312  std::string text;
313 
314  // буфер для посылаемых данных (write buffer)
315  std::queue<UTCPCore::Buffer*> wbuf;
316  };
317 
318  std::vector< std::shared_ptr<Log> > logservers;
319  std::shared_ptr<DebugStream> dblog;
320 
321 #ifndef DISABLE_REST_API
322  std::shared_ptr<Poco::Net::HTTPServer> httpserv;
323  std::string httpHost = { "" };
324  int httpPort = { 0 };
325  std::string httpCORS_allow = { "*" };
326  std::string httpReplyAddr = { "" };
327 
328  double wsHeartbeatTime_sec = { 3.0 };
329  double wsSendTime_sec = { 0.5 };
330  size_t wsMaxSend = { 200 };
331 
332  std::string fgColor = { "#c4c4c4" };
333  std::string bgColor = { "#111111" };
334  std::string bgColorTitle = { "green" };
335  std::string fgColorTitle = { "#ececec" };
336 
345  public Poco::Net::WebSocket
346  {
347  public:
348  LogWebSocket(Poco::Net::HTTPServerRequest* req,
349  Poco::Net::HTTPServerResponse* resp,
350  std::shared_ptr<Log>& log );
351 
352  virtual ~LogWebSocket();
353 
354  // конечно некрасиво что это в public
355  std::shared_ptr<DebugStream> dblog;
356 
357  bool isActive();
358  void set( ev::dynamic_loop& loop );
359 
360  void send( ev::timer& t, int revents );
361  void ping( ev::timer& t, int revents );
362 
363  void add( Log* log, const std::string& txt );
364 
365  void term();
366 
367  void waitCompletion();
368 
369  // настройка
370  void setHearbeatTime( const double& sec );
371  void setSendPeriod( const double& sec );
372  void setMaxSendCount( size_t val );
373 
374  protected:
375 
376  void write();
377 
378  ev::timer iosend;
379  double send_sec = { 0.5 };
380  size_t maxsend = { 200 };
381 
382  ev::timer ioping;
383  double ping_sec = { 3.0 };
384 
385  std::mutex finishmut;
386  std::condition_variable finish;
387 
388  std::atomic_bool cancelled = { false };
389 
390  sigc::connection con; // подписка на появление логов..
391 
392  Poco::Net::HTTPServerRequest* req;
393  Poco::Net::HTTPServerResponse* resp;
394 
395  // очередь данных на посылку..
396  std::queue<UTCPCore::Buffer*> wbuf;
397  size_t maxsize; // рассчитывается сходя из max_send (см. конструктор)
398  };
399 
401  {
402  public:
403 
404  LogWebSocketGuard( std::shared_ptr<LogWebSocket>& s, LogDB* l ):
405  ws(s), logdb(l) {}
406 
408  {
409  logdb->delWebSocket(ws);
410  }
411 
412 
413  private:
414  std::shared_ptr<LogWebSocket> ws;
415  LogDB* logdb;
416  };
417 
418  friend class LogWebSocketGuard;
419 
420  std::list<std::shared_ptr<LogWebSocket>> wsocks;
421  uniset::uniset_rwmutex wsocksMutex;
422  size_t maxwsocks = { 50 }; // максимальное количество websocket-ов
423 
424 
426  public Poco::Net::HTTPRequestHandlerFactory
427  {
428  public:
429  LogDBRequestHandlerFactory( LogDB* l ): logdb(l) {}
430  virtual ~LogDBRequestHandlerFactory() {}
431 
432  virtual Poco::Net::HTTPRequestHandler* createRequestHandler( const Poco::Net::HTTPServerRequest& req ) override;
433 
434  private:
435  LogDB* logdb;
436  };
437 #endif
438 
439  private:
440  };
441  // ----------------------------------------------------------------------------------
442 } // end of namespace uniset
443 //------------------------------------------------------------------------------------------
444 #endif
std::string tmsFormat
Definition: LogDB.h:245
Definition: LogDB.h:268
Definition: CommonEventLoop.h:14
Poco::JSON::Object::Ptr httpGetList(const Poco::URI::QueryParameters &p)
Definition: LogDB.cc:973
static void help_print()
Definition: LogDB.cc:464
void ioprepare()
Definition: LogDB.cc:638
Definition: LogDB.h:400
static std::shared_ptr< LogDB > init_logdb(int argc, const char *const *argv, const std::string &prefix="logdb-")
Definition: LogDB.cc:451
Definition: LogDB.h:178
Definition: Mutex.h:31
The EventLoopServer class Реализация общей части всех процессов использующих libev....
Definition: EventLoopServer.h:17
Definition: LogDB.h:344