UniSet 2.41.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// -------------------------------------------------------------------------
44namespace uniset
45{
46 //------------------------------------------------------------------------------------------
195 //------------------------------------------------------------------------------------------
197 class LogDB:
198 public EventLoopServer
199#ifndef DISABLE_REST_API
200 , public Poco::Net::HTTPRequestHandler
201#endif
202 {
203 public:
204 LogDB( const std::string& name, int argc, const char* const* argv, const std::string& prefix );
205 virtual ~LogDB();
206
208 static std::shared_ptr<LogDB> init_logdb( int argc, const char* const* argv, const std::string& prefix = "logdb-" );
209
211 static void help_print();
212
213 inline std::shared_ptr<DebugStream> log()
214 {
215 return dblog;
216 }
217
218 void run( bool async );
219#ifndef DISABLE_REST_API
220 virtual void handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) override;
221 void onWebSocketSession( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp );
222#endif
223
224 protected:
225
226 class Log;
227 class LogWebSocket;
228
229 virtual void evfinish() override;
230 virtual void evprepare() override;
231 void onCheckBuffer( ev::timer& t, int revents );
232 void onActivate( ev::async& watcher, int revents ) ;
233 void addLog( Log* log, const std::string& txt );
234 void log2File( Log* log, const std::string& txt );
235
236 size_t getCountOfRecords( const std::string& logname = "" );
237 size_t getFirstOfOldRecord( size_t maxnum );
238
239 // экранирование кавычек (удваивание для sqlite)
240 static std::string qEscapeString( const std::string& s );
241
242#ifndef DISABLE_REST_API
243 Poco::JSON::Object::Ptr respError( Poco::Net::HTTPServerResponse& resp, Poco::Net::HTTPResponse::HTTPStatus s, const std::string& message );
244 Poco::JSON::Object::Ptr httpGetRequest( Poco::Net::HTTPServerResponse& resp, const std::string& cmd, const Poco::URI::QueryParameters& p );
245 Poco::JSON::Object::Ptr httpGetList( Poco::Net::HTTPServerResponse& resp, const Poco::URI::QueryParameters& p );
246 Poco::JSON::Object::Ptr httpGetLogs( Poco::Net::HTTPServerResponse& resp, const Poco::URI::QueryParameters& p );
247 Poco::JSON::Object::Ptr httpGetCount( Poco::Net::HTTPServerResponse& resp, const Poco::URI::QueryParameters& p );
248 Poco::JSON::Object::Ptr httpDownload( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp, const Poco::URI::QueryParameters& p );
249 Poco::JSON::Object::Ptr httpLogControl(std::ostream& out, Poco::Net::HTTPServerRequest& req,
250 Poco::Net::HTTPServerResponse& resp, const std::string& logname, const Poco::URI::QueryParameters& params );
251
252 void httpWebSocketPage( std::ostream& out, Poco::Net::HTTPServerRequest& req,
253 Poco::Net::HTTPServerResponse& resp, const Poco::URI::QueryParameters& p );
254 void httpWebSocketConnectPage( Poco::Net::HTTPServerRequest& req,
255 Poco::Net::HTTPServerResponse& resp, const std::string& logname, const Poco::URI::QueryParameters& p );
256
257 bool supportsGzip( Poco::Net::HTTPServerRequest& request );
258
259 // формирование условия where для строки XX[m|h|d|M]
260 // XX m - минут, h-часов, d-дней, M - месяцев
261 static std::string qLast( const std::string& p );
262
263 // преобразование в дату 'YYYY-MM-DD' из строки 'YYYYMMDD' или 'YYYY/MM/DD'
264 static std::string qDate(const std::string& p, const char sep = '-');
265
266 std::shared_ptr<LogWebSocket> newWebSocket(Poco::Net::HTTPServerRequest* req, Poco::Net::HTTPServerResponse* resp,
267 const std::string& logname, const Poco::URI::QueryParameters& p );
268 void delWebSocket( std::shared_ptr<LogWebSocket>& ws );
269
270#endif
271 std::string myname;
272 std::unique_ptr<SQLiteInterface> db;
273 std::string dbfile;
274
275 std::string tmsFormat = { "localtime" };
276
277 bool activate = { false };
278
279 typedef std::queue<std::string> QueryBuffer;
280 QueryBuffer qbuf;
281 size_t qbufSize = { 1000 }; // размер буфера сообщений.
282
283 ev::timer flushBufferTimer;
284 double tmFlushBuffer_sec = { 1.0 };
285 void flushBuffer();
286 void rotateDB();
287
288 size_t maxdbRecords = { 200 * 1000 };
289 size_t numOverflow = { 0 }; // вычисляется из параметра "overflow factor"(float)
290
291 ev::sig sigTERM;
292 ev::sig sigQUIT;
293 ev::sig sigINT;
294 void onTerminate( ev::sig& evsig, int revents );
295
296 ev::async wsactivate; // активация LogWebSocket-ов
297
298 class Log
299 {
300 public:
301 std::string name;
302 std::string ip;
303 int port = { 0 };
304 std::string cmd;
305 std::string usercmd;
306 std::string lastcmd;
307 std::string peername;
308 std::string description;
309
310 std::shared_ptr<DebugStream> dblog;
311 std::shared_ptr<DebugStream> logfile;
312
313 bool isConnected() const;
314
315 void set( ev::dynamic_loop& loop );
316 void check( ev::timer& t, int revents );
317 void event( ev::io& watcher, int revents );
318 void read( ev::io& watcher );
319 void oncommand( ev::async& watcher, int revents );
320 void write( ev::io& io );
321 void close();
322
323 typedef sigc::signal<void, Log*, const std::string&> ReadSignal;
324 ReadSignal signal_on_read();
325
326 void setCheckConnectionTime( double sec );
327 void setReadBufSize( size_t sz );
328 void setCommand( const std::string& cmd );
329
330 protected:
331 void ioprepare();
332 bool connect() noexcept;
333
334 private:
335 ReadSignal sigRead;
336 ev::io io;
337 ev::timer iocheck;
338 ev::async iocmd;
339
340 double checkConnection_sec = { 5.0 };
341
342 std::shared_ptr<UTCPStream> tcp;
343 std::vector<char> buf; // буфер для чтения сообщений
344
345 static const size_t reservsize = { 1000 };
346 std::string text;
347
348 // буфер для посылаемых данных (write buffer)
349 std::queue<UTCPCore::Buffer*> wbuf;
350
351 // очередь команд для посылки
352 std::vector<UTCPCore::Buffer*> cmdbuf;
354 };
355
356 std::vector< std::shared_ptr<Log> > logservers;
357 std::shared_ptr<DebugStream> dblog;
358
359
360#ifndef DISABLE_REST_API
361 std::shared_ptr<Poco::Net::HTTPServer> httpserv;
362 std::string httpHost = { "" };
363 int httpPort = { 0 };
364 std::string httpCORS_allow = { "*" };
365 std::string httpReplyAddr = { "" };
366 std::string httpJsonContentType = {"text/json; charset=UTF-8" };
367 std::string httpHtmlContentType = {"text/html; charset=UTF-8" };
368 std::string utf8Code = "UTF-8";
369
370 double wsHeartbeatTime_sec = { 3.0 };
371 double wsSendTime_sec = { 0.5 };
372 size_t wsMaxSend = { 200 };
373 bool httpEnabledLogControl = { false };
374 bool httpEnabledDownload = { false };
375
376 std::string wsPageTemplate = "";
377
385 class LogWebSocket:
386 public Poco::Net::WebSocket
387 {
388 public:
389 LogWebSocket(Poco::Net::HTTPServerRequest* req,
390 Poco::Net::HTTPServerResponse* resp,
391 std::shared_ptr<Log>& log );
392
393 virtual ~LogWebSocket();
394
395 // конечно некрасиво что это в public
396 std::shared_ptr<DebugStream> dblog;
397
398 bool isActive();
399 void set( ev::dynamic_loop& loop );
400
401 void send( ev::timer& t, int revents );
402 void ping( ev::timer& t, int revents );
403 void add( Log* log, const std::string& txt );
404
405 void term();
406 void waitCompletion();
407
408 // настройка
409 void setHearbeatTime( const double& sec );
410 void setSendPeriod( const double& sec );
411 void setMaxSendCount( size_t val );
412
413 protected:
414
415 void write();
416
417 ev::timer iosend;
418 double send_sec = { 0.5 };
419 size_t maxsend = { 200 };
420
421 ev::timer ioping;
422 double ping_sec = { 3.0 };
423
424 std::mutex finishmut;
425 std::condition_variable finish;
426
427 std::atomic_bool cancelled = { false };
428
429 sigc::connection con; // подписка на появление логов..
430
431 Poco::Net::HTTPServerRequest* req;
432 Poco::Net::HTTPServerResponse* resp;
433
434 // очередь данных на посылку..
435 std::queue<UTCPCore::Buffer*> wbuf;
436 size_t maxsize; // рассчитывается исходя из max_send (см. конструктор)
437
438 std::shared_ptr<Log> log;
439 };
440
441 class LogWebSocketGuard
442 {
443 public:
444
445 LogWebSocketGuard( std::shared_ptr<LogWebSocket>& s, LogDB* l ):
446 ws(s), logdb(l) {}
447
448 ~LogWebSocketGuard()
449 {
450 ws->term();
451 logdb->delWebSocket(ws);
452 }
453
454
455 private:
456 std::shared_ptr<LogWebSocket> ws;
457 LogDB* logdb;
458 };
459
460 friend class LogWebSocketGuard;
461
462 std::list<std::shared_ptr<LogWebSocket>> wsocks;
463 uniset::uniset_rwmutex wsocksMutex;
464 size_t maxwsocks = { 50 }; // максимальное количество websocket-ов
465
466 class LogDBRequestHandlerFactory:
467 public Poco::Net::HTTPRequestHandlerFactory
468 {
469 public:
470 LogDBRequestHandlerFactory( LogDB* l ): logdb(l) {}
471 virtual ~LogDBRequestHandlerFactory() {}
472
473 virtual Poco::Net::HTTPRequestHandler* createRequestHandler( const Poco::Net::HTTPServerRequest& req ) override;
474
475 private:
476 LogDB* logdb;
477 };
478#endif
479
480 private:
481 };
482 // ----------------------------------------------------------------------------------
483} // end of namespace uniset
484//------------------------------------------------------------------------------------------
485#endif
Определения LogDB.h:299
void setCommand(const std::string &cmd)
Определения LogDB.cc:771
Определения LogDB.h:442
Определения LogDB.h:387
std::string tmsFormat
Определения LogDB.h:275
Poco::JSON::Object::Ptr httpGetList(Poco::Net::HTTPServerResponse &resp, const Poco::URI::QueryParameters &p)
Определения LogDB.cc:1151
static std::shared_ptr< LogDB > init_logdb(int argc, const char *const *argv, const std::string &prefix="logdb-")
Определения LogDB.cc:526
static void help_print()
Определения LogDB.cc:539
Определения Mutex.h:32
Определения Calibration.h:27