OmniEvents
omniEventsLog.cc
Go to the documentation of this file.
1// -*- Mode: C++; -*-
2// Package : omniEvents
3// omniEventsLog.cc Created : 1/10/99
4// Author : Paul Nader (pwn)
5//
6// Copyright (C) 1998 Paul Nader, 2003-2005 Alex Tingle.
7//
8// This file is part of the omniEvents application.
9//
10// omniEvents is free software; you can redistribute it and/or
11// modify it under the terms of the GNU Lesser General Public
12// License as published by the Free Software Foundation; either
13// version 2.1 of the License, or (at your option) any later version.
14//
15// omniEvents is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23//
24// Description:
25//
26
27/*
28 $Log: omniEventsLog.cc,v $
29 Revision 1.20.2.3 2005/05/10 14:28:11 alextingle
30 Updated copyrights to 2005.
31
32 Revision 1.20.2.2 2005/05/04 23:06:02 alextingle
33 Fixed reference leak. Releases ref to factory servant.
34
35 Revision 1.20.2.1 2004/11/16 21:46:11 alextingle
36 Made several methods virtual to allow users of libomniEvents to override
37 the default persistency behaviour. (Dirk O. Siebnich)
38
39 Revision 1.20 2004/09/25 23:12:28 alextingle
40 New method: Orb::reportObjectFailure() - flags unexpected failures at a higher
41 priority than normal non-fatal exceptions.
42
43 New macro: NP_MINORSTRING() - a safe interface to
44 CORBA::SystemException::NP_minorString() that returns "??" when there is no
45 mapping for the exception's minor code.
46
47 Revision 1.19 2004/07/26 16:27:08 alextingle
48 Support for NT service on windows: main() moved into daemon.cc.
49 New (laxer) start up syntax. Port is now set with -p (not -s). There is no
50 special cold start mode.
51 More flexible naming service name option -N. (No more -K option).
52
53 Revision 1.18 2004/07/16 08:45:46 alextingle
54 New macro: IF_OMNIORB4(). Fixes warnings on AIX xlC_r.
55
56 Revision 1.17 2004/07/15 16:18:45 alextingle
57 Fixed casting warnings on Tru64.
58
59 Revision 1.16 2004/07/06 12:46:34 alextingle
60 Moved default macros into defaults.h
61
62 Revision 1.15 2004/07/06 10:59:39 alextingle
63 Tightened privileges on created files.
64
65 Revision 1.14 2004/07/05 13:52:37 alextingle
66 Improved iostream portability (again).
67
68 Revision 1.13 2004/07/02 15:20:39 alextingle
69 Added daemonization, syslog & pidfile support on Unix.
70 Corrected trace levels for consistency with omniORB.
71
72 Revision 1.12 2004/05/14 14:44:48 alextingle
73 Explicitly cast 'flags' to type ios::openmode for platforms where this type is an enum.
74
75 Revision 1.11 2004/04/20 20:23:03 alextingle
76 Cross-platform friendly use of std:ifstream.
77
78 Revision 1.10 2004/04/20 17:16:16 alextingle
79 Corrected openOfstream() arg name/comments.
80
81 Revision 1.9 2004/03/30 17:31:00 alextingle
82 Added exception handlers to thread methods.
83
84 Revision 1.8 2004/03/28 01:03:58 alextingle
85 Refactored class omniEventsLog to allow for more EventChannelFactory parameters.\nNew omniEvents params: -v, -a (alternate endPoint).
86
87 Revision 1.7 2004/03/23 13:29:34 alextingle
88 Fixed bizarre compilation errors on Sun's CC.
89
90 Revision 1.6 2004/01/11 16:57:26 alextingle
91 New persistancy log file format, implemented by PersistNode.h/cc. The new format enables new nodes to be added and old ones erased by appending a single line to the file, rather than by re-persisting the whole application. This is much more efficient when lots of proxies are being created all at once. It's also a much simpler solution, with far fewer lines of code.
92
93 Revision 1.5 2003/12/21 16:17:19 alextingle
94 Added OmniEvents namespace. Now uses POA implementations.
95
96 Revision 1.4 2003/11/14 14:05:21 alextingle
97 New output() members functions. Eliminates the need for friend ostream
98 functions that are problematic on earlier versions of Microsoft
99 VisualC++. Improved helpfulness of usage and error messages.
100
101 Revision 1.3 2003/11/03 22:41:00 alextingle
102 Oops! Removed excess log comments.
103
104 Revision 1.2 2003/11/03 22:38:39 alextingle
105 Removed many platform specific switches, alas many remain. Now uses
106 autoconf,config.h wherever possible.
107 Removed local definition of strdup() - omniEvents.cc manages to get
108 along without it, so it can't be needed here.
109 Moved convoluted code to obtain hostname into its own header file:
110 gethostname.h
111 Moved code that constructs logfile names into its own private method,
112 omniEventsLog::initializeFileNames()
113 Added explicit initialisation for all `class omniEventsLog' members.
114 Moved code that opens file stream into its own private method,
115 omniEventsLog::openOfstream()
116
117 Revision 1.1.1.1 2002/09/25 19:00:35 shamus13
118 Import of OmniEvents source tree from release 2.1.1
119
120 Revision 1.8 2000/09/26 09:20:26 naderp
121 STL Default parameters rework.
122 Configurable checkpoint period.
123
124 Revision 1.7 2000/09/04 05:05:22 naderp
125 Fixed problem with triggering multiple checkpoints.
126
127 Revision 1.6 2000/08/30 04:38:24 naderp
128 Fix to prevent recorder thread from terminating.
129
130 Revision 1.5 2000/08/30 00:57:29 naderp
131 Fixed broken persist method exiting after first checkpoint.
132
133 Revision 1.4 2000/03/06 13:19:58 naderp
134 Moved port from global to factory persistency data.
135
136 Revision 1.3 2000/03/06 04:15:09 naderp
137 Removed internal dependency between factory and Naming Service.
138
139 Revision 1.2 2000/03/02 04:20:09 naderp
140 Initialising factory refernce in init().
141
142 Revision 1.1 2000/03/02 02:00:25 naderp
143 Re-open active logfile during re-start.
144
145 Revision 1.0 1999/11/01 17:04:08 naderp
146 Initial revision
147
148*/
149
150#include "omniEventsLog.h"
151
152#ifdef HAVE_CONFIG_H
153# include "config.h"
154#endif
155
156#include <stdio.h>
157
158#ifdef HAVE_STDLIB_H
159# include <stdlib.h>
160#endif
161
162#ifdef HAVE_SYS_TYPES_H
163# include <sys/types.h>
164#endif
165
166#ifdef HAVE_SYS_STAT_H
167# include <sys/stat.h>
168#endif
169
170#ifdef HAVE_FCNTL_H
171# include <fcntl.h>
172#endif
173
174#if defined(__VMS) && __CRTL_VER < 70000000
175# include <omniVMS/unlink.hxx>
176#endif
177
178#ifdef __WIN32__
179# include <io.h>
180# include <winbase.h>
181# define stat(x,y) _stat(x,y)
182# define unlink(x) _unlink(x)
183# define STRUCT_STAT struct _stat
184#else
185# define STRUCT_STAT struct stat
186#endif // __WIN32__
187
188#ifdef HAVE_UNISTD_H
189# include <unistd.h>
190#endif
191
192#ifdef HAVE_LIBC_H
193# include <libc.h>
194#endif
195
196#ifdef HAVE_SYS_PARAM_H
197# include <sys/param.h>
198#endif
199
200#include <errno.h>
201#include <time.h>
202#include <assert.h>
203#include "gethostname.h"
204
205#include "EventChannelFactory.h"
206#include "Orb.h"
207#include "defaults.h"
208
209//
210// Set flags for use in calls to omniEventsLog::openOfstream()
211//
212
213#if defined(HAVE_FSTREAM_OPEN)
214# define FLAG_TRUNCATE ios::trunc
215# define FLAG_APPEND ios::app
216# define FLAG_SYNC 0
217#elif defined(HAVE_FSTREAM_ATTACH)
218# if defined(__WIN32__)
219# define FLAG_SYNC 0
220# elif defined(O_SYNC)
221# define FLAG_SYNC O_SYNC
222# else
223# define FLAG_SYNC O_FSYNC // FreeBSD 3.2 does not have O_SYNC???
224# endif
225# define FLAG_TRUNCATE O_CREAT|O_TRUNC
226# define FLAG_APPEND O_APPEND
227#else
228# error "Can't open a file without ofstream::open() or ofstream::attach()"
229#endif
230
231//
232// Append ';' to VMS filenames to force the latest version.
233//
234
235#ifdef __VMS
236# define VMS_SEMICOLON ";"
237#else
238# define VMS_SEMICOLON
239#endif
240
241extern int yyparse();
242extern int yydebug;
243extern FILE *yyin;
244
245namespace OmniEvents {
246
253{
254 char str[29];
255public:
257 {
258 str[0] = '[';
259 str[1] = str[28] = '\0';
260 }
261 const char* t(void)
262 {
263 time_t t =time(NULL);
264 char* p =ctime(&t);
265 if(strncmp(p, &str[1], 24) == 0)
266 return "";
267 strncpy(&str[1], p, 24);
268 str[25] = ']';
269 str[26] = ' ';
270 str[27] = ' ';
271 return str;
272 }
273};
274
276
277//------------------------------------------------------------------------
278// omniEvents Log Implementation
279//------------------------------------------------------------------------
280
282
283omniEventsLog::omniEventsLog(const char* logdir) :
284 _logstream(),
285 _activeFilename(NULL),
286 _backupFilename(NULL),
287 _checkpointFilename(NULL),
288 _workerThread(NULL),
289 _factory(NULL),
290 _checkpointNeeded(true),
291 _lock()
292{
294 initializeFileNames(logdir);
295}
296
297
299{
300 DB(20, "omniEventsLog::~omniEventsLog()");
301/*
302 if(NULL != _workerThread)
303 {
304 _workerThread->join(0);
305 _workerThread = NULL;
306 }
307*/
308 if(NULL != _factory)
309 {
310 _factory->_remove_ref();
311 _factory = NULL;
312 }
314}
315
316
317bool omniEventsLog::fileExists(const char* filename) const
318{
319 STRUCT_STAT sb;
320 return(::stat(filename,&sb) == 0);
321}
322
323
324PersistNode* omniEventsLog::bootstrap(int port, const char* endPointNoListen)
325{
326 //
327 // Construct a new initialState, from the arguments.
328 PersistNode* initialState=new PersistNode();
329 PersistNode* ecf =initialState->addnode("ecf");
330 ecf->addattr("port",port);
331 if(endPointNoListen && endPointNoListen[0])
332 ecf->addattr(string("endPointNoListen=")+endPointNoListen);
333 return initialState;
334} // bootstrap()
335
336
338{
339 //
340 // Restart - parse log file.
341 ifstream persiststream(_activeFilename);
342 if(!persiststream)
343 {
344 cerr << "Error: cannot read database file '"
345 << _activeFilename << "'." << endl;
347 {
348 cerr <<
349 " Backup file '" << _backupFilename << "' exists.\n"
350 " Either rename it to '" << _activeFilename << "' to\n"
351 " to recover the server's state, or delete it to create a new\n"
352 " database file." << endl;
353 }
354 exit(1);
355 }
356 PersistNode* initialState=new PersistNode(persiststream);
357 persiststream.close();
358
359 //
360 // Check that the file contains a valid EventChannelFactory.
361 const char* errorStr =NULL;
362 PersistNode* ecf=initialState->child("ecf");
363 if(!ecf)
364 errorStr="Can't find EventChannelFactory.";
365 else if(ecf->attrLong("port",-1)<=0)
366 errorStr="EventChannelFactory is not assigned a valid port.";
367
368 if(errorStr)
369 {
370 cerr<<"Error parsing database '"<<_activeFilename<<"'.\n"
371 <<errorStr<<" Try deleting the file (and any backup)."<<endl;
372 exit(1);
373 }
374
375 return initialState;
376} // parse()
377
378
380{
381 assert(initialState!=NULL);
382
383 //
384 // Open the logstream (The EventChannelFactory might want to write to it).
385 try
386 {
388 }
389 catch (IOError& ex)
390 {
391 cerr << "Error: cannot "
392 << (fileExists(_activeFilename)?"write to":"create new")
393 << " database file '" << _activeFilename
394 << "': " << strerror(errno) << endl;
395 cerr << "\nUse option '-l' or set the environment variable "
397 << "\nto specify the directory where the files are kept.\n"
398 << endl;
399 _logstream.close();
400 unlink(_activeFilename);
401 exit(1);
402 }
403
404 //
405 // Recreate the persisted factory.
406 PersistNode* ecf=initialState->child("ecf");
407 assert(ecf!=NULL);
409 CORBA::Object_var obj;
410 assert(!CORBA::is_nil(obj = _factory->_this()));
411} // incarnateFactory
412
413
415{
416 assert(_factory!=NULL);
417
419 this,
420 &omniEventsLog::checkpoint, // member function pointer
421 omni_thread::PRIORITY_NORMAL
422 );
423}
424
425
426void omniEventsLog::output(ostream& os)
427{
428 _factory->output(os);
429 os<<endl;
430}
431
432
434{
435 int idle_time_btw_chkpt;
436 static int firstCheckPoint = 1;
437 char *itbc = getenv("OMNIEVENTS_ITBC");
438 if (itbc == NULL || sscanf(itbc,"%d",&idle_time_btw_chkpt) != 1)
439 {
440 idle_time_btw_chkpt=OMNIEVENTS_LOG_CHECKPOINT_PERIOD;
441 }
442
443 omni_mutex mutex;
444 omni_condition cond(&mutex);
445
446 mutex.lock();
447 while (1) {
448
449 // Take an initial checkpoint the first time. All subsequent
450 // checkpoints are conditionally tested on whether they are
451 // needed or not.
452
453 if (! firstCheckPoint)
454 {
455 unsigned long s, n;
456 omni_thread::get_time(&s, &n, idle_time_btw_chkpt);
457 cond.timedwait(s,n);
458
459 _lock.lock();
461 {
462 _lock.unlock();
463 continue;
464 }
465 }
466 else
467 {
468 _lock.lock();
469 firstCheckPoint = 0;
470 }
471
472 DB(1,ts.t() << "Checkpointing Phase 1: Prepare.")
473
474 ofstream ckpf;
475 int fd = -1;
476
477 try
478 {
479 try
480 {
481 openOfstream(ckpf,_checkpointFilename,FLAG_TRUNCATE|FLAG_SYNC,&fd);
482 }
483 catch(IOError& ex)
484 {
485 DB(0,ts.t() << "Error: cannot open checkpoint file '"
486 << _checkpointFilename << "' for writing.")
487 throw;
488 }
489
490 output(ckpf);
491
492 ckpf.close();
493 if(!ckpf)
494 throw IOError();
495
496 // a bug in sparcworks C++ means that the fd doesn't get closed.
497#if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500
498 if(close(fd) < 0)
499 throw IOError();
500#endif
501
502 }
503 catch(IOError& ex)
504 {
505 DB(0,ts.t()<<"I/O error writing checkpoint file: "<<strerror(errno)
506 <<"\nAbandoning checkpoint")
507 ckpf.close();
508 // a bug in sparcworks C++ means that the fd doesn't get closed.
509#if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500
510 close(fd);
511#endif
512 unlink(_checkpointFilename);
513 _lock.unlock();
514 continue;
515 }
516
517 //
518 // Now commit the checkpoint to become the active log.
519 //
520
521 DB(1,ts.t() << "Checkpointing Phase 2: Commit.")
522
523 // a bug in sparcworks C++ means that the fd doesn't get closed.
524#if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500
525 close(_logstream.rdbuf()->fd());
526#endif
527
528 _logstream.close();
529
530 unlink(_backupFilename);
531
532#if defined(__WIN32__)
533 if(rename(_activeFilename, _backupFilename) != 0)
534#elif defined(__VMS)
535 if(rename(_activeFilename, _backupFilename) < 0)
536#else
537 if(link(_activeFilename,_backupFilename) < 0)
538#endif
539 {
540 // Failure here leaves old active and checkpoint file.
541 DB(0,ts.t() << "Error: failed to link backup file '"
542 << _backupFilename << "' to old log file '"
543 << _activeFilename << "'.")
544 exit(1);
545 }
546
547#if !defined( __VMS) && !defined(__WIN32__)
548 if(unlink(_activeFilename) < 0)
549 {
550 // Failure here leaves active and backup pointing to the same (old) file.
551 DB(0,ts.t() << "Error: failed to unlink old log file '"
552 << _activeFilename << "': " << strerror(errno))
553 exit(1);
554 }
555#endif
556
557#if defined(__WIN32__)
558 if(rename(_checkpointFilename,_activeFilename) != 0)
559#elif defined(__VMS)
561#else
563#endif
564 {
565 // Failure here leaves no active but backup points to the old file.
566 DB(0,ts.t() << "Error: failed to link log file '" << _activeFilename
567 << "' to checkpoint file '" << _checkpointFilename << "'.")
568 exit(1);
569 }
570
571#if !defined( __VMS) && !defined(__WIN32__)
572 if (unlink(_checkpointFilename) < 0)
573 {
574 // Failure here leaves active and checkpoint pointing to the same file.
575 DB(0,ts.t() << "Error: failed to unlink checkpoint file '"
576 << _checkpointFilename << "'.")
577 exit(1);
578 }
579#endif
580
581 try
582 {
583 openOfstream(_logstream,_activeFilename,FLAG_APPEND|FLAG_SYNC,&fd);
584 }
585 catch (IOError& ex)
586 {
587 DB(0,ts.t() << "Error: cannot open new log file '" << _activeFilename
588 << "' for writing.")
589 exit(1);
590 }
591
592 DB(1,ts.t() << "Checkpointing completed.")
593
594 _checkpointNeeded=false;
595 _lock.unlock();
596 }
597 mutex.unlock();
598} // checkpoint
599
600
612{
613 if(!logdir)
614 logdir=getenv(OMNIEVENTS_LOGDIR_ENV_VAR);
615 if(!logdir)
617
618 const char* logname ="omnievents-";
619 char hostname[MAXHOSTNAMELEN];
620 if (0!=gethostname(hostname,MAXHOSTNAMELEN))
621 {
622 cerr << "Error: cannot get the name of this host." << endl;
623 exit(1);
624 }
625 const char* sep ="";
626
627#if defined(__WIN32__)
628 sep="\\";
629#elif defined(__VMS)
630 char last( logdir[strlen(logdir)-1] );
631 if (last != ':' && last != ']')
632 {
633 cerr << "Error: " << OMNIEVENTS_LOGDIR_ENV_VAR << " (" << logdir
634 << ") is not a directory name." << endl;
635 exit(1);
636 }
637#else // Unix
638 if (logdir[0] != '/')
639 {
640 cerr << "Error: " << OMNIEVENTS_LOGDIR_ENV_VAR << " (" << logdir
641 << ") is not an absolute path name." << endl;
642 exit(1);
643 }
644 if (logdir[strlen(logdir)-1] != '/')
645 sep="/";
646#endif
647
648 // VMS_SEMICOLON specifies latest version of the file on VMS
649 // (essentially, we're saying we don't want to use VMS file versioning).
650
651 setFilename(_activeFilename,logdir,sep,logname,hostname,".log" VMS_SEMICOLON);
652 setFilename(_backupFilename,logdir,sep,logname,hostname,".bak" VMS_SEMICOLON);
654 _checkpointFilename,logdir,sep,logname,hostname,".ckp" VMS_SEMICOLON);
655}
656
657
662 char*& filename, const char* logdir, const char* sep,
663 const char* logname, const char* hostname, const char* ext)
664{
665 size_t len=1+
666 strlen(logdir)+strlen(sep)+strlen(logname)+strlen(hostname)+strlen(ext);
667 filename=new char[len];
668 sprintf(filename,"%s%s%s%s%s",logdir,sep,logname,hostname,ext);
669}
670
671
686 ofstream& s, const char* filename, int flags, int* fd)
687{
688#if defined(HAVE_FSTREAM_OPEN)
689# ifdef HAVE_STD_IOSTREAM
690 ios::openmode openmodeflags =ios::out|ios::openmode(flags);
691# else
692 int openmodeflags =ios::out|flags;
693# endif
694
695# ifdef FSTREAM_OPEN_PROT
696 s.open(filename,openmodeflags,0644);
697# else
698 s.open(filename,openmodeflags);
699# endif
700 if (!s)
701 throw IOError();
702
703#elif defined(HAVE_FSTREAM_ATTACH)
704# ifdef __WIN32__
705 int localFd = _open(filename, O_WRONLY | flags, _S_IWRITE);
706# else
707 int localFd = open(filename, O_WRONLY | flags, 0644);
708# endif /* __WIN32__ */
709 if (localFd < 0)
710 throw IOError();
711 if(fd)
712 (*fd)=localFd;
713 s.attach(localFd);
714#endif
715}
716
717
718//------------------------------------------------------------------------
719// OmniEvents Log Worker Implementation
720//------------------------------------------------------------------------
722 omniEventsLog* object,
723 Method method,
724 priority_t priority
725):omni_thread(NULL,priority)
726{
727 DB(15, "omniEventsLogWorker::omniEventsLogWorker()");
728
729 _method=method;
730 _object=object;
731
732 start_undetached();
733}
734
735
737{
738 try {
739 DB(15, "omniEventsLogWorker : run_undetached Start");
740 (_object->*_method)();
741 DB(15, "omniEventsLogWorker : run_undetached End");
742 }
743 catch (CORBA::SystemException& ex) {
744 DB(0,"omniEventsLogWorker killed by CORBA system exception"
745 IF_OMNIORB4(": "<<ex._name()<<" ("<<NP_MINORSTRING(ex)<<")") ".")
746 }
747 catch (CORBA::Exception& ex) {
748 DB(0,"omniEventsLogWorker killed by CORBA exception"
749 IF_OMNIORB4(": "<<ex._name()<<) ".")
750 }
751 catch(...) {
752 DB(0,"omniEventsLogWorker killed by unknown exception.")
753 }
754 return NULL;
755}
756
758{
759 DB(20, "omniEventsLogWorker::~omniEventsLogWorker()");
760}
761
762
763}; // end namespace OmniEvents
FILE * yyin
#define STRUCT_STAT
int yydebug
#define VMS_SEMICOLON
int yyparse()
#define OMNIEVENTS_LOG_CHECKPOINT_PERIOD
Define OMNIEVENTS_LOG_CHECKPOINT_PERIOD to specify the number of seconds the omniEvents server execut...
Definition defaults.h:111
#define OMNIEVENTS_LOG_DEFAULT_LOCATION
Define OMNIEVENTS_LOG_DEFAULT_LOCATION to specify the default location where the omniEvents server ex...
Definition defaults.h:93
#define OMNIEVENTS_LOGDIR_ENV_VAR
Define OMNIEVENTS_LOGDIR_ENV_VAR to specify the environment variable that users may set to override t...
Definition defaults.h:100
#define DB(l, x)
Definition Orb.h:49
#define IF_OMNIORB4(omniORB4_code)
Definition Orb.h:46
#define NP_MINORSTRING(systemException)
Definition Orb.h:52
int gethostname(char *hostname, size_t len)
Definition gethostname.h:76
#define MAXHOSTNAMELEN
Provides the function ‘int gethostname(char* hostname, size_t len)’ in a platform independent manner.
Definition gethostname.h:65
static omni_mutex mutex
Definition pushcons.cc:168
timestamp ts
This class can be used to generate timestamps.
const char * t(void)
static omniEventsLog * theLog
void setFilename(char *&filename, const char *logdir, const char *sep, const char *logname, const char *hostname, const char *ext)
Helper function that sets the value of the first parameter to the concatenation of all the subsequent...
PersistNode * bootstrap(int port, const char *endPointNoListen)
Creates an initialState from its arguments.
void incarnateFactory(PersistNode *initialState)
Constructs the EventChannelFactory from the information in the initialState parameter.
EventChannelFactory_i * _factory
virtual void openOfstream(ofstream &s, const char *filename, int flags=0, int *fd=NULL)
Helper method that opens an output file stream using whatever method is available.
virtual PersistNode * parse()
Creates an initialState from the logfile.
bool fileExists(const char *filename) const
virtual void initializeFileNames(const char *logdir)
Sets the values of 'active', 'backup' and 'checkpoint' file names.
virtual void runWorker()
Kicks off the worker thread that periodically checkpoints the persistency logfile.
omniEventsLog(const char *logdir=NULL)
omni_thread * _workerThread
In charge of checkpoints.
virtual void output(ostream &os)
void checkpoint(void)
Entry point used by the omniEventsLogWorker to perform checkpointing.
omniEventsLogWorker()
No default construction allowed.
PersistNode * addnode(const string &name)
long attrLong(const string &key, long fallback=0) const
PersistNode * child(const string &key) const
void addattr(const string &keyvalue)