00001 #include <stdio.h>
00002 #include <sys/types.h>
00003 #include <sys/stat.h>
00004 #include <fcntl.h>
00005 #include <string.h>
00006 #include <dirent.h>
00007 #include <errno.h>
00008 #include <zlib.h>
00009 #include <unistd.h>
00010
00011
00012 #include <sys/syscall.h>
00013
00014
00015 #include <algorithm>
00016
00017 #include "LogRotation.h"
00018 #include "RioInterface.h"
00019
00020
00021 CLogRotation::CLogRotation( bool ServerInstance )
00022 {
00023 #ifdef RIO_DEBUG1
00024 RioErr << "[CLogRotation - Construtor] Start" << endl;
00025 #endif
00026
00027
00028
00029 m_ServerInstance = ServerInstance;
00030
00031 m_Initialized = false;
00032
00033 m_RequestThread = 0;
00034 m_ProcessThread = 0;
00035
00036 m_MaxLogFileSize = 0;
00037 m_MaxCombinedLogFilesSize = 0;
00038
00039 m_LogsFileDirectory[0] = 0;
00040 m_LogsFilePrefix[0] = 0;
00041
00042 m_MinLogTime = 0;
00043
00044
00045
00046
00047
00048 m_LogFileDescriptor = NULL;
00049
00050 pthread_mutex_init( &m_MutexMinLogTime, NULL );
00051 pthread_mutex_init( &m_MutexRequestQueue, NULL );
00052 pthread_mutex_init( &m_MutexProcessQueues, NULL );
00053 pthread_cond_init( &m_CondRequestThread, NULL );
00054 pthread_cond_init( &m_CondProcessThread, NULL );
00055
00056
00057
00058 m_StopRequestThread = false;
00059 m_StopProcessThread = false;
00060
00061
00062
00063 m_SaveLogs = false;
00064
00065 #ifdef RIO_DEBUG1
00066 RioErr << "[CLogRotation - Construtor] Finish" << endl;
00067 #endif
00068 }
00069
00070
00071 CLogRotation::~CLogRotation()
00072 {
00073 int error;
00074
00075 #ifdef RIO_DEBUG1
00076 RioErr << "[CLogRotation - Destructor] Start" << endl;
00077 #endif
00078
00079 if( m_Initialized )
00080 {
00081
00082
00083 if( m_RequestThread != 0 )
00084 {
00085
00086
00087 m_StopRequestThread = true;
00088
00089
00090 pthread_cond_signal( &m_CondRequestThread );
00091
00092 error = pthread_join( m_RequestThread, NULL );
00093 if( error != 0 )
00094 {
00095 RioErr << "CLogRotation::~CLogRotation erro " << error
00096 << "( " << strerror( error ) << " ao executar a "
00097 << "pthread_join na RequestThread" << endl;
00098 }
00099 }
00100
00101
00102 if( m_ProcessThread != 0 )
00103 {
00104
00105
00106 m_StopProcessThread = true;
00107
00108
00109
00110 pthread_cond_signal( &m_CondProcessThread );
00111
00112 error = pthread_join( m_ProcessThread, NULL );
00113 if( error != 0 )
00114 {
00115 RioErr << "CLogRotation::~CLogRotation erro " << error
00116 << "( " << strerror( error ) << " ao executar a "
00117 << "pthread_join na ProcessThread" << endl;
00118 }
00119 }
00120
00121
00122 DeleteSearchQueue();
00123 DeleteLogLineQueue();
00124
00125
00126 DeleteRequestQueue();
00127
00128
00129 if( m_LogFileDescriptor != NULL )
00130 {
00131 if( fclose( m_LogFileDescriptor ) != 0 )
00132 RioErr << "CLogRotation::~CLogRotation erro ao fechar o "
00133 << "arquivo de log " << m_FileLogs.back()->FileName
00134 << ": " << strerror( errno ) << " ( " << errno << ")"
00135 << endl;
00136 m_LogFileDescriptor = NULL;
00137 }
00138
00139
00140
00141 while( !m_FileLogs.empty() )
00142 {
00143 delete m_FileLogs.back();
00144 m_FileLogs.pop_back();
00145 }
00146 }
00147 pthread_mutex_destroy( &m_MutexMinLogTime );
00148 pthread_mutex_destroy( &m_MutexRequestQueue );
00149 pthread_mutex_destroy( &m_MutexProcessQueues );
00150 pthread_cond_destroy( &m_CondRequestThread );
00151 pthread_cond_destroy( &m_CondProcessThread );
00152
00153 #ifdef RIO_DEBUG1
00154 RioErr << "[CLogRotation - Destructor] Finish" << endl;
00155 #endif
00156 }
00157
00158
00159 RequestRecord *CLogRotation::RemoveRequestQueue( void )
00160 {
00161 RequestRecord *request;
00162
00163 #ifdef RIO_DEBUG1
00164 RioErr << "[CLogRotation - RemoveRequestQueue] Start" << endl;
00165 #endif
00166
00167 request = m_RequestQueue.front();
00168 if( request != NULL )
00169 m_RequestQueue.pop();
00170
00171 #ifdef RIO_DEBUG1
00172 RioErr << "[CLogRotation - RemoveRequestQueue] Finish" << endl;
00173 #endif
00174
00175 return request;
00176 }
00177
00178
00179 LogLine *CLogRotation::RemoveLogLineQueue( void )
00180 {
00181 LogLine *line;
00182
00183 #ifdef RIO_DEBUG1
00184 RioErr << "[CLogRotation - RemoveLogLineQueue] Start" << endl;
00185 #endif
00186
00187 line = m_LogLineQueue.front();
00188 if( line != NULL )
00189 m_LogLineQueue.pop();
00190
00191 #ifdef RIO_DEBUG1
00192 RioErr << "[CLogRotation - RemoveLogLineQueue] Finish" << endl;
00193 #endif
00194
00195 return line;
00196 }
00197
00198
00199 SearchRecord *CLogRotation::RemoveSearchQueue( void )
00200 {
00201 SearchRecord *search;
00202
00203 #ifdef RIO_DEBUG1
00204 RioErr << "[CLogRotation - RemoveSearchQueue] Start" << endl;
00205 #endif
00206
00207 search = m_SearchQueue.front();
00208 if( search != NULL )
00209 m_SearchQueue.pop();
00210
00211 #ifdef RIO_DEBUG1
00212 RioErr << "[CLogRotation - RemoveSearchQueue] Finish" << endl;
00213 #endif
00214
00215 return search;
00216 }
00217
00218
00219
00220
00221
00222 void CLogRotation::DeleteRequestQueue()
00223 {
00224 int erro;
00225 RequestRecord *record;
00226 LogLine *line;
00227 SearchRecord *search;
00228
00229 #ifdef RIO_DEBUG1
00230 RioErr << "[CLogRotation - DeleteRequestQueue] Start" << endl;
00231 #endif
00232
00233 while( !m_RequestQueue.empty() )
00234 {
00235
00236 record = RemoveRequestQueue();
00237 if( record == NULL )
00238 RioErr << "CLogRotation::DeleteRequestQueue erro ao obter uma "
00239 << "entrada da fila de solitacoes (m_RequestQueue)"
00240 << endl;
00241
00242
00243 switch( record->Type )
00244 {
00245 case INSERT_LINE:
00246 line = ( LogLine * ) record->Data;
00247 erro = InsertLogLine( line );
00248 if( erro != S_OK )
00249 RioErr << "CLogRotation::DeleteRequestQueue erro ao "
00250 << "escrever uma linha no log" << endl;
00251 delete line;
00252 break;
00253 case EXECUTE_SEARCH:
00254 search = ( SearchRecord * ) record->Data;
00255 delete search;
00256 break;
00257 default:
00258 RioErr << "CLogRotation::DeleteRequestQueue tipo "
00259 << record->Type << " invalida. Nao sera possivel "
00260 << "remover o ponteiro." << endl;
00261 break;
00262 }
00263 delete record;
00264 }
00265
00266 #ifdef RIO_DEBUG1
00267 RioErr << "[CLogRotation - DeleteRequestQueue] Finish" << endl;
00268 #endif
00269 }
00270
00271
00272
00273 void CLogRotation::DeleteLogLineQueue()
00274 {
00275 int erro;
00276 LogLine *line;
00277
00278 #ifdef RIO_DEBUG1
00279 RioErr << "[CLogRotation - DeleteLogLineQueue] Start" << endl;
00280 #endif
00281
00282 while( !m_LogLineQueue.empty() )
00283 {
00284 line = RemoveLogLineQueue();
00285 if( line == NULL )
00286 RioErr << "CLogRotation::DeleteLogLineQueue erro ao obter uma "
00287 << "entrada da fila de logs (m_LogLineQueue)"
00288 << endl;
00289 erro = InsertLogLine( line );
00290 if( erro != S_OK )
00291 RioErr << "CLogRotation::DeleteLogLineQueue erro ao "
00292 << "escrever uma linha no log" << endl;
00293 delete line;
00294 }
00295
00296 #ifdef RIO_DEBUG1
00297 RioErr << "[CLogRotation - DeleteLogLineQueue] Finish" << endl;
00298 #endif
00299 }
00300
00301
00302
00303 void CLogRotation::DeleteSearchQueue()
00304 {
00305 SearchRecord *record;
00306
00307 #ifdef RIO_DEBUG1
00308 RioErr << "[CLogRotation - DeleteSearchQueue] Start" << endl;
00309 #endif
00310
00311 while( !m_SearchQueue.empty() )
00312 {
00313 record = RemoveSearchQueue();
00314 if( record == NULL )
00315 RioErr << "CLogRotation::DeleteSearchQueue erro ao obter uma "
00316 << "entrada da fila de logs (m_SearchQueue)"
00317 << endl;
00318 delete record;
00319 }
00320
00321 #ifdef RIO_DEBUG1
00322 RioErr << "[CLogRotation - DeleteSearchQueue] Finish" << endl;
00323 #endif
00324 }
00325
00326
00327
00328
00329 int CLogRotation::NewRequest( unsigned short Type, void *Data )
00330 {
00331 RequestRecord *request;
00332 bool SendSignal;
00333 unsigned int ExpectedSize;
00334
00335 #ifdef RIO_DEBUG1
00336 RioErr << "[CLogRotation - NewRequest] Start" << endl;
00337 #endif
00338
00339
00340 request = new RequestRecord;
00341 if( request == NULL )
00342 {
00343
00344 #ifdef RIO_DEBUG1
00345 RioErr << "[CLogRotation - NewRequest] Finish1" << endl;
00346 #endif
00347
00348 #ifdef RIO_DEBUG2
00349 RioErr << "CLogRotation::NewRequest erro de alocacao de memoria ao "
00350 << "criar uma nova solicitacao" << endl;
00351 #endif
00352
00353 return ERROR_LOGROTATION + ERROR_MEMORY;
00354 }
00355 request->Type = Type;
00356 request->Data = Data;
00357
00358 pthread_mutex_lock( &m_MutexRequestQueue );
00359
00360 SendSignal = m_RequestQueue.empty();
00361 ExpectedSize = m_RequestQueue.size() + 1;
00362
00363 m_RequestQueue.push( request );
00364 if( m_RequestQueue.size() != ExpectedSize )
00365 {
00366
00367 #ifdef RIO_DEBUG1
00368 RioErr << "[CLogRotation - NewRequest] Finish2" << endl;
00369 #endif
00370
00371 #ifdef RIO_DEBUG2
00372 RioErr << "CLogRotation::NewRequest erro de alocacao de memoria ao "
00373 << "criar uma nova solicitacao" << endl;
00374 #endif
00375
00376 delete request;
00377 return ERROR_LOGROTATION + ERROR_MEMORY;
00378 }
00379
00380
00381
00382 if( SendSignal )
00383 pthread_cond_signal( &m_CondRequestThread );
00384
00385 pthread_mutex_unlock( &m_MutexRequestQueue );
00386
00387 #ifdef RIO_DEBUG1
00388 RioErr << "[CLogRotation - NewRequest] Finish3" << endl;
00389 #endif
00390
00391 return S_OK;
00392 }
00393
00394
00395
00396
00397 int CLogRotation::InsertLogLine( LogLine *line )
00398 {
00399
00400
00401 struct stat LogStat;
00402
00403
00404 int LogFile;
00405
00406 gzFile ZipFile;
00407
00408
00409 LogFileRecord *FileRecord;
00410
00411
00412
00413
00414
00415
00416
00417
00418 int NumRead, NumWrite;
00419 char CompacLogsFileName[ MaxPathSize ];
00420 char Buffer[ BUFFERCOMPACSIZE ];
00421
00422
00423
00424
00425 int erro;
00426
00427 #ifdef RIO_DEBUG1
00428 RioErr << "[CLogRotation - InsertLogLine] Start" << endl;
00429 #endif
00430
00431
00432
00433
00434
00435 if( m_LogFileDescriptor == NULL )
00436 {
00437 #ifdef RIO_DEBUG2
00438 RioErr << "CLogRotation::InsertLogLine o arquivo anterior foi "
00439 << "compactado. Criando um novo arquivo" << endl;
00440 #endif
00441
00442 FileRecord = new LogFileRecord;
00443 if( FileRecord == NULL )
00444 {
00445 RioErr << "CLogRotation::InsertLogLine erro de alocacao de memoria "
00446 << "ao criar a estrutura FileRecord" << endl;
00447
00448 #ifdef RIO_DEBUG1
00449 RioErr << "[CLogRotation - InsertLogLine] Finish1" << endl;
00450 #endif
00451
00452 return ERROR_LOGROTATION + ERROR_MEMORY;
00453 }
00454
00455 sprintf( FileRecord->FileName, "%s%s.%lu-0", m_LogsFileDirectory,
00456 m_LogsFilePrefix, (unsigned long) line->LogTime );
00457
00458 FileRecord->StartTime = line->LogTime;
00459 FileRecord->EndTime = 0;
00460
00461
00462 m_FileLogs.push_back( FileRecord );
00463
00464
00465
00466 m_LogFileDescriptor = fopen( FileRecord->FileName, "a" );
00467 if( m_LogFileDescriptor == NULL )
00468 {
00469 RioErr << "CLogRotation::InsertLogLine erro ao abrir o arquivo de "
00470 << "log " << FileRecord->FileName << ": "
00471 << strerror( errno ) << " ( " << errno << ")" << endl;
00472
00473 #ifdef RIO_DEBUG1
00474 RioErr << "[CLogRotation - InsertLogLine] Finish2" << endl;
00475 #endif
00476
00477 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
00478 }
00479 RioErr << "CLogRotation::InsertLogLine criando o novo log "
00480 << FileRecord->FileName << ": Tempo inicial = "
00481 << ( unsigned int ) FileRecord->StartTime << endl;
00482 }
00483 else
00484 {
00485
00486
00487 FileRecord = m_FileLogs.back();
00488 #ifdef RIO_DEBUG2
00489 RioErr << "CLogRotation::InsertLogLine usando o arquivo nao "
00490 << "compactado " << FileRecord->FileName << endl;
00491 #endif
00492 }
00493
00494
00495
00496
00497
00498
00499 pthread_mutex_lock( &m_MutexMinLogTime );
00500 if( m_MinLogTime == 0 )
00501 m_MinLogTime = line->LogTime;
00502
00503 pthread_mutex_unlock( &m_MutexMinLogTime );
00504
00505 if( FileRecord == NULL )
00506 {
00507 RioErr << "CLogRotation::InsertLogLine erro ao obter o nome do log "
00508 << "usado: nao existem nomes de logs no vetor m_FileLogs"
00509 << endl;
00510
00511 #ifdef RIO_DEBUG1
00512 RioErr << "[CLogRotation - InsertLogLine] Finish3" << endl;
00513 #endif
00514
00515 return ERROR_LOGROTATION + ERROR_UNEXPECTED;
00516 }
00517 #ifdef RIO_DEBUG2
00518 RioErr << "CLogRotation::InsertLogLine tentando escrever no arquivo "
00519 << FileRecord->FileName << endl;
00520 #endif
00521
00522 if( fprintf( m_LogFileDescriptor, "%lu %s\n",
00523 ( unsigned long ) ( line->LogTime ), line->LogInfo ) < 0 )
00524
00525 {
00526 RioErr << "CLogRotation::InsertLogLine erro ao escrever no arquivo de "
00527 << "log " << FileRecord->FileName << ": " << strerror( errno )
00528 << " ( " << errno << ")" << endl;
00529
00530 #ifdef RIO_DEBUG1
00531 RioErr << "[CLogRotation - InsertLogLine] Finish4" << endl;
00532 #endif
00533
00534 return ERROR_LOGROTATION + ERROR_LOGFILE_WRITE_FAILED;
00535 }
00536
00537
00538
00539 if ( fflush( m_LogFileDescriptor ) != 0 )
00540 {
00541 RioErr << "CLogRotation::InsertLogLine erro ao escrever no arquivo de "
00542 << "log " << FileRecord->FileName << ": " << strerror( errno )
00543 << " ( " << errno << ")" << endl;
00544
00545 #ifdef RIO_DEBUG1
00546 RioErr << "[CLogRotation - InsertLogLine] Finish5" << endl;
00547 #endif
00548
00549 return ERROR_LOGROTATION + ERROR_LOGFILE_WRITE_FAILED;
00550 }
00551 #ifdef RIO_DEBUG2
00552 RioErr << "CLogRotation::InsertLogLine obtendo os atributos do arquivo "
00553 << FileRecord->FileName << endl;
00554 #endif
00555
00556
00557
00558
00559 if ( stat( FileRecord->FileName, &LogStat ) < 0 )
00560 {
00561 RioErr << "CLogRotation::InsertLogLine erro ao obter o estado do "
00562 << "arquivo de log " << FileRecord->FileName << ": "
00563 << strerror( errno ) << " ( " << errno << ")" << endl;
00564
00565 #ifdef RIO_DEBUG1
00566 RioErr << "[CLogRotation - InsertLogLine] Finish6" << endl;
00567 #endif
00568
00569 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
00570 }
00571 else
00572 {
00573 #ifdef RIO_DEBUG2
00574 RioErr << "CLogRotation::InsertLogLine verificando se e necessario "
00575 << "compactar o arquivo " << FileRecord->FileName << endl;
00576 #endif
00577
00578 if( LogStat.st_size > ( off_t ) m_MaxLogFileSize )
00579 {
00580 RioErr << "CLogRotation::InsertLogLine o tamanho "
00581 << LogStat.st_size << " do arquivo de log "
00582 << FileRecord->FileName << " passou do tamanho maximo igual "
00583 << "ao valor " << m_MaxLogFileSize << " ( m_MaxLogFileSize )"
00584 << endl;
00585
00586
00587
00588 if( fclose( m_LogFileDescriptor ) != 0 )
00589 {
00590 RioErr << "CLogRotation::InsertLogLine erro ao fechar o arquivo"
00591 << " de log " << FileRecord->FileName << ": "
00592 << strerror( errno ) << " ( " << errno << ")" << endl;
00593
00594 #ifdef RIO_DEBUG1
00595 RioErr << "[CLogRotation - InsertLogLine] Finish7" << endl;
00596 #endif
00597
00598 return ERROR_LOGROTATION + ERROR_LOGFILE_CLOSE_FAILED;
00599 }
00600 m_LogFileDescriptor = NULL;
00601
00602
00603 sprintf( CompacLogsFileName, "%s%s.%lu-%lu.gz", m_LogsFileDirectory,
00604 m_LogsFilePrefix, (unsigned long) FileRecord->StartTime,
00605 (unsigned long) line->LogTime );
00606
00607 RioErr << "CLogRotation::InsertLogLine criando o arquivo "
00608 << "compactado " << CompacLogsFileName << ", a partir do "
00609 << "arquivo atual de logs " << FileRecord->FileName << endl;
00610
00611
00612 ZipFile = gzopen( CompacLogsFileName, "w9" );
00613 if( ZipFile == NULL )
00614 {
00615 RioErr << "CLogRotation::InsertLogLine erro ao criar o arquivo "
00616 << "compactado " << CompacLogsFileName << "zlib error : "
00617 << gzerror( ZipFile, &erro ) << " (" << erro << ")";
00618 if( erro == 0 )
00619 RioErr << "libc error: " << strerror( errno ) << "("
00620 << errno << ")" << endl;
00621 else
00622 RioErr << endl;
00623
00624 #ifdef RIO_DEBUG1
00625 RioErr << "[CLogRotation - InsertLogLine] Finish8" << endl;
00626 #endif
00627
00628 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
00629 }
00630 LogFile = open( FileRecord->FileName, O_RDONLY );
00631 if( LogFile < 0 )
00632 {
00633 RioErr << "CLogRotation::InsertLogLine erro ao abrir o "
00634 << "arquivo de log " << FileRecord->FileName << ": "
00635 << strerror( errno ) << " ( " << errno << ")" << endl;
00636
00637 #ifdef RIO_DEBUG1
00638 RioErr << "[CLogRotation - InsertLogLine] Finish9" << endl;
00639 #endif
00640
00641 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
00642 }
00643
00644 while( ( NumRead = read( LogFile, Buffer, 1024 ) ) > 0 )
00645 {
00646 if( NumRead < 0 )
00647 {
00648 RioErr << "CLogRotation::InsertLogLine erro ao ler do "
00649 << "arquivo de log " << FileRecord->FileName << ": "
00650 << strerror( errno ) << " ( " << errno << ")"
00651 << endl;
00652 close( LogFile );
00653 gzclose( ZipFile );
00654 remove( CompacLogsFileName );
00655
00656 #ifdef RIO_DEBUG1
00657 RioErr << "[CLogRotation - InsertLogLine] Finish10" << endl;
00658 #endif
00659
00660 return ERROR_LOGROTATION + ERROR_LOGFILE_READ_FAILED;
00661
00662 }
00663 NumWrite = gzwrite( ZipFile, Buffer, NumRead );
00664 if( NumWrite == 0 )
00665 {
00666 RioErr << "CLogRotation::InsertLogLine erro ao escrever no "
00667 << "arquivo compactado " << CompacLogsFileName
00668 << "zlib error : " << gzerror( ZipFile, &erro )
00669 << " (" << erro << ")";
00670 if( erro == 0 )
00671 RioErr << "libc error: " << strerror( errno ) << "("
00672 << errno << ")" << endl;
00673 else
00674 RioErr << endl;
00675 close( LogFile );
00676 gzclose( ZipFile );
00677 remove( CompacLogsFileName );
00678
00679 #ifdef RIO_DEBUG1
00680 RioErr << "[CLogRotation - InsertLogLine] Finish11" << endl;
00681 #endif
00682
00683 return ERROR_LOGROTATION + ERROR_LOGFILE_WRITE_FAILED;
00684 }
00685 else if( NumWrite != NumRead )
00686 {
00687 RioErr << "CLogRotation::InsertLogLine erro ao escrever no "
00688 << "arquivo compactado " << CompacLogsFileName
00689 << ": escritos somente " << NumWrite << " bytes de "
00690 << NumRead << " bytes" << endl;
00691 close( LogFile );
00692 if( gzclose( ZipFile ) != Z_OK )
00693 {
00694 RioErr << "CLogRotation::InsertLogLine erro ao fechar "
00695 << "o arquivo compactado " << CompacLogsFileName
00696 << "zlib error : " << gzerror( ZipFile, &erro )
00697 << " (" << erro << ")";
00698 if( erro == 0 )
00699 RioErr << "libc error: " << strerror( errno ) << "("
00700 << errno << ")" << endl;
00701 else
00702 RioErr << endl;
00703 }
00704 remove( CompacLogsFileName );
00705
00706 #ifdef RIO_DEBUG1
00707 RioErr << "[CLogRotation - InsertLogLine] Finish12" << endl;
00708 #endif
00709
00710 return ERROR_LOGROTATION + ERROR_LOGFILE_WRITE_FAILED;
00711 }
00712 }
00713 if( close( LogFile ) < 0 )
00714 {
00715 RioErr << "CLogRotation::InsertLogLine erro ao fechar o "
00716 << "arquivo nao compactado " << FileRecord->FileName
00717 << ": libc error: " << strerror( errno ) << "("
00718 << errno << ")" << endl;
00719
00720 #ifdef RIO_DEBUG1
00721 RioErr << "[CLogRotation - InsertLogLine] Finish13" << endl;
00722 #endif
00723
00724 return ERROR_LOGROTATION + ERROR_LOGFILE_CLOSE_FAILED;
00725 }
00726
00727 if( gzclose( ZipFile ) != Z_OK )
00728 {
00729 RioErr << "CLogRotation::InsertLogLine erro ao fechar o "
00730 << "arquivo compactado " << CompacLogsFileName
00731 << ": zlib error : " << gzerror( ZipFile, &erro ) << " ("
00732 << erro << ")";
00733 if( erro == 0 )
00734 RioErr << ", libc error: " << strerror( errno ) << "("
00735 << errno << ")" << endl;
00736 else
00737 RioErr << endl;
00738
00739 #ifdef RIO_DEBUG1
00740 RioErr << "[CLogRotation - InsertLogLine] Finish14" << endl;
00741 #endif
00742
00743 return ERROR_LOGROTATION + ERROR_LOGFILE_CLOSE_FAILED;
00744 }
00745
00746 if( remove( FileRecord->FileName ) < 0 )
00747 {
00748 RioErr << "CLogRotation::InsertLogLine erro ao remover o "
00749 << "arquivo " << FileRecord->FileName << endl;
00750 strcpy( FileRecord->FileName, CompacLogsFileName );
00751
00752 #ifdef RIO_DEBUG1
00753 RioErr << "[CLogRotation - InsertLogLine] Finish15" << endl;
00754 #endif
00755
00756 return ERROR_LOGROTATION + ERROR_LOGFILE_REMOVE_FAILED;
00757 }
00758
00759
00760 strcpy( FileRecord->FileName, CompacLogsFileName );
00761
00762
00763 FileRecord->EndTime = line->LogTime;
00764 }
00765 }
00766
00767 #ifdef RIO_DEBUG1
00768 RioErr << "[CLogRotation - InsertLogLine] Finish16" << endl;
00769 #endif
00770
00771 return S_OK;
00772 }
00773
00774
00775
00776
00777
00778 int CLogRotation::SearchLogs( SearchRecord *Search )
00779 {
00780 unsigned int PosLog;
00781
00782 gzFile CompacLogFile;
00783
00784
00785 gzFile SearchFile;
00786
00787
00788 bool SearchFileUsed;
00789
00790 bool SearchLogFile;
00791
00792 int erro, SearchResult;
00793
00794 char Line[ MAXLOGLINESIZE + MAXTIMESTRSIZE ];
00795
00796 time_t LogTime;
00797
00798 #ifdef RIO_DEBUG1
00799 RioErr << "[CLogRotation - SearchLogs] Start" << endl;
00800 #endif
00801
00802 #ifdef RIO_DEBUG2
00803
00804
00805 time_t MinLogTime = 0, MaxLogTime = 0;
00806 RioErr << "CLogRotation::SearchLogs lista com os arquivos: tamanho = "
00807 << m_FileLogs.size() << ":" << endl;
00808 for( unsigned int i = 0; i < m_FileLogs.size(); i++ )
00809 RioErr << "CLogRotation:::SearchLogs posicao " << i << " do vetor: "
00810 << "nome = " << m_FileLogs[ i ]->FileName << ", Tempo inicial = "
00811 << ( unsigned long ) m_FileLogs[ i ]->StartTime
00812 << ", Tempo Final = "
00813 << ( unsigned long ) m_FileLogs[ i ]->EndTime << endl;
00814 #endif
00815
00816 SearchFile = gzopen( Search->SearchFileName, "w9" );
00817 if( SearchFile == NULL )
00818 {
00819 RioErr << "CLogRotation::SearchLogs erro ao criar o arquivo compactado "
00820 << Search->SearchFileName << ": zlib error : "
00821 << gzerror( SearchFile, &erro ) << " (" << erro << ")";
00822 if( erro == 0 )
00823 RioErr << ", libc error: " << strerror( errno ) << "(" << errno
00824 << ")" << endl;
00825 else
00826 RioErr << endl;
00827
00828 #ifdef RIO_DEBUG1
00829 RioErr << "[CLogRotation - SearchLogs] Finish1" << endl;
00830 #endif
00831
00832 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
00833 }
00834
00835
00836
00837 SearchFileUsed = false;
00838
00839
00840 for( PosLog = 0; PosLog < m_FileLogs.size(); PosLog++ )
00841 {
00842 if( m_FileLogs[ PosLog ]->EndTime == 0 )
00843 SearchLogFile = ( Search->EndTime >=
00844 m_FileLogs[ PosLog ]->StartTime );
00845 else
00846 SearchLogFile = ( ( Search->EndTime >=
00847 m_FileLogs[ PosLog ]->StartTime ) &&
00848 ( Search->StartTime <=
00849 m_FileLogs[ PosLog ]->EndTime ) );
00850 if( SearchLogFile )
00851 {
00852 #ifdef RIO_DEBUG2
00853 RioErr << "SearchLogs verificando o arquivo compactado de log "
00854 << m_FileLogs[ PosLog ]->FileName << " com o tempo inicial "
00855 << "de " << ( unsigned long ) m_FileLogs[ PosLog ]->StartTime
00856 << " e o tempo final de "
00857 << ( unsigned long ) m_FileLogs[ PosLog ]->EndTime << endl;
00858 #endif
00859
00860
00861
00862
00863 CompacLogFile = gzopen( m_FileLogs[ PosLog ]->FileName, "r" );
00864 if( CompacLogFile == NULL )
00865 {
00866 RioErr << "CLogRotation::SearchLogs erro ao abrir o arquivo "
00867 << m_FileLogs[ PosLog ]->FileName << ": zlib error : "
00868 << gzerror( CompacLogFile, &erro ) << " (" << erro
00869 << ")";
00870 if( erro == 0 )
00871 RioErr << ", libc error: " << strerror( errno ) << "("
00872 << errno << ")" << endl;
00873 else
00874 RioErr << endl;
00875 gzclose( CompacLogFile );
00876
00877 #ifdef RIO_DEBUG1
00878 RioErr << "[CLogRotation - SearchLogs] Finish2" << endl;
00879 #endif
00880
00881 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
00882 }
00883
00884 while( gzgets( CompacLogFile, Line, MAXLOGLINESIZE ) != Z_NULL )
00885 {
00886
00887 if( sscanf( Line, "%lu", ( unsigned long * ) &LogTime ) != 1 )
00888 {
00889 RioErr << "CLogRotation::SearchLogs erro o tempo de uma "
00890 << "linha do arquivo "
00891 << m_FileLogs[ PosLog ]->FileName << endl;
00892 gzclose( CompacLogFile );
00893
00894 #ifdef RIO_DEBUG1
00895 RioErr << "[CLogRotation - SearchLogs] Finish3" << endl;
00896 #endif
00897
00898 return ERROR_LOGROTATION + ERROR_LOGFILE_LINE_FORMAT;
00899 }
00900 #ifdef RIO_DEBUG2
00901 RioErr << "CLogRotation::SearchLogs linha = \"" << Line
00902 << "\", tempo lido = " << ( unsigned long ) LogTime
00903 << endl;
00904 if( MinLogTime == 0 )
00905 MinLogTime = LogTime;
00906 if( MaxLogTime <= LogTime )
00907 {
00908 if( ( MaxLogTime != 0) && ( LogTime > MaxLogTime + 1 ) )
00909 {
00910 RioErr << "CLogRotation::SearchLogs a busca verificou, "
00911 << "ao ler o arquivo de log "
00912 << m_FileLogs[ PosLog ]->FileName
00913 << " a seguinte faixa de tempo: "
00914 << ( unsigned long ) MinLogTime << " ate "
00915 << ( unsigned long ) MaxLogTime << endl;
00916 MinLogTime = LogTime;
00917 }
00918 MaxLogTime = LogTime;
00919 }
00920 else
00921 RioErr << "CLogRotation::SearchLogs erro na ordenacao dos "
00922 << "logs: o log com um tempo menor igual a "
00923 << ( unsigned long ) LogTime << " esta, no arquivo, "
00924 << "apos um log com o tempo "
00925 << ( unsigned long ) MaxLogTime << endl;
00926 #endif
00927
00928
00929
00930 if( ( LogTime >= Search->StartTime ) &&
00931 ( LogTime <= Search->EndTime ) )
00932 {
00933
00934 if( gzputs ( SearchFile, Line ) < 0 )
00935 {
00936 RioErr << "CLogRotation::SearchLogs erro ao escrever "
00937 << "no arquivo compactado "
00938 << Search->SearchFileName << ": zlib error : "
00939 << gzerror( SearchFile, &erro ) << " (" << erro
00940 << ")";
00941 if( erro == 0 )
00942 RioErr << ", libc error: " << strerror( errno )
00943 << "(" << errno << ")" << endl;
00944 else
00945 RioErr << endl;
00946 if( gzclose( SearchFile ) != Z_OK )
00947 {
00948 RioErr << "CLogRotation::SearchLogs erro ao fechar "
00949 << "o arquivo compactado "
00950 << Search->SearchFileName
00951 << ": zlib error : "
00952 << gzerror( SearchFile, &erro ) << " (" << erro
00953 << ")";
00954 if( erro == 0 )
00955 RioErr << ",libc error: " << strerror( errno )
00956 << "(" << errno << ")" << endl;
00957 else
00958 RioErr << endl;
00959 }
00960 remove( Search->SearchFileName );
00961 gzclose( CompacLogFile );
00962
00963 #ifdef RIO_DEBUG1
00964 RioErr << "[CLogRotation - SearchLogs] Finish3" << endl;
00965 #endif
00966
00967 return ERROR_LOGROTATION + ERROR_LOGFILE_WRITE_FAILED;
00968 }
00969 SearchFileUsed = true;
00970 }
00971 }
00972 if( !gzeof( CompacLogFile ) )
00973 {
00974 RioErr << "CLogRotation::SearchLogs erro ao ler o arquivo "
00975 << m_FileLogs[ PosLog ]->FileName << ": zlib error : "
00976 << gzerror( CompacLogFile, &erro ) << " (" << erro
00977 << ")";
00978 if( erro == 0 )
00979 RioErr << ", libc error: " << strerror( errno ) << "("
00980 << errno << ")" << endl;
00981 else
00982 RioErr << endl;
00983 if( gzeof( CompacLogFile ) )
00984 RioErr << "CLogRotation::SearchLogs fim do arquivo "
00985 << m_FileLogs[ PosLog ]->FileName << endl;
00986 gzclose( CompacLogFile );
00987
00988 #ifdef RIO_DEBUG1
00989 RioErr << "[CLogRotation - SearchLogs] Finish4" << endl;
00990 #endif
00991
00992 return ERROR_LOGROTATION + ERROR_LOGFILE_READ_FAILED;
00993 }
00994 if( gzclose( CompacLogFile ) != Z_OK )
00995 {
00996 RioErr << "CLogRotation::SearchLogs erro ao fechar o arquivo "
00997 << "compactado " << m_FileLogs[ PosLog ]->FileName
00998 << ": zlib error : " << gzerror( CompacLogFile, &erro )
00999 << " (" << erro << ")";
01000 if( erro == 0 )
01001 RioErr << ",libc error: " << strerror( errno ) << "("
01002 << errno << ")" << endl;
01003 else
01004 RioErr << endl;
01005 }
01006 }
01007 }
01008 #ifdef RIO_DEBUG2
01009
01010 if( ( MinLogTime != 0 ) && ( MaxLogTime != 0 ) )
01011 RioErr << "CLogRotation::SearchLogs a busca verificou, ao ler o arquivo "
01012 << " de log " << m_FileLogs.back()->FileName << " a seguinte "
01013 << " faixa de tempo: " << ( unsigned long ) MinLogTime << " ate "
01014 << ( unsigned long ) MaxLogTime << endl;
01015 #endif
01016
01017 if( gzclose( SearchFile ) != Z_OK )
01018 {
01019 RioErr << "CLogRotation::SearchLogs erro ao fechar o arquivo "
01020 << "compactado " << Search->SearchFileName << ": zlib error : "
01021 << gzerror( SearchFile, &erro ) << " (" << erro << ")";
01022 if( erro == 0 )
01023 RioErr << ", libc error: " << strerror( errno ) << "(" << errno
01024 << ")" << endl;
01025 else
01026 RioErr << endl;
01027
01028 #ifdef RIO_DEBUG1
01029 RioErr << "[CLogRotation - SearchLogs] Finish5" << endl;
01030 #endif
01031
01032 return ERROR_LOGROTATION + ERROR_LOGFILE_CLOSE_FAILED;
01033 }
01034 if( SearchFileUsed )
01035 SearchResult = SEARCH_OK;
01036 else
01037 {
01038 SearchResult = SEARCH_FAILED;
01039
01040 remove( Search->SearchFileName );
01041 }
01042
01043 Search->callback( Search->SearchFileName, Search->StartTime,
01044 Search->EndTime, SearchResult, Search->callbackparam );
01045
01046 #ifdef RIO_DEBUG1
01047 RioErr << "[CLogRotation - SearchLogs] Finish6" << endl;
01048 #endif
01049
01050 return S_OK;
01051 }
01052
01053
01054
01055
01056 int CLogRotation::GetTimeStamp( char *FileName, time_t *StartTime,
01057 time_t *EndTime )
01058 {
01059 char *StartTimeStamp, *StrAux;
01060
01061 #ifdef RIO_DEBUG1
01062 RioErr << "[CLogRotation - GetTimeStamp] Start" << endl;
01063 #endif
01064
01065
01066 StartTimeStamp = strrchr( FileName, '.' );
01067 if( strcasecmp( StartTimeStamp, ".gz" ) == 0 )
01068 {
01069
01070 StrAux = StartTimeStamp;
01071 StrAux[ 0 ] = 0;
01072 StartTimeStamp = strrchr( FileName, '.' );
01073 StrAux[ 0 ] = '.';
01074 }
01075 if( StartTimeStamp != NULL )
01076 {
01077 StartTimeStamp++;
01078
01079
01080 if( sscanf( StartTimeStamp, "%lu-%lu", (unsigned long *) StartTime,
01081 (unsigned long *) EndTime ) != 2 )
01082 {
01083 RioErr << "CLogRotation::GetTimeStamp formato incorreto no nome "
01084 << FileName << " do arquivo" << endl;
01085
01086
01087
01088 #ifdef RIO_DEBUG1
01089 RioErr << "[CLogRotation - GetTimeStamp] Finish1" << endl;
01090 #endif
01091
01092 return ERROR_LOGROTATION + ERROR_LOGFILE_FILENAME_FORMAT;
01093 }
01094 return S_OK;
01095 }
01096 else
01097 {
01098 #ifdef RIO_DEBUG1
01099 RioErr << "[CLogRotation - GetTimeStamp] Finish2" << endl;
01100 #endif
01101
01102 return ERROR_LOGROTATION + ERROR_LOGFILE_FILENAME_FORMAT;
01103 }
01104 }
01105
01106
01107
01108
01109
01110
01111 int CLogRotation::GetFileLogs()
01112 {
01113
01114 DIR *LogsDir;
01115
01116
01117 struct dirent *File;
01118
01119 time_t StartTime, EndTime;
01120
01121 int erro;
01122
01123 LogFileRecord *FileRecord;
01124
01125 #ifdef RIO_DEBUG1
01126 RioErr << "[CLogRotation - GetFileLogs] Start" << endl;
01127 #endif
01128
01129 LogsDir = opendir( m_LogsFileDirectory );
01130 if( LogsDir == NULL )
01131 {
01132 RioErr << "CLogRotation::GetFileLogs erro ao abrir o diretorio "
01133 << m_LogsFileDirectory << endl;
01134
01135 #ifdef RIO_DEBUG1
01136 RioErr << "[CLogRotation - GetFileLogs] Finish1" << endl;
01137 #endif
01138
01139 return ERROR_LOGROTATION + ERROR_DIRECTORY_READ_FAILED;
01140 }
01141
01142 while ( ( File = readdir( LogsDir ) ) != NULL )
01143 {
01144
01145 if( strstr( File->d_name, m_LogsFilePrefix ) == File->d_name )
01146 {
01147
01148
01149
01150
01151
01152
01153 FileRecord = new LogFileRecord;
01154 if( FileRecord == NULL )
01155 {
01156 RioErr << "CLogRotation::GetFileLogs erro de alocacao de "
01157 << "memoria ao alocar um registro para o arquivo de log "
01158 << File->d_name << endl;
01159 closedir( LogsDir );
01160
01161 #ifdef RIO_DEBUG1
01162 RioErr << "[CLogRotation - GetFileLogs] Finish2" << endl;
01163 #endif
01164
01165 return ERROR_LOGROTATION + ERROR_MEMORY;
01166 }
01167
01168
01169 strcpy( FileRecord->FileName, m_LogsFileDirectory );
01170 strcat( FileRecord->FileName, File->d_name );
01171
01172
01173 erro = GetTimeStamp( File->d_name, &StartTime, &EndTime );
01174 if( erro != S_OK )
01175 {
01176 RioErr << "CLogRotation::GetFileLogs erro ao obter os tempos"
01177 << " inicial e final do nome " << File->d_name
01178 << " do arquivo de log" << endl;
01179 closedir( LogsDir );
01180 delete FileRecord;
01181
01182 #ifdef RIO_DEBUG1
01183 RioErr << "[CLogRotation - GetFileLogs] Finish3" << endl;
01184 #endif
01185
01186 return erro;
01187 }
01188 FileRecord->StartTime = StartTime;
01189 FileRecord->EndTime = EndTime;
01190
01191 if( EndTime == 0 )
01192 {
01193
01194
01195
01196
01197 if( m_LogFileDescriptor == NULL )
01198 {
01199 m_LogFileDescriptor = fopen( FileRecord->FileName, "a" );
01200 if( m_LogFileDescriptor == NULL )
01201 {
01202 RioErr << "CLogRotation::InsertLogLine erro ao abrir o "
01203 << "arquivo de log " << FileRecord->FileName
01204 << ": " << strerror( errno ) << " ( " << errno
01205 << ")" << endl;
01206
01207 #ifdef RIO_DEBUG1
01208 RioErr << "[CLogRotation - GetFileLogs] Finish4"
01209 << endl;
01210 #endif
01211
01212 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
01213 }
01214 }
01215 else
01216 {
01217
01218
01219
01220 RioErr << "CLogRotation::GetFileLogs existem pelo menos "
01221 << "dois arquivos de log nao compactados no "
01222 << "diretorio " << m_LogsFileDirectory << endl;
01223 closedir( LogsDir );
01224 fclose( m_LogFileDescriptor );
01225
01226 #ifdef RIO_DEBUG1
01227 RioErr << "[CLogRotation - GetFileLogs] Finish5" << endl;
01228 #endif
01229
01230 return ERROR_LOGROTATION + ERROR_LOGFILES_LIST;
01231 }
01232 }
01233
01234 m_FileLogs.push_back( FileRecord );
01235 }
01236
01237 errno = 0;
01238
01239
01240
01241
01242 }
01243 if( errno != 0 )
01244 {
01245 RioErr << "CLogRotation::GetFileLogs erro ao ler uma entrada do "
01246 << "diretorio " << m_LogsFileDirectory << endl;
01247
01248 #ifdef RIO_DEBUG1
01249 RioErr << "[CLogRotation - GetFileLogs] Finish6" << endl;
01250 #endif
01251
01252 return ERROR_LOGROTATION + ERROR_DIRECTORY_READ_FAILED;
01253 }
01254
01255 closedir( LogsDir );
01256
01257
01258 sort( m_FileLogs.begin(), m_FileLogs.end(), CompareFileLogs );
01259
01260
01261
01262 if( m_FileLogs.empty() )
01263 m_MinLogTime = 0;
01264 else
01265 m_MinLogTime = m_FileLogs[ 0 ]->StartTime;
01266 #ifdef RIO_DEBUG2
01267
01268 RioErr << "CLogRotation::GetFileLogs lista com os arquivos: tamanho = "
01269 << m_FileLogs.size() << ":" << endl;
01270 for( unsigned int i = 0; i < m_FileLogs.size(); i++ )
01271 RioErr << "CLogRotation::GetFileLogs posicao " << i << " do vetor: "
01272 << "nome = " << m_FileLogs[ i ]->FileName << ", Tempo inicial = "
01273 << ( unsigned long ) m_FileLogs[ i ]->StartTime
01274 << ", Tempo Final = "
01275 << ( unsigned long ) m_FileLogs[ i ]->EndTime << endl;
01276 #endif
01277
01278 #ifdef RIO_DEBUG1
01279 RioErr << "[CLogRotation - GetFileLogs] Finish7" << endl;
01280 #endif
01281
01282 return S_OK;
01283 }
01284
01285
01286
01287
01288 int CLogRotation::CheckCombinedLogsSizes()
01289 {
01290
01291 unsigned long long int CombinedLogsSize;
01292
01293
01294 struct stat LogStat;
01295
01296 #ifdef RIO_DEBUG1
01297 RioErr << "[CLogRotation - CheckCombinedLogsSizes] Start" << endl;
01298 #endif
01299
01300 #ifdef RIO_DEBUG2
01301
01302 RioErr << "CLogRotation::CheckCombinedLogsSizes lista com os arquivos: "
01303 << "tamanho = " << m_FileLogs.size() << ":" << endl;
01304 for( unsigned int i = 0; i < m_FileLogs.size(); i++ )
01305 RioErr << "CLogRotation::CheckCombinedLogsSizes posicao " << i
01306 << " do vetor: nome = " << m_FileLogs[ i ]->FileName
01307 << ", Tempo inicial = "
01308 << ( unsigned long ) m_FileLogs[ i ]->StartTime
01309 << ", Tempo Final = "
01310 << ( unsigned long ) m_FileLogs[ i ]->EndTime << endl;
01311 #endif
01312
01313 CombinedLogsSize = 0;
01314 for( unsigned int i = 0; i < m_FileLogs.size(); i++ )
01315 {
01316
01317 if ( stat( m_FileLogs[ i ]->FileName, &LogStat ) < 0 )
01318 {
01319 RioErr << "CLogRotation::CheckCombinedLogsSizesI erro ao obter o "
01320 << "estado do arquivo de log " << m_FileLogs[ i ]->FileName
01321 << ": " << strerror( errno ) << " ( " << errno << ")"
01322 << endl;
01323
01324 #ifdef RIO_DEBUG1
01325 RioErr << "[CLogRotation - CheckCombinedLogsSizes] Finish1" << endl;
01326 #endif
01327
01328 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
01329 }
01330
01331 CombinedLogsSize = CombinedLogsSize + ( unsigned long long int )
01332 LogStat.st_size;
01333 }
01334
01335
01336
01337 if( CombinedLogsSize > m_MaxCombinedLogFilesSize )
01338 {
01339 RioErr << "CLogRotation::CheckCombinedLogsSizes o tamanho "
01340 << CombinedLogsSize << " do diretorio " << m_LogsFileDirectory
01341 << " com os logs passou do tamanho maximo de "
01342 << m_MaxCombinedLogFilesSize << ". Logs precisarao ser "
01343 << "removidos." << endl;
01344
01345
01346
01347 while( CombinedLogsSize > m_MaxCombinedLogFilesSize )
01348 {
01349
01350 if ( stat( m_FileLogs.front()->FileName, &LogStat ) < 0 )
01351 {
01352 RioErr << "CLogRotation::CheckCombinedLogsSizesII erro ao "
01353 << "obter o estado do arquivo de log "
01354 << m_FileLogs.front()->FileName << ": "
01355 << strerror( errno ) << " ( " << errno << ")" << endl;
01356
01357 #ifdef RIO_DEBUG1
01358 RioErr << "[CLogRotation - CheckCombinedLogsSizes] Finish2"
01359 << endl;
01360 #endif
01361
01362 return ERROR_LOGROTATION + ERROR_LOGFILE_OPEN_FAILED;
01363 }
01364
01365 CombinedLogsSize = CombinedLogsSize - ( unsigned long long int )
01366 LogStat.st_size;
01367 RioErr << "CLogRotation::CheckCombinedLogsSizes removendo o "
01368 << "arquivo " << m_FileLogs.front()->FileName << " com o "
01369 << " tamanho de " << LogStat.st_size << " bytes. Novo "
01370 << " tamanho do diretorio " << m_LogsFileDirectory
01371 << " com os logs e de " << CombinedLogsSize << endl;
01372
01373
01374
01375 if( m_FileLogs.front()->EndTime == 0 )
01376 {
01377 fclose( m_LogFileDescriptor );
01378 m_LogFileDescriptor = NULL;
01379 }
01380
01381 if( remove( m_FileLogs.front()->FileName ) < 0 )
01382 {
01383 RioErr << "CLogRotation::CheckCombinedLogsSizes erro ao "
01384 << "remover o arquivo " << m_FileLogs.front()->FileName
01385 << endl;
01386
01387 #ifdef RIO_DEBUG1
01388 RioErr << "[CLogRotation - CheckCombinedLogsSizes] Finish3"
01389 << endl;
01390 #endif
01391
01392 return ERROR_LOGROTATION + ERROR_LOGFILE_REMOVE_FAILED;
01393 }
01394
01395 m_FileLogs.erase( m_FileLogs.begin() );
01396 }
01397 }
01398 else if( CombinedLogsSize > ( unsigned long long int )
01399 ( PERCENTMAXCOMBINEDSIZE * ( double ) m_MaxCombinedLogFilesSize ) )
01400 {
01401 RioErr << "CLogRotation::CheckCombinedLogsSizes aviso: o tamanho "
01402 << CombinedLogsSize << " do diretorio " << m_LogsFileDirectory
01403 << " com os logs esta maior do que " << PERCENTMAXCOMBINEDSIZE
01404 << " vezes o valor do tamanho maximo "
01405 << m_MaxCombinedLogFilesSize << endl;
01406 }
01407
01408 #ifdef RIO_DEBUG1
01409 RioErr << "[CLogRotation - CheckCombinedLogsSizes] Finish4" << endl;
01410 #endif
01411
01412 return S_OK;
01413 }
01414
01415
01416
01417
01418
01419 bool CLogRotation::CompareFileLogs( LogFileRecord* x, LogFileRecord* y )
01420 {
01421
01422 #ifdef RIO_DEBUG1
01423 RioErr << "[CLogRotation - CompareFileLogs] Start" << endl;
01424 #endif
01425
01426 if( x->StartTime != y->StartTime )
01427 {
01428
01429 #ifdef RIO_DEBUG1
01430 RioErr << "[CLogRotation - CompareFileLogs] Finish1" << endl;
01431 #endif
01432
01433 return x->StartTime < y->StartTime;
01434 }
01435 else
01436 {
01437
01438 #ifdef RIO_DEBUG1
01439 RioErr << "[CLogRotation - CompareFileLogs] Finish2" << endl;
01440 #endif
01441
01442 return x->EndTime < y->EndTime;
01443 }
01444 }
01445
01446
01447
01448
01449 void *CLogRotation::RequestThread( void *Param )
01450 {
01451 bool SendSignal;
01452 CLogRotation *LogRotation;
01453 LogLine *line;
01454 SearchRecord *search;
01455 RequestRecord *request;
01456 LogRotation = ( CLogRotation * ) Param;
01457
01458 #ifdef RIO_DEBUG1
01459 RioErr << "[CLogRotation - RequestThread] Start" << endl;
01460 #endif
01461
01462 #ifdef RIO_DEBUG2
01463 RioErr << "REQUESTTHREADID " << syscall( SYS_gettid ) << endl;
01464 #else
01465 if( LogRotation->m_ServerInstance )
01466 RioErr << "REQUESTTHREADID " << syscall( SYS_gettid ) << endl;
01467 #endif
01468
01469
01470
01471
01472 while( 1 )
01473 {
01474
01475 pthread_mutex_lock( &LogRotation->m_MutexRequestQueue );
01476
01477
01478
01479
01480
01481 if( LogRotation->m_RequestQueue.empty() )
01482 {
01483
01484
01485 pthread_cond_wait( &LogRotation->m_CondRequestThread,
01486 &LogRotation->m_MutexRequestQueue );
01487
01488
01489 }
01490
01491 if( LogRotation->m_StopRequestThread )
01492 {
01493
01494
01495 pthread_mutex_unlock( &LogRotation->m_MutexRequestQueue );
01496
01497 #ifdef RIO_DEBUG1
01498 RioErr << "[CLogRotation - RequestThread] Finish1" << endl;
01499 #endif
01500
01501 pthread_exit( NULL );
01502 }
01503
01504
01505
01506
01507
01508
01509 request = LogRotation->RemoveRequestQueue();
01510
01511 pthread_mutex_unlock( &LogRotation->m_MutexRequestQueue );
01512 if( request != NULL )
01513 {
01514
01515 pthread_mutex_lock( &LogRotation->m_MutexProcessQueues );
01516
01517
01518
01519
01520 SendSignal = ( ( LogRotation->m_LogLineQueue.empty() ) &&
01521 ( LogRotation->m_SearchQueue.empty() ) );
01522 switch( request->Type )
01523 {
01524 case INSERT_LINE:
01525
01526
01527
01528 line = ( LogLine * ) request->Data;
01529 LogRotation->m_LogLineQueue.push( line );
01530 break;
01531 case EXECUTE_SEARCH:
01532
01533
01534
01535 search = ( SearchRecord * ) request->Data;
01536 LogRotation->m_SearchQueue.push( search );
01537 break;
01538 default:
01539 RioErr << "CLogRotation::RequestThread Recebido um tipo "
01540 << request->Type << " invalido de solicitacao"
01541 << endl;
01542
01543
01544 SendSignal = false;
01545 break;
01546 }
01547
01548
01549 if( SendSignal )
01550 pthread_cond_signal( &LogRotation->m_CondProcessThread );
01551
01552
01553 pthread_mutex_unlock( &LogRotation->m_MutexProcessQueues );
01554
01555
01556 delete request;
01557 }
01558 else
01559 RioErr << "CLogRotation::RequestThread erro ao obter uma "
01560 << "solicitacao da fila m_RequestQueue" << endl;
01561 }
01562
01563 #ifdef RIO_DEBUG1
01564 RioErr << "[CLogRotation - RequestThread] Finish2" << endl;
01565 #endif
01566
01567 return NULL;
01568 }
01569
01570
01571
01572
01573
01574
01575 void *CLogRotation::ProcessThread( void *Param )
01576 {
01577 CLogRotation *LogRotation;
01578 LogLine *line;
01579 SearchRecord *search;
01580 int erro;
01581 LogRotation = ( CLogRotation * ) Param;
01582
01583 #ifdef RIO_DEBUG1
01584 RioErr << "[CLogRotation - ProcessThread] Start" << endl;
01585 #endif
01586
01587 #ifdef RIO_DEBUG2
01588 RioErr << "PROCESSTHREADID " << syscall( SYS_gettid ) << endl;
01589 #else
01590 if( LogRotation->m_ServerInstance )
01591 RioErr << "PROCESSTHREADID " << syscall( SYS_gettid ) << endl;
01592 #endif
01593
01594
01595
01596 while( 1 )
01597 {
01598
01599 pthread_mutex_lock( &LogRotation->m_MutexProcessQueues );
01600
01601
01602
01603 if ( ( LogRotation->m_LogLineQueue.empty() ) &&
01604 ( LogRotation->m_SearchQueue.empty() ) )
01605 pthread_cond_wait( &LogRotation->m_CondProcessThread,
01606 &LogRotation->m_MutexProcessQueues );
01607
01608 if( LogRotation->m_StopProcessThread )
01609 {
01610
01611
01612 pthread_mutex_unlock( &LogRotation->m_MutexProcessQueues );
01613
01614 #ifdef RIO_DEBUG1
01615 RioErr << "[CLogRotation - ProcessThread] Finish1" << endl;
01616 #endif
01617
01618 pthread_exit( NULL );
01619 }
01620
01621
01622 while( !LogRotation->m_LogLineQueue.empty() )
01623 {
01624 line = LogRotation->RemoveLogLineQueue();
01625 if( line != NULL )
01626 {
01627
01628 erro = LogRotation->InsertLogLine( line );
01629
01630 delete line;
01631 if( erro != S_OK )
01632 RioErr << "CLogRotation::ProcessThread erro ao imprimir "
01633 << "uma linha do log (funcao InsertLogLine)" << endl;
01634 }
01635 else
01636 RioErr << "CLogRotation::ProcessThread erro ao obter uma linha "
01637 << "de log da fila m_LogLineQueue" << endl;
01638 }
01639
01640 if( !LogRotation->m_SearchQueue.empty() )
01641 {
01642
01643 search = LogRotation->RemoveSearchQueue();
01644
01645
01646 pthread_mutex_unlock( &LogRotation->m_MutexProcessQueues );
01647 if( search != NULL )
01648 {
01649
01650 erro = LogRotation->SearchLogs( search );
01651
01652 delete search;
01653 if( erro != S_OK )
01654 RioErr << "CLogRotation::ProcessThread erro ao executar "
01655 << "uma das buscas (funcao SearchLogs)" << endl;
01656 }
01657 else
01658 RioErr << "CLogRotation::ProcessThread erro ao obter um "
01659 << "registro de busca da fila m_SearchQueue" << endl;
01660 }
01661 else
01662
01663
01664 pthread_mutex_unlock( &LogRotation->m_MutexProcessQueues );
01665
01666
01667 erro = LogRotation->CheckCombinedLogsSizes();
01668 if( erro != S_OK )
01669 RioErr << "CLogRotation::ProcessThread erro ao verificar o tamanho "
01670 << "combinado dos arquivos de logs (funcao "
01671 << "CheckCombinedLogsSizes)" << endl;
01672 }
01673
01674 #ifdef RIO_DEBUG1
01675 RioErr << "[CLogRotation - ProcessThread] Finish2" << endl;
01676 #endif
01677
01678 return NULL;
01679 }
01680
01681
01682 int CLogRotation::Initialize( char *LogsFilePrefixPath,
01683 unsigned int MaxLogFileSize,
01684 unsigned long long int MaxCombinedLogFilesSize,
01685 bool SaveLogs )
01686 {
01687 int erro;
01688 char *EndDirPath;
01689
01690 #ifdef RIO_DEBUG1
01691 RioErr << "[CLogRotation - Initialize] Start" << endl;
01692 #endif
01693
01694
01695 pthread_attr_t attribRequestThread;
01696 pthread_attr_t attribProcessThread;
01697 if( !m_Initialized )
01698 {
01699
01700 if( strlen( LogsFilePrefixPath ) >
01701 ( MaxPathSize - MAXSIZESUFFIXFILELOG ) )
01702 {
01703 #ifdef RIO_DEBUG2
01704 RioErr << "CLogRotation::Initialize O nome do caminho "
01705 << LogsFilePrefixPath << "e muito grande" << endl;
01706 #endif
01707
01708 #ifdef RIO_DEBUG1
01709 RioErr << "[CLogRotation - Initialize] Finish1" << endl;
01710 #endif
01711
01712 return ERROR_LOGROTATION + ERROR_PATHNAME_TOOLARGE;
01713 }
01714
01715
01716 if( ( EndDirPath = strrchr( LogsFilePrefixPath, '/' ) ) != 0 )
01717 {
01718
01719 strncpy( m_LogsFileDirectory, LogsFilePrefixPath,
01720 EndDirPath - LogsFilePrefixPath + 1 );
01721
01722 m_LogsFileDirectory[ EndDirPath - LogsFilePrefixPath + 1 ] = 0;
01723
01724 strcpy( m_LogsFilePrefix, ++EndDirPath );
01725 }
01726 else
01727 {
01728
01729
01730
01731
01732
01733 strcpy( m_LogsFilePrefix, LogsFilePrefixPath );
01734
01735
01736 if( getcwd( m_LogsFileDirectory,
01737 sizeof( m_LogsFileDirectory ) - 2 ) == NULL )
01738 {
01739
01740 #ifdef RIO_DEBUG2
01741 RioErr << "CLogRotation::Initialize O nome do diretorio de "
01742 << "trabalho e muito grande" << endl;
01743 #endif
01744
01745 #ifdef RIO_DEBUG1
01746 RioErr << "[CLogRotation - Initialize] Finish2" << endl;
01747 #endif
01748
01749 return ERROR_LOGROTATION + ERROR_PATHNAME_TOOLARGE;
01750 }
01751 strcat( m_LogsFileDirectory, "/" );
01752 }
01753
01754 #ifdef RIO_DEBUG2
01755 RioErr << "CLogRotation::Initialize m_LogsFileDirectory = "
01756 << m_LogsFileDirectory << " e m_LogsFilePrefix = "
01757 << m_LogsFilePrefix << endl;
01758 #endif
01759
01760
01761
01762 m_MaxLogFileSize = MaxLogFileSize;
01763
01764
01765 if( MaxCombinedLogFilesSize < 2 * MaxLogFileSize )
01766 {
01767
01768 #ifdef RIO_DEBUG1
01769 RioErr << "[CLogRotation - Initialize] Finish3" << endl;
01770 #endif
01771
01772 return ERROR_LOGROTATION + ERROR_INVALID_PARAM;
01773 }
01774
01775
01776
01777
01778 m_MaxCombinedLogFilesSize = MaxCombinedLogFilesSize - MaxLogFileSize;
01779
01780 erro = GetFileLogs();
01781 if( erro != S_OK )
01782 {
01783
01784 #ifdef RIO_DEBUG2
01785 RioErr << "CLogRotation::Initialize erro ao executar a funcao "
01786 << "GetFileLogs" << endl;
01787 #endif
01788
01789 #ifdef RIO_DEBUG1
01790 RioErr << "[CLogRotation - Initialize] Finish4" << endl;
01791 #endif
01792
01793 return erro;
01794 }
01795
01796
01797
01798 m_StopRequestThread = false;
01799 m_StopProcessThread = false;
01800
01801
01802 m_SaveLogs = SaveLogs;
01803
01804
01805
01806
01807 pthread_attr_init( &attribRequestThread );
01808 pthread_attr_init( &attribProcessThread );
01809 pthread_attr_setstacksize( &attribRequestThread, 2*PTHREAD_STACK_MIN );
01810 pthread_attr_setstacksize( &attribProcessThread, 2*PTHREAD_STACK_MIN );
01811
01812 if ( pthread_create( &m_RequestThread, &attribRequestThread,
01813 RequestThread, this ) != 0 )
01814 {
01815
01816 #ifdef RIO_DEBUG2
01817 RioErr << "CLogRotation::Initialize erro ao criar a thread "
01818 << "RequestThread" << endl;
01819 #endif
01820
01821 #ifdef RIO_DEBUG1
01822 RioErr << "[CLogRotation - Initialize] Finish5" << endl;
01823 #endif
01824
01825 return ERROR_LOGROTATION + ERROR_CREATE_THREAD;
01826 }
01827 if ( pthread_create( &m_ProcessThread, &attribProcessThread,
01828 ProcessThread, this ) != 0 )
01829 {
01830 RioErr << "CLogRotation::Initialize erro ao criar a thread "
01831 << "ProcessThread" << endl;
01832 pthread_cancel( m_RequestThread );
01833
01834 #ifdef RIO_DEBUG1
01835 RioErr << "[CLogRotation - Initialize] Finish6" << endl;
01836 #endif
01837
01838 return ERROR_LOGROTATION + ERROR_CREATE_THREAD;
01839 }
01840
01841
01842 m_Initialized = true;
01843 }
01844 else
01845 {
01846
01847 #ifdef RIO_DEBUG2
01848 RioErr << "CLogRotation::Initialize o objeto ja foi inicializado"
01849 << endl;
01850 #endif
01851
01852 #ifdef RIO_DEBUG1
01853 RioErr << "[CLogRotation - Initialize] Finish7" << endl;
01854 #endif
01855
01856 return ERROR_LOGROTATION + ERROR_INITIALIZED;
01857 }
01858
01859 #ifdef RIO_DEBUG1
01860 RioErr << "[CLogRotation - Initialize] Finish8" << endl;
01861 #endif
01862
01863 return S_OK;
01864 }
01865
01866
01867 int CLogRotation::NewLogLine( time_t LogTime, char *LogInfo )
01868 {
01869 int erro;
01870 LogLine *line;
01871
01872 #ifdef RIO_DEBUG1
01873 RioErr << "[CLogRotation - NewLogLine] Start" << endl;
01874 #endif
01875
01876 if( m_Initialized )
01877 {
01878
01879
01880
01881 if( !m_SaveLogs )
01882 {
01883
01884 #ifdef RIO_DEBUG1
01885 RioErr << "[CLogRotation - NewLogLine] Finish1" << endl;
01886 #endif
01887
01888 return S_OK;
01889 }
01890
01891 if( strlen( LogInfo ) > MAXLOGLINESIZE )
01892 {
01893
01894 #ifdef RIO_DEBUG2
01895 RioErr << "CLogRotation::NewLogLine o tamanho "
01896 << strlen( LogInfo ) << " da linha de log \"" << LogInfo
01897 << "\" e muito grande. Deveria ser no maximo de "
01898 << MAXLOGLINESIZE << endl;
01899 #endif
01900
01901 #ifdef RIO_DEBUG1
01902 RioErr << "[CLogRotation - NewLogLine] Finish2" << endl;
01903 #endif
01904
01905 return ERROR_LOGROTATION + ERROR_LOGLINE_TOOLARGE;
01906 }
01907
01908 line = new LogLine;
01909 if( line == NULL )
01910 {
01911
01912 #ifdef RIO_DEBUG2
01913 RioErr << "CLogRotation::NewLogLine erro de alocacao de memoria ao "
01914 << "criar uma estrutura do tipo LogLine" << endl;
01915 #endif
01916
01917 #ifdef RIO_DEBUG1
01918 RioErr << "[CLogRotation - NewLogLine] Finish3" << endl;
01919 #endif
01920
01921 return ERROR_LOGROTATION + ERROR_MEMORY;
01922 }
01923
01924 line->LogTime = LogTime;
01925 strcpy( line->LogInfo, LogInfo );
01926
01927
01928 erro = NewRequest( INSERT_LINE, ( void * ) line );
01929 if( erro != S_OK )
01930 {
01931
01932 #ifdef RIO_DEBUG2
01933 RioErr << "CLogRotation::NewLogLine erro ao executar a funcao "
01934 << "NewRequisition" << endl;
01935 #endif
01936
01937 #ifdef RIO_DEBUG1
01938 RioErr << "[CLogRotation - NewLogLine] Finish4" << endl;
01939 #endif
01940
01941 return erro;
01942 }
01943
01944 #ifdef RIO_DEBUG1
01945 RioErr << "[CLogRotation - NewLogLine] Finish5" << endl;
01946 #endif
01947
01948 return S_OK;
01949 }
01950 else
01951 {
01952
01953 #ifdef RIO_DEBUG2
01954 RioErr << "CLogRotation::NewLogLine o objeto nao foi inicializado"
01955 << endl;
01956 #endif
01957
01958 #ifdef RIO_DEBUG1
01959 RioErr << "[CLogRotation - NewLogLine] Finish6" << endl;
01960 #endif
01961
01962 return ERROR_LOGROTATION + ERROR_NOT_INITIALIZED;
01963 }
01964 }
01965
01966
01967
01968 int CLogRotation::SearchLogFiles( char *SearchFileName, time_t StartTime,
01969 time_t EndTime, callback_log callback,
01970 void *callbackparam )
01971 {
01972 int erro;
01973 SearchRecord *search;
01974
01975 #ifdef RIO_DEBUG1
01976 RioErr << "[CLogRotation - SearchLogFiles] Start" << endl;
01977 #endif
01978
01979 if( m_Initialized )
01980 {
01981
01982 if( strlen( SearchFileName ) >= MaxPathSize )
01983 {
01984
01985 #ifdef RIO_DEBUG2
01986 RioErr << "CLogRotation::SearchLogFiles O tamanho do nome do "
01987 << "caminho " << SearchFileName << " do arquivo de saida "
01988 << "e muito grande (maior do que " << MaxPathSize << ")"
01989 << endl;
01990 #endif
01991
01992 #ifdef RIO_DEBUG1
01993 RioErr << "[CLogRotation - SearchLogFiles] Finish1" << endl;
01994 #endif
01995
01996 return ERROR_LOGROTATION + ERROR_PATHNAME_TOOLARGE;
01997 }
01998
01999 search = new SearchRecord;
02000 if( search == NULL )
02001 {
02002
02003 #ifdef RIO_DEBUG2
02004 RioErr << "CLogRotation::SearchLogFiles erro de alocacao de memoria"
02005 << " ao criar uma estrutura do tipo SearchRecord" << endl;
02006 #endif
02007
02008 #ifdef RIO_DEBUG1
02009 RioErr << "[CLogRotation - SearchLogFiles] Finish2" << endl;
02010 #endif
02011
02012 return ERROR_LOGROTATION + ERROR_MEMORY;
02013 }
02014
02015 strcpy( search->SearchFileName, SearchFileName );
02016 search->StartTime = StartTime;
02017 search->EndTime = EndTime;
02018 search->callback = callback;
02019 search->callbackparam = callbackparam;
02020
02021
02022 erro = NewRequest( EXECUTE_SEARCH, ( void * ) search );
02023 if( erro != S_OK )
02024 {
02025
02026 #ifdef RIO_DEBUG2
02027 RioErr << "CLogRotation::SearchLogFiles erro ao executar a funcao "
02028 << "NewRequisition" << endl;
02029 #endif
02030
02031 #ifdef RIO_DEBUG1
02032 RioErr << "[CLogRotation - SearchLogFiles] Finish3" << endl;
02033 #endif
02034
02035 return erro;
02036 }
02037
02038 #ifdef RIO_DEBUG1
02039 RioErr << "[CLogRotation - SearchLogFiles] Finish4" << endl;
02040 #endif
02041
02042 return S_OK;
02043 }
02044 else
02045 {
02046
02047 #ifdef RIO_DEBUG2
02048 RioErr << "CLogRotation::SearchLogFiles o objeto nao foi inicializado"
02049 << endl;
02050 #endif
02051
02052 #ifdef RIO_DEBUG1
02053 RioErr << "[CLogRotation - SearchLogFiles] Finish5" << endl;
02054 #endif
02055
02056 return ERROR_LOGROTATION + ERROR_NOT_INITIALIZED;
02057 }
02058 }
02059
02060
02061 time_t CLogRotation::MinLogTime( void )
02062 {
02063 time_t MinTime;
02064
02065 #ifdef RIO_DEBUG1
02066 RioErr << "[CLogRotation - MinLogTime] Start" << endl;
02067 #endif
02068
02069
02070
02071
02072
02073
02074 pthread_mutex_lock( &m_MutexMinLogTime );
02075 MinTime = m_MinLogTime;
02076
02077 pthread_mutex_unlock( &m_MutexMinLogTime );
02078
02079 #ifdef RIO_DEBUG1
02080 RioErr << "[CLogRotation - MinLogTime] Finish" << endl;
02081 #endif
02082
02083 return MinTime;
02084 }