UniSet  2.24.2
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  //------------------------------------------------------------------------------------------
175  //------------------------------------------------------------------------------------------
177  class LogDB:
178  public EventLoopServer
179 #ifndef DISABLE_REST_API
180  , public Poco::Net::HTTPRequestHandler
181 #endif
182  {
183  public:
184  LogDB( const std::string& name, int argc, const char* const* argv, const std::string& prefix );
185  virtual ~LogDB();
186 
188  static std::shared_ptr<LogDB> init_logdb( int argc, const char* const* argv, const std::string& prefix = "logdb-" );
189 
191  static void help_print();
192 
193  inline std::shared_ptr<DebugStream> log()
194  {
195  return dblog;
196  }
197 
198  void run( bool async );
199 #ifndef DISABLE_REST_API
200  virtual void handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) override;
201  void onWebSocketSession( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp );
202 #endif
203 
204  protected:
205 
206  class Log;
207  class LogWebSocket;
208 
209  virtual void evfinish() override;
210  virtual void evprepare() override;
211  void onCheckBuffer( ev::timer& t, int revents );
212  void onActivate( ev::async& watcher, int revents ) ;
213  void addLog( Log* log, const std::string& txt );
214  void log2File( Log* log, const std::string& txt );
215 
216  size_t getCountOfRecords( const std::string& logname = "" );
217  size_t getFirstOfOldRecord( size_t maxnum );
218 
219  // экранирование кавычек (удваивание для sqlite)
220  static std::string qEscapeString( const std::string& s );
221 
222 #ifndef DISABLE_REST_API
223  Poco::JSON::Object::Ptr respError( Poco::Net::HTTPServerResponse& resp, Poco::Net::HTTPResponse::HTTPStatus s, const std::string& message );
224  Poco::JSON::Object::Ptr httpGetRequest( const std::string& cmd, const Poco::URI::QueryParameters& p );
225  Poco::JSON::Object::Ptr httpGetList( const Poco::URI::QueryParameters& p );
226  Poco::JSON::Object::Ptr httpGetLogs( const Poco::URI::QueryParameters& p );
227  Poco::JSON::Object::Ptr httpGetCount( const Poco::URI::QueryParameters& p );
228  void httpWebSocketPage( std::ostream& out, Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp );
229  void httpWebSocketConnectPage( std::ostream& out, Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp, const std::string& logname );
230 
231  // формирование условия where для строки XX[m|h|d|M]
232  // XX m - минут, h-часов, d-дней, M - месяцев
233  static std::string qLast( const std::string& p );
234 
235  // преобразование в дату 'YYYY-MM-DD' из строки 'YYYYMMDD' или 'YYYY/MM/DD'
236  static std::string qDate(const std::string& p, const char sep = '-');
237 
238  std::shared_ptr<LogWebSocket> newWebSocket(Poco::Net::HTTPServerRequest* req, Poco::Net::HTTPServerResponse* resp, const std::string& logname );
239  void delWebSocket( std::shared_ptr<LogWebSocket>& ws );
240 #endif
241  std::string myname;
242  std::unique_ptr<SQLiteInterface> db;
243 
244  std::string tmsFormat = { "localtime" };
246  bool activate = { false };
247 
248  typedef std::queue<std::string> QueryBuffer;
249  QueryBuffer qbuf;
250  size_t qbufSize = { 1000 }; // размер буфера сообщений.
251 
252  ev::timer flushBufferTimer;
253  double tmFlushBuffer_sec = { 1.0 };
254  void flushBuffer();
255  void rotateDB();
256 
257  size_t maxdbRecords = { 200 * 1000 };
258  size_t numOverflow = { 0 }; // вычисляется из параметра "overflow factor"(float)
259 
260  ev::sig sigTERM;
261  ev::sig sigQUIT;
262  ev::sig sigINT;
263  void onTerminate( ev::sig& evsig, int revents );
264 
265  ev::async wsactivate; // активация LogWebSocket-ов
266 
267  class Log
268  {
269  public:
270  std::string name;
271  std::string ip;
272  int port = { 0 };
273  std::string cmd;
274  std::string peername;
275  std::string description;
276 
277  std::shared_ptr<DebugStream> dblog;
278  std::shared_ptr<DebugStream> logfile;
279 
280  bool isConnected() const;
281 
282  void set( ev::dynamic_loop& loop );
283  void check( ev::timer& t, int revents );
284  void event( ev::io& watcher, int revents );
285  void read( ev::io& watcher );
286  void write( ev::io& io );
287  void close();
288 
289  typedef sigc::signal<void, Log*, const std::string&> ReadSignal;
290  ReadSignal signal_on_read();
291 
292 
293  void setCheckConnectionTime( double sec );
294  void setReadBufSize( size_t sz );
295 
296  protected:
297  void ioprepare();
298  bool connect() noexcept;
299 
300  private:
301  ReadSignal sigRead;
302  ev::io io;
303  ev::timer iocheck;
304 
305  double checkConnection_sec = { 5.0 };
306 
307  std::shared_ptr<UTCPStream> tcp;
308  std::vector<char> buf; // буфер для чтения сообщений
309 
310  static const size_t reservsize = { 1000 };
311  std::string text;
312 
313  // буфер для посылаемых данных (write buffer)
314  std::queue<UTCPCore::Buffer*> wbuf;
315  };
316 
317  std::vector< std::shared_ptr<Log> > logservers;
318  std::shared_ptr<DebugStream> dblog;
319 
320 #ifndef DISABLE_REST_API
321  std::shared_ptr<Poco::Net::HTTPServer> httpserv;
322  std::string httpHost = { "" };
323  int httpPort = { 0 };
324  std::string httpCORS_allow = { "*" };
325  std::string httpReplyAddr = { "" };
326 
327  double wsHeartbeatTime_sec = { 3.0 };
328  double wsSendTime_sec = { 0.5 };
329  size_t wsMaxSend = { 200 };
330 
331  std::string fgColor = { "#c4c4c4" };
332  std::string bgColor = { "#111111" };
333  std::string bgColorTitle = { "green" };
334  std::string fgColorTitle = { "#ececec" };
335 
344  public Poco::Net::WebSocket
345  {
346  public:
347  LogWebSocket(Poco::Net::HTTPServerRequest* req,
348  Poco::Net::HTTPServerResponse* resp,
349  std::shared_ptr<Log>& log );
350 
351  virtual ~LogWebSocket();
352 
353  // конечно некрасиво что это в public
354  std::shared_ptr<DebugStream> dblog;
355 
356  bool isActive();
357  void set( ev::dynamic_loop& loop );
358 
359  void send( ev::timer& t, int revents );
360  void ping( ev::timer& t, int revents );
361 
362  void add( Log* log, const std::string& txt );
363 
364  void term();
365 
366  void waitCompletion();
367 
368  // настройка
369  void setHearbeatTime( const double& sec );
370  void setSendPeriod( const double& sec );
371  void setMaxSendCount( size_t val );
372 
373  protected:
374 
375  void write();
376 
377  ev::timer iosend;
378  double send_sec = { 0.5 };
379  size_t maxsend = { 200 };
380 
381  ev::timer ioping;
382  double ping_sec = { 3.0 };
383 
384  std::mutex finishmut;
385  std::condition_variable finish;
386 
387  std::atomic_bool cancelled = { false };
388 
389  sigc::connection con; // подписка на появление логов..
390 
391  Poco::Net::HTTPServerRequest* req;
392  Poco::Net::HTTPServerResponse* resp;
393 
394  // очередь данных на посылку..
395  std::queue<UTCPCore::Buffer*> wbuf;
396  size_t maxsize; // рассчитывается сходя из max_send (см. конструктор)
397  };
398 
400  {
401  public:
402 
403  LogWebSocketGuard( std::shared_ptr<LogWebSocket>& s, LogDB* l ):
404  ws(s), logdb(l) {}
405 
407  {
408  logdb->delWebSocket(ws);
409  }
410 
411 
412  private:
413  std::shared_ptr<LogWebSocket> ws;
414  LogDB* logdb;
415  };
416 
417  friend class LogWebSocketGuard;
418 
419  std::list<std::shared_ptr<LogWebSocket>> wsocks;
420  uniset::uniset_rwmutex wsocksMutex;
421  size_t maxwsocks = { 50 }; // максимальное количество websocket-ов
422 
423 
425  public Poco::Net::HTTPRequestHandlerFactory
426  {
427  public:
428  LogDBRequestHandlerFactory( LogDB* l ): logdb(l) {}
429  virtual ~LogDBRequestHandlerFactory() {}
430 
431  virtual Poco::Net::HTTPRequestHandler* createRequestHandler( const Poco::Net::HTTPServerRequest& req ) override;
432 
433  private:
434  LogDB* logdb;
435  };
436 #endif
437 
438  private:
439  };
440  // ----------------------------------------------------------------------------------
441 } // end of namespace uniset
442 //------------------------------------------------------------------------------------------
443 #endif
The EventLoopServer class Реализация общей части всех процессов использующих libev....
Definition: EventLoopServer.h:18
Definition: LogDB.h:268
void ioprepare()
Definition: LogDB.cc:655
Definition: LogDB.h:400
Definition: LogDB.h:345
Definition: LogDB.h:182
std::string tmsFormat
Definition: LogDB.h:244
Poco::JSON::Object::Ptr httpGetList(const Poco::URI::QueryParameters &p)
Definition: LogDB.cc:1005
static std::shared_ptr< LogDB > init_logdb(int argc, const char *const *argv, const std::string &prefix="logdb-")
Definition: LogDB.cc:461
static void help_print()
Definition: LogDB.cc:474
Definition: Mutex.h:32
Definition: CommonEventLoop.h:15