CLogRotation Class Reference

Classe que implementa o controle da geracao de um conjunto de logs. More...

#include <LogRotation.h>

Public Member Functions

 CLogRotation (bool ServerInstance=true)
 Construtor da classe.
virtual ~CLogRotation ()
 Destrutor da classe.
virtual int Initialize (char *LogsFilePrefixPath, unsigned int MaxLogFileSize, unsigned long long int MaxCombinedLogFilesSize, bool SaveLogs=true)
 Funcao usada para inicializar um objeto da classe CLogRotation.
virtual int NewLogLine (time_t LogTime, char *LogInfo)
 Funcao para criar uma nova solicitacao de impressao de uma linha no log.
virtual int SearchLogFiles (char *SearchFileName, time_t StartTime, time_t EndTime, callback_log callback, void *callbackparam)
 Funcao para criar uma nova solicitacao de busca nos arquivos de log.
virtual time_t MinLogTime (void)
 Retorna o tempo do primeira linha salva nos arquivos de log.

Private Member Functions

RequestRecordRemoveRequestQueue (void)
 Funcao para obter e remover o primeiro elemento da fila m_RequestQueue.
LogLineRemoveLogLineQueue (void)
 Funcao para obter e remover o primeiro elemento da fila m_LogLineQueue.
SearchRecordRemoveSearchQueue (void)
 Funcao para obter e remover o primeiro elemento da fila m_SearchQueue.
void DeleteRequestQueue ()
 Funcao para remover os elementos da fila m_RequuestQueue, salvando todos os registros que apontem para logs.
void DeleteLogLineQueue ()
 Funcao para remover os elementos da fila m_LogLineQueue,salvando todas as linhas de log, na ordem dada pela fila, no arquivo atual com os logs.
void DeleteSearchQueue ()
 Funcao para remover os elementos da fila m_SearchQueue.
int NewRequest (unsigned short Type, void *Data)
 Cria uma nova solicitacao (de impressao ou de busca) e a coloca no final da fila m_RequestQueue.
int InsertLogLine (LogLine *line)
 Funcao para inserir uma linha no arquivo de log.
int SearchLogs (SearchRecord *Record)
 Funcao para buscar, nos arquivos de logs, os tempos definidos pelo ponteiro para a estrutura Record.
int GetTimeStamp (char *FileName, time_t *StartTime, time_t *EndTime)
 Funcao para determinar, a partir do nome de arquivo passado como parametro, o tempo neste nome de arquivo.
int GetFileLogs ()
 Funcao para preencher o vetor m_FileLogs com os nomes dos arquivos de log (que possuem o prefixo m_LogsFilePrefix) do diretorio dado em m_LogsFileDirectory).
int CheckCombinedLogsSizes ()
 Verifica se o tamanho combinado de todos os logs passou o tamanho maximo dado em m_MaxCombinedLogFilesSize.

Static Private Member Functions

static bool CompareFileLogs (LogFileRecord *x, LogFileRecord *y)
 Compara duas estrutoras do tipo LogFileRecord.
static void * RequestThread (void *Param)
 Funcao que implementa a thread que separa as solicitacoes da fila m_RequestQueue nas filas de impressao de logs (m_LogLineQueue) e execucao das buscas (m_SearchQueue), usadas pela thread ProcessThread.
static void * ProcessThread (void *Param)
 Funcao que implementa a thread que processa as solicitacoes de impressao de logs colocadas na fila m_LogLineQueue e as buscas colocadas na fila m_SearchQueue.

Private Attributes

bool m_Initialized
 Variavel booleana que indica se a classe foi inicializada.
bool m_StopRequestThread
 Variavel booleana usada para sabermos se devemos terminar a thread RequestThread.
bool m_StopProcessThread
 Variavel booleana usada para sabermos se devemos terminar a thread ProcessThread.
bool m_SaveLogs
 Variavel booleana indicando se a linha de log passada a funcao InsertLogLine deve ser salva nos logs, isto e, se esta variavel for false, a classe somente fara buscas nos logs, e a funcao InsertLogLine retornara imediatamente, sem salvar esta linha nos logs.
char m_LogsFileDirectory [MaxPathSize]
 Caminho do diretorio onde estao os logs.
char m_LogsFilePrefix [MaxPathSize]
 Prefixo dos nomes dos arquivos.
FILE * m_LogFileDescriptor
 Descritor para o arquivo de log atualmente usado.
FileLogs m_FileLogs
 Vetor com os nomes dos arquivos de log, ordenados pelo tempo do primeiro log do arquivo.
unsigned int m_MaxLogFileSize
 Tamanho maximo para o arquivo de log (antes de ser compactado).
unsigned long long int m_MaxCombinedLogFilesSize
 Tamanho maximo usado por todos os logs de um objeto da classe LogRotation.
time_t m_MinLogTime
 Menor tempo disponivel no log.
pthread_mutex_t m_MutexMinLogTime
 Mutex para garantir o acesso exclusivo a variavel m_MinLogTime.
RequestQueue m_RequestQueue
 Fila com as solicitacoes de entrada (necessaria para que a geracao dos logs e as buscas nao atrase as threads que imprimem no log ou fazem buscas).
pthread_mutex_t m_MutexRequestQueue
 Mutex para garantir a exclusao mutual ao acessar a fila m_RequisitionRecordQueue.
LogLineQueue m_LogLineQueue
 Fila com as solicitacoes de impressao de logs no arquivo de log atual (nao compactado).
SearchQueue m_SearchQueue
 Fila com as solicitacoes de buscas.
pthread_mutex_t m_MutexProcessQueues
 Mutex para garantir acesso exclusivo as filas m_LogLineQueue e m_SearchQueue.
pthread_cond_t m_CondRequestThread
 Variavel de condicao usada para bloquear a thread que recebe as solicitacoes externas (de impressao de linhas de log ou de buscas).
pthread_cond_t m_CondProcessThread
 Variavel de condicao usada para bloquear a thread que imprime as linhas de log e faz as buscas, caso nao existam linha a serem impressas e buscas a serem executadas.
pthread_t m_RequestThread
 Identificador da thread que recebe as solicitacoes de entrada (impressao do log e as buscas) e as coloca nas filas m_LogLineQueue ou m_SearchQueue de acordo com o tipo de solicitacao (impressao ou busca), para serem processadas pela thread ProcessThread.
pthread_t m_ProcessThread
 Identificador da thread que processa as solicitacoes, ou seja, as impressoes no log atualmente usado (o nao compactado) e as buscas nos arquivos de logs.
bool m_ServerInstance
 Nova variavel usada para indicar se o objeto da classe esta associado a um dos servidores ou a um cliente.

Detailed Description

Classe que implementa o controle da geracao de um conjunto de logs.

Definition at line 152 of file LogRotation.h.


Constructor & Destructor Documentation

CLogRotation::CLogRotation ( bool  ServerInstance = true  ) 

Construtor da classe.

Parameters:
ServerInstance novo parametro usado para indicar se o objeto da classe esta associado a um servidor ou a um cliente (o novo parametro possui a opcao default de true para manter compatibilidade com a versao anterior da classe).

Definition at line 21 of file LogRotation.cpp.

00022 {
00023     #ifdef RIO_DEBUG1
00024     RioErr << "[CLogRotation - Construtor] Start" << endl;
00025     #endif
00026 
00027     // Inicializa a variavel que informa se o objeto esta associado a um cliente
00028     // ou a um servidor.
00029     m_ServerInstance = ServerInstance;
00030     // A classe deve comecar nao inicializada.
00031     m_Initialized = false;
00032     // Inicializa os identificadores das threads.
00033     m_RequestThread = 0;
00034     m_ProcessThread = 0;
00035     // Inicializa o tamanho maximo do arquivo.
00036     m_MaxLogFileSize = 0;
00037     m_MaxCombinedLogFilesSize = 0;
00038     // Inicializa as strings da classe com a string vazia.
00039     m_LogsFileDirectory[0] = 0;
00040     m_LogsFilePrefix[0] = 0;
00041     // Inicializa o tempo do menor log armazenado nos arquivos de log.
00042     m_MinLogTime = 0;
00043     // Esta variavel e inicialmente true, pois caso nao existam logs no 
00044     // diretorio ou todos estejam compactados, ela deve ser true para garantir
00045     // que a proxima insercao de uma informacao no log crie um novo arquivo.
00046     // O descritor e inicializado com -1, para indicar que o arquivo ainda nao
00047     // foi aberto.
00048     m_LogFileDescriptor = NULL;
00049     // Inicializa os mutexes e as variaveis de condicao.
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     // Inicializa as variaveis booleanas que indicam que devemos parar as 
00056     // threads RequestThread e ProcessThread com false, pois vamos criar as
00057     // threads.
00058     m_StopRequestThread = false;
00059     m_StopProcessThread = false;
00060     // Inicializa a variavel usada para saber se devemos ou nao salvar a linha
00061     // nos logs. Por default, supomos que as linhas nao devem ser salvas (pois
00062     // a classe ainda nao foi inicializada).
00063     m_SaveLogs = false;
00064 
00065     #ifdef RIO_DEBUG1
00066     RioErr << "[CLogRotation - Construtor] Finish" << endl;
00067     #endif
00068 }

CLogRotation::~CLogRotation (  )  [virtual]

Destrutor da classe.

Definition at line 71 of file LogRotation.cpp.

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         // Termina a thread que trata as requisicoes da fila de entrada.
00083         if( m_RequestThread != 0 )
00084         {
00085             // Informa a thread RequestThread que ela deve finalizar a sua
00086             // execucao.
00087             m_StopRequestThread = true;
00088             // Envia um sinal para a thread, caso ela esteja bloqueada esperando
00089             // por elementos serem colocados na fila m_RequestQueue.
00090             pthread_cond_signal( &m_CondRequestThread );
00091             // Espera que a thread retorne
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         // Termina a thread que trata das filas de impressao e de busca.
00102         if( m_ProcessThread != 0 )
00103         {
00104             // Informa a thread ProcessThread que ela deve finalizar a sua
00105             // execucao.
00106             m_StopProcessThread = true;
00107             // Envia um sinal para a thread, caso ela esteja bloqueada esperando
00108             // por elementos serem colocados nas filas m_LogLineQueue ou 
00109             // m_SearchQueue.
00110             pthread_cond_signal( &m_CondProcessThread );
00111             // Espera que a thread retorne
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         // Remove as filas, salvando os logs, se necessario.
00122         DeleteSearchQueue(); 
00123         DeleteLogLineQueue(); 
00124         // Esta classe precisa ser a ultima a ser removida, para garantir a
00125         // ordem dos logs no arquivo atual com os logs.
00126         DeleteRequestQueue(); 
00127         
00128         // Fecha o arquivo atual de log, se ele ainda estiver aberto.
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         // Remove o vetor com os arquivos. Este vetor precisa ser a ultima a 
00139         // ser removida, pois o salvamento de linhas no log pode alterar o 
00140         // vetor.
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 }


Member Function Documentation

int CLogRotation::CheckCombinedLogsSizes (  )  [private]

Verifica se o tamanho combinado de todos os logs passou o tamanho maximo dado em m_MaxCombinedLogFilesSize.

Se isso ocorrer, os logs mais antigos serao removidos ate que o tamanho passe a ser menor do que o maximo. A funcao enviara avisos para a stderr (via RioErr) quando o tamanho passar de PERCENTMAXCOMBINEDSIZE do valor maximo.

Returns:
S_OK se a vefiricacao foi feita com sucesso, e um valor diferente de S_OK em caso contrario.

Definition at line 1288 of file LogRotation.cpp.

01289 {
01290     // Variavel que armazena a soma dos tamanhos dos arquivos logs.
01291     unsigned long long int CombinedLogsSize;
01292     // Estrutura usada para obter as informacoes sobre o arquivo atualmente
01293     // avaliado (necessaria para obtermos o tamanho do arquivo).
01294     struct stat LogStat;
01295 
01296     #ifdef RIO_DEBUG1
01297     RioErr << "[CLogRotation - CheckCombinedLogsSizes] Start" << endl;
01298     #endif
01299 
01300     #ifdef RIO_DEBUG2
01301     // Imprime a lista com os arquivos.
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     // Computa a soma de todos os arquivos com os logs.
01313     CombinedLogsSize = 0;
01314     for( unsigned int i = 0; i < m_FileLogs.size(); i++ )
01315     {
01316         // Obtem o tamanho do arquivo atualmente avaliado.
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         // Soma o tamanho do arquivo ao tamanho total.
01331         CombinedLogsSize = CombinedLogsSize + ( unsigned long long int ) 
01332                                               LogStat.st_size;
01333     }
01334     // Verifica se o tamanho passou do maximo, e neste caso, comeca a remover
01335     // os arquivos (a partir do primeiro), ate que o tamanho deixe de ser
01336     // maior do que o maximo.
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         // Remove o primeiro arquivo atualmente no vetor (o mais antigo) ate
01345         // que o tamanho combinado deixe de ser maior do que 
01346         // m_MaxCombinedLogFilesSize
01347         while( CombinedLogsSize > m_MaxCombinedLogFilesSize )
01348         {
01349             // Obtem o tamanho do primeiro arquivo do vetor.
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             // Remove o tamanho do primeiro arquivo do tamanho combinado.
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             // Verifica se o registro a ser removido e o arquivo atual com os 
01373             // logs, pois neste caso, precisamos fechar o arquivo e invalidar o 
01374             // indicador.
01375             if( m_FileLogs.front()->EndTime == 0 )
01376             {
01377                 fclose( m_LogFileDescriptor );
01378                 m_LogFileDescriptor = NULL;
01379             }
01380             // Remove o primeiro arquivo da lista e do sistema de arquivos.
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             // Remove o registro do vetor.
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 } 

bool CLogRotation::CompareFileLogs ( LogFileRecord x,
LogFileRecord y 
) [static, private]

Compara duas estrutoras do tipo LogFileRecord.

A comparacao e baseada nos campos StartTime e EndTime.

Parameters:
x ponteiro para a primeira estrutura do tipo LogFileRecord.
y ponteiro para a primeira estrutura do tipo LogFileRecord.
Returns:
true se o campo StartTime de x for menor do que o campo StartTime de y ou, se estes campos forem identicos, se o campo EndTime de x for menor do que o campo Endtime de y.

Definition at line 1419 of file LogRotation.cpp.

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 // Se os tempos iniciais forem iguais, usamos os finais.
01436     {
01437 
01438         #ifdef RIO_DEBUG1
01439         RioErr << "[CLogRotation - CompareFileLogs] Finish2" << endl;
01440         #endif
01441         
01442         return x->EndTime < y->EndTime;
01443     }
01444 }

void CLogRotation::DeleteLogLineQueue (  )  [private]

Funcao para remover os elementos da fila m_LogLineQueue,salvando todas as linhas de log, na ordem dada pela fila, no arquivo atual com os logs.

Definition at line 273 of file LogRotation.cpp.

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 }

void CLogRotation::DeleteRequestQueue (  )  [private]

Funcao para remover os elementos da fila m_RequuestQueue, salvando todos os registros que apontem para logs.

Definition at line 222 of file LogRotation.cpp.

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         //cerr << "c: " << m_RequestQueue.size() << endl;
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         // Se o tipo da solicitacao for um log, a insere no arquivo de log. As
00242         // solicitacoes de busca serao ignoradas e removidas do log
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 }

void CLogRotation::DeleteSearchQueue (  )  [private]

Funcao para remover os elementos da fila m_SearchQueue.

As buscas pendentes serao ignoradas.

Definition at line 303 of file LogRotation.cpp.

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 }

int CLogRotation::GetFileLogs (  )  [private]

Funcao para preencher o vetor m_FileLogs com os nomes dos arquivos de log (que possuem o prefixo m_LogsFilePrefix) do diretorio dado em m_LogsFileDirectory).

Definition at line 1111 of file LogRotation.cpp.

01112 {
01113     // Ponteiro para uma estrutura com as informacoes do diretorio aberto.
01114     DIR *LogsDir;
01115     // Ponteiro para uma estrutura com as informacoes de um dos arquivos do 
01116     // diretorio.
01117     struct dirent *File;
01118     // Variaveis para armazenar os tempos extraidos do nome do arquivo.
01119     time_t StartTime, EndTime;
01120     // Variavel para armazenar os erros.
01121     int erro;
01122     // Novo registro para um novo arquivo de log lido do diretorio.
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     // Le as entradas do diretorio ate que todas tenham sido avaliadas.
01142     while ( ( File = readdir( LogsDir ) ) != NULL )
01143     {
01144         // Verifica se o arquivo atual e um dos arquivos de log.
01145         if( strstr( File->d_name, m_LogsFilePrefix ) == File->d_name )
01146         {
01147             // O nome do arquivo atual tem m_LogsFilePrefix como prefixo.
01148             // Vamos agora verificar se ele e um dos arquivos compactados, 
01149             // ou o arquivo de log, cujo nome desejamos obter. Isso sera
01150             // feito a partir do tempo final, que e 0 para o arquivo de 
01151             // log nao compactado.
01152             // Cria um novo registro para este arquivo de log no vetor.
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             // Copia o nome do arquivo (completo) para o registro. O camimho do
01168             // diretorio m_LogsFileDirectory ja possui uma "/" ao seu final.
01169             strcpy( FileRecord->FileName, m_LogsFileDirectory );
01170             strcat( FileRecord->FileName, File->d_name );
01171             // Determina o tempo inicial das linhas do log do arquivo 
01172             // a partir do seu nome.
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                 // Se o tempo final for 0, entao o arquivo e o arquivo com
01194                 // os logs nao compactado (o que este sendo usado para 
01195                 // armazenar os logs).
01196                 // Achamos o nome do arquivo que desejamos.
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                     // Se ja achamos o arquivo antes, temos um erro de 
01218                     // implementacao na classe
01219                     // Fecha o diretorio.
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             // Adiciona o registro do arquivo no final do vetor.
01234             m_FileLogs.push_back( FileRecord );
01235         }
01236         
01237         errno = 0; // Reseta o erro caso a funcao strstr ao a insercao em
01238                    // m_FileLogs nao preserve errno. Isso e para verificarmos,
01239                    // apos o final deste laco, se ele terminou devido a um 
01240                    // erro ou devido a termos lido todas as entradas do 
01241                    // diretorio.
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     // Fecha o diretorio.
01255     closedir( LogsDir );
01256     // Ordena o vetor com os nomes dos logs, de acordo com os tempos inicial
01257     // e final (que somente sera usado se dois tempos iniciais forem iguais).
01258     sort( m_FileLogs.begin(), m_FileLogs.end(), CompareFileLogs );
01259     // Inicializa o campo tempo inicial dos logs com o valor do tempo inicial
01260     // do arquivo com os logs mais antigos (que deve agora estar na primeira
01261     // posicao do vetor, se o vetor nao estiver vazio).
01262     if( m_FileLogs.empty() )
01263         m_MinLogTime = 0;    
01264     else
01265         m_MinLogTime = m_FileLogs[ 0 ]->StartTime;
01266     #ifdef RIO_DEBUG2
01267     // Imprime a lista com os arquivos.
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 }

int CLogRotation::GetTimeStamp ( char *  FileName,
time_t *  StartTime,
time_t *  EndTime 
) [private]

Funcao para determinar, a partir do nome de arquivo passado como parametro, o tempo neste nome de arquivo.

Parameters:
FileName ponteiro para o nome do arquivo. O arquivo deve estar no formato [prefixo].[tempo_inicial]-[tempo_final], podendo ter, ao final do nome, a extensao opcional ".gz" (quando estiver compactado).
StartTime ponteiro para o valor do tipo time_t onde sera retornado o tempo inicial extraido do nome do arquivo.
EndTime ponteiro para o valor do tipo time_t onde sera retornado o tempo final extraido do nome do arquivo.
Returns:
S_OK se os tempos foram obtidos com sucesso do none do arquivo (que deve estar no formato acima, o valor diferente de S_OK em caso de erro).

Definition at line 1056 of file LogRotation.cpp.

01058 {
01059     char *StartTimeStamp, *StrAux;
01060 
01061     #ifdef RIO_DEBUG1
01062     RioErr << "[CLogRotation - GetTimeStamp] Start" << endl;
01063     #endif
01064 
01065     // Procura pelo primeiro "." no nome passado como parametro.
01066     StartTimeStamp = strrchr( FileName, '.' );
01067     if( strcasecmp( StartTimeStamp, ".gz" ) == 0 )
01068     {
01069         // Se o arquivo termina com .gz, procura pelo "." anterior.
01070         StrAux = StartTimeStamp;
01071         StrAux[ 0 ] = 0;
01072         StartTimeStamp = strrchr( FileName, '.' );
01073         StrAux[ 0 ] = '.';
01074     }
01075     if( StartTimeStamp != NULL )
01076     {
01077         StartTimeStamp++; // Move o ponteiro para o caractere apos o "."
01078         // Extrai os tempos do nome do arquivo. O nome do arquivo possui o 
01079         // formato <prefixo>.<tempo_inicial>-<tempo_final>[.gz].
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             // Se nao lemos dois valores, existe um erro no formato do nome do 
01086             // arquivo.
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 }

int CLogRotation::Initialize ( char *  LogsFilePrefixPath,
unsigned int  MaxLogFileSize,
unsigned long long int  MaxCombinedLogFilesSize,
bool  SaveLogs = true 
) [virtual]

Funcao usada para inicializar um objeto da classe CLogRotation.

O objeto deve estar inicializado para podermos usar as funcoes NewLogLine e SearchLogFiles (caso o objeto nao esteja inicializado, e retornado o erro ERROR_LOGROTATION + ERROR_NOT_INITIALIZED).

Parameters:
LogsFilePrefixPath nome do caminho do prefixo para os arquivos de log. Este caminho deve incluir, alem do prefixo, o nome do diretorio onde os logs serao armazenados. Por exemplo, o parametro "/home/xandao/TesteLogs" indica que os logs serao armazenados no diretorio "/home/xandao", com nomes com o prefixo de "TesteLogs".
MaxLogFileSize tamanho maximo que o arquivo de log deve ter. Quando o tamanho passar do tamanho maximo, o arquivo de log sera compactado e um novo arquivo de log (com o prefixo dado) sera criado.
MaxCombinedLogFilesSize valor maximo para o tamanho combinado dos arquivos com os logs.
SaveLogs novo parametro booleano, com valor default de true, que indica se devemos salvar a linha do log passada a funcao NewLogLine nos logs. Caso este parametro seja false, a funcao NewLogLine sempre retornara sem fazer nada, ou seja, sem salvar a linha passada como parametro nos logs.
Returns:
S_OK se a inicializacao foi feita com sucesso, e um valor diferente de S_OK em caso contrario.

Definition at line 1682 of file LogRotation.cpp.

01686 {
01687     int erro;
01688     char *EndDirPath;
01689 
01690     #ifdef RIO_DEBUG1
01691     RioErr << "[CLogRotation - Initialize] Start" << endl;
01692     #endif
01693 
01694     // Atributos para as threads criadas pela classe.
01695     pthread_attr_t attribRequestThread;
01696     pthread_attr_t attribProcessThread;
01697     if( !m_Initialized ) 
01698     {
01699         // Verifica se o nome do caminho e valido.
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         // Procura pelo final do nome do caminho do diretorio do arquivo dado 
01715         // pelo ponteiro LogsFilePrefixPath.
01716         if( ( EndDirPath = strrchr( LogsFilePrefixPath, '/' ) ) != 0 )
01717         {
01718             // Inicializa o nome do caminho do diretorio com o diretorio.
01719             strncpy( m_LogsFileDirectory, LogsFilePrefixPath, 
01720                      EndDirPath - LogsFilePrefixPath + 1 );
01721             // Adiciona o terminador ao caminho do diretorio.
01722             m_LogsFileDirectory[ EndDirPath - LogsFilePrefixPath + 1 ] = 0;
01723             // Inicializa o nome do prefixo com o prefixo.
01724             strcpy( m_LogsFilePrefix, ++EndDirPath );
01725         } 
01726         else 
01727         {
01728             // Neste caso, vamos armazenar os arquivos no diretorio atual.
01729             // Como o arquivo nao tem um nome de caminho, vamos somente o
01730             // nome do prefixo com uma copia de LogsFilePrefixPath, pois o 
01731             // nome do diretorio ja e inicializado, no construtor da classe,
01732             // com a string vazia.
01733             strcpy( m_LogsFilePrefix, LogsFilePrefixPath );
01734             // Inicializa, neste caso, o diretorio dos logs com o diretorio de
01735             // trabalho.
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         // Inicializa o campo com o tamanho maximo do log principal antes de
01761         // precisarmos compacta-lo.
01762         m_MaxLogFileSize = MaxLogFileSize;
01763         // Verifica se existe espaco suficiente para pelo menos dois logs (o
01764         // compactado e o espaco temporario para compactar os logs)
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         // Inicializa o campo com o tamanho maximo combinado dos logs da classe.
01775         // Note que precisamos reservar o espaco de um log para podermos ter
01776         // espaco suficiente para compactar o log atual (supomos aqui, que o
01777         // arquivo compactado nunca sera maior do que o arquivo original).
01778         m_MaxCombinedLogFilesSize = MaxCombinedLogFilesSize - MaxLogFileSize;
01779         // Preenche o vetor com os arquivos de logs.
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         // Inicializa as variaveis booleanas que indicam que devemos parar as
01796         // threads RequestThread e ProcessThread com false, pois vamos criar as
01797         // threads.
01798         m_StopRequestThread = false;
01799         m_StopProcessThread = false;
01800         // Inicializa a nova variavel que indica se a linha de log passada a
01801         // funcao NewLogLine deve ou nao ser salva nos logs.
01802         m_SaveLogs = SaveLogs;
01803         // Procura, no diretorio com os logs, o arquivo que esta atualmente
01804         // sendo usado (este arquivo sera o unico com o prefixo nao compactado).
01805         // Primeiramente tenta abrir o diretorio.
01806         // Cria as threads da classe.
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         // Cria as threads usadas pela classe.
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         // Muda o valor da variavel booleana que indica que a classe foi 
01841         // inicializada para true.
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 }

int CLogRotation::InsertLogLine ( LogLine line  )  [private]

Funcao para inserir uma linha no arquivo de log.

Parameters:
line informacoes (tempo, string) da linha a ser armazenada no log. Depois de escrever a linha, se o arquivo de log passar do tamanho maximo m_MaxLogFileSize, este arquivo sera compactado. Obs: se um arquivo de log nao compactado existir (o que ocorrera quando o primeiro arquivo de log for criado ou quando acabamos, na chamada anterior desta funcao, de compactar o log atual), este arquivo sera criado. Isso nao pode ser feito antes (por exemplo, apos compactar os logs), pois somente agora sabemos o tempo inicial do arquivo, que sera o tempo da linha de log que estamos salvando no arquivo.
Returns:
S_OK se as informacoes foram armazenadas no arquivo com sucesso, ou um valor diferente de S_OK em caso contrario.

Definition at line 397 of file LogRotation.cpp.

00398 {
00399     // Estrutura usada para obter as informacoes sobre o arquivo atual com os
00400     // logs (necessaria para verificarmos se precisamos compactar o arquivo).
00401     struct stat LogStat;
00402     // Identificador para a versao nao compactada do arquivo atual com os logs,
00403     // usado ao compactarmos este arquivo.
00404     int LogFile;
00405     // Identificador para a versao compactada do arquivo atual com os logs.
00406     gzFile ZipFile; 
00407     // Novo registro para um novo arquivo de log, se for necessario criarmos
00408     // um novo log, ou para o log usado atualmente, em caso contrario.
00409     LogFileRecord *FileRecord;
00410     // Variaveis temporarias usadas ao compactarmos o arquivo atual de logs.
00411     // NumRead - contem o numero de bytes lidos do log.
00412     // NumWrite - contem o numero de bytes salvos com sucesso no arquivo 
00413     // compactado (este valor nao e o numero de bytes realmente salvos, e sim o 
00414     // numero de bytes que foram compactados e salvos com sucesso).
00415     // CompacLogsFileName - nome do arquivo compactado (o nome do caminho do 
00416     // diretorio com os logs + o nome do arquivo atual de log + ".gz").
00417     // Buffer - Buffer temporario usado para compactaro arquivo de log.
00418     int NumRead, NumWrite;
00419     char CompacLogsFileName[ MaxPathSize ];
00420     char Buffer[ BUFFERCOMPACSIZE ];
00421     // String usada para armazenar a linha de log a ser impressa. Esta string
00422     // e usado para limitar o tamanho maximo da linha do log.
00423     //char StrLogLine[ MAXLOGLINESIZE + MAXTIMESTRSIZE ];
00424     // Variavel com o erro ocorrido nas operacoes da funcao.
00425     int erro;
00426     
00427     #ifdef RIO_DEBUG1
00428     RioErr << "[CLogRotation - InsertLogLine] Start" << endl;
00429     #endif
00430 
00431     // Verifica se e necessario criar um novo arquivo de log. Isso ocorrera se
00432     // m_LogFileDescriptor for NULL, pois isso indicara que a linha impressa e
00433     // a primeira linha do arquivo de log (possivelmente porque o log acabou de
00434     // ser compactado).
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         // Cria um novo registro para o novo arquivo.
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         // Compoe o nome do arquivo usando o prefixo e o tempo dado no log.
00455         sprintf( FileRecord->FileName, "%s%s.%lu-0", m_LogsFileDirectory, 
00456                  m_LogsFilePrefix, (unsigned long) line->LogTime );
00457         // Preenche a estrutura com as informacoes do novo arquivo a ser criado.         
00458         FileRecord->StartTime = line->LogTime;
00459         FileRecord->EndTime = 0; // O tempo final igual a 0 indica que o arquivo
00460                                  // de log nao esta compactado.
00461         // Adiciona o novo arquivo de log ao final do vetor.
00462         m_FileLogs.push_back( FileRecord );
00463         // Abre o arquivo com os logs. Se o arquivo nao existir, ele sera criado
00464         // (pois podemos ter acabado de compactar o arquivo com os logs, ou a 
00465         // classe acabou de inicialializar e nenhum log ainda foi salvo).
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         // Obtem o ultimo elemento do vetor de logs, que e o log atualmente
00486         // aberto e usado para armazenar os logs.
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     // Obtem acesso exclusivo a variavel m_MinLogTime. Este lock e necessario
00494     // porque alguma thread pode tentar executar a funcao MinLogTime enquanto
00495     // estivermos tentando alterar esta variavel. Esta alteracao somente sera
00496     // executada uma unica vez, e o lock nao ira bloquear a thread chamando
00497     // MinLogTime por muito tempo, porque vamos verificar o valor da variavel,
00498     // altera-lo, se necessario, e loco em seguida liberar o lock.
00499     pthread_mutex_lock( &m_MutexMinLogTime );
00500     if( m_MinLogTime == 0 )
00501         m_MinLogTime = line->LogTime;
00502     // Libera o acesso exclusivo a variavel m_MinLogTime
00503     pthread_mutex_unlock( &m_MutexMinLogTime );
00504     // Verifica se o FileRecord e NULL (o que seria um erro).
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     // Imprime a linha no arquivo de log.
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     // Forca que a linha seja salva no arquivo atual com os logs (isso e para 
00537     // que a ultima linha impressa esteja imediatamente disponivel para uma
00538     // possivel busca a ser executada).
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     // Verifica se o tamanho do arquivo passou do maximo. Caso isso tenha 
00556     // ocorrido, precisamos compactar o arquivo e informar que a proxima escrita
00557     // deve criar um novo arquivo (invalidando o identicador do arquivo 
00558     // atualmente usado).
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         // Verifica se o tamanho do arquivo passou o tamanho maximo
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             // Fecha o arquivo, e invalida o seu descritor, para informar que
00586             // o arquivo deve ser criado quando inserirmos a proxima linha do
00587             // log.
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             // Compoe o nome do arquivo usando o prefixo, o tempo inicial 
00602             // armazenado no objeto, o tempo dado no log, e a extensao ".gz".
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             // Compacta o arquivo de log, usando o formato gzip.
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             // Fecha o arquivo compactado.
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             // Remove o arquivo nao compactado.
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             // Muda o nome do ultimo log do vetor para o novo nome do arquivo
00759             // compactado.
00760             strcpy( FileRecord->FileName, CompacLogsFileName );
00761             // Atualiza o tempo do ultimo log do arquivo, igual ao tempo do log 
00762             // cuja insercao fez com que o arquivo fosse compactado.
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 }

time_t CLogRotation::MinLogTime ( void   )  [virtual]

Retorna o tempo do primeira linha salva nos arquivos de log.

O valor 0 indica que nenhuma linha ainda foi salva no arquivo de log.

Returns:
tempo em que o primeiro log foi escrito no arquivo de logs. O valor 0 indica que ainda nao escrevemos nos arquivos com os logs.

Definition at line 2061 of file LogRotation.cpp.

02062 {
02063     time_t MinTime;
02064 
02065     #ifdef RIO_DEBUG1
02066     RioErr << "[CLogRotation - MinLogTime] Start" << endl;
02067     #endif
02068 
02069     // Obtem acesso exclusivo a variavel m_MinLogTime. Este lock e necessario
02070     // porque a thread ProcessThread pode tentar executar a funcao InsertLogLine 
02071     // enquanto estivermos tentando ler esta variavel. Esta alteracao somente 
02072     // sera executada uma unica vez, e o lock nao ira bloquear a thread chamando
02073     // MinLogTime por muito tempo.
02074     pthread_mutex_lock( &m_MutexMinLogTime );
02075     MinTime = m_MinLogTime;
02076     // Libera o acesso exclusivo a variavel m_MinLogTime
02077     pthread_mutex_unlock( &m_MutexMinLogTime );
02078 
02079     #ifdef RIO_DEBUG1
02080     RioErr << "[CLogRotation - MinLogTime] Finish" << endl;
02081     #endif
02082 
02083     return MinTime;
02084 }       

int CLogRotation::NewLogLine ( time_t  LogTime,
char *  LogInfo 
) [virtual]

Funcao para criar uma nova solicitacao de impressao de uma linha no log.

Parameters:
LogTime tempo em que o log foi gerado (o tempo e o numero de segundos desde o 12:00 PM de 1 de Janeiro de 1970, tempo universal).
LogInfo linha a ser impressa no log. A linha deve incluir o caractere de retorno de carro (o "\n" do comando printf), pois a funcao de impressao supoe a existencia do "\n" na linha.
Returns:
S_OK se a solicitacao foi criada com sucesso, e um valor diferente de S_OK se algum erro ocorreu ao criarmos a solicitacao.

Definition at line 1867 of file LogRotation.cpp.

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         // Verifica se classe foi inicializada para somente fazer buscas nos
01879         // logs pois, neste caso, nao devemos salvar as linhas passadas a 
01880         // funcao.
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         // Verifica se a linha de log e muito grande.
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         // Cria uma nova linha no log.
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         // Copia os dados para a estrutura.
01924         line->LogTime = LogTime;
01925         strcpy( line->LogInfo, LogInfo );
01926         // Insere uma nova entrada na fila de requisicoes, acordando a thread
01927         // RequisitionThread, se necessario.
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 }

int CLogRotation::NewRequest ( unsigned short  Type,
void *  Data 
) [private]

Cria uma nova solicitacao (de impressao ou de busca) e a coloca no final da fila m_RequestQueue.

Parameters:
Type tipo da solicitacao: INSERT_LINE - Data aponta para uma estrutura do tipo LogLine com uma nova linha para o log; e EXECUTE_SEARCH - Data aponta para uma estrutura do tipo SearchRecord com as informacoes sobre a busca a ser executada nos logs. Qualquer outro valor e um tipo invalido.
Data ponteiro generico cujo valor dependera do campo Type.
Returns:
S_OK se a insercao foi feita com sucesso, ou um valor diferente de S_OK em caso contrario (isto e, ocorreu um erro de alocacao de memoria).

Definition at line 329 of file LogRotation.cpp.

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     // Cria uma nova solicitacao.
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     // Obtem acesso exclusivo a fila m_RequestQueue.
00358     pthread_mutex_lock( &m_MutexRequestQueue );
00359     // Verifica se e preciso acordar a thread RequestThread.
00360     SendSignal = m_RequestQueue.empty();
00361     ExpectedSize = m_RequestQueue.size() + 1;
00362     // Insere o novo registro no final da fila.
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     //cerr << "id: " << m_RequestQueue.size() << endl;
00380     //fflush( stderr ); 
00381     // Se for preciso, enviamos o sinal para acordar a thread RequestThread.
00382     if( SendSignal )
00383         pthread_cond_signal( &m_CondRequestThread );
00384     // Libera o acesso exclusivo a fila m_RequestQueue.
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 }

void * CLogRotation::ProcessThread ( void *  Param  )  [static, private]

Funcao que implementa a thread que processa as solicitacoes de impressao de logs colocadas na fila m_LogLineQueue e as buscas colocadas na fila m_SearchQueue.

Parameters:
Param ponteiro para o parametro passado a thread. No nosso caso, e um ponteiro para um objeto da classe CLogRotation.

Definition at line 1575 of file LogRotation.cpp.

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     // Fica em um laco eterno pegando os registros da fila m_MutexSearchQueue,
01595     // para processar os pedidos de busca por logs pendentes na fila.
01596     while( 1 ) 
01597     {
01598         // Obtem o acesso exclusivo as filas m_LogLineQueue e m_SearchQueue.
01599         pthread_mutex_lock( &LogRotation->m_MutexProcessQueues );
01600         // Se ambas as filas, m_LogLineQueue e m_SearchQueue, estiverem vazias,
01601         // entao bloqueamos na variavel de condicao m_CondProcessThread, ate que
01602         // a thread RequestThread insira algo em uma delas.
01603         if ( ( LogRotation->m_LogLineQueue.empty() ) &&
01604              ( LogRotation->m_SearchQueue.empty() ) )
01605             pthread_cond_wait( &LogRotation->m_CondProcessThread, 
01606                                &LogRotation->m_MutexProcessQueues );
01607         // Verifica se devemos parar a thread.
01608         if( LogRotation->m_StopProcessThread )
01609         {
01610             // Libera o acesso exclusivo as filas m_LogLineQueue e 
01611             // m_SearchQueue.
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         // Agora copiamos todos os logs da fila de logs m_LogLineQueue para o 
01621         // arquivo de saida.
01622         while( !LogRotation->m_LogLineQueue.empty() )
01623         {
01624             line = LogRotation->RemoveLogLineQueue();
01625             if( line != NULL )
01626             {
01627                 // Imprime a linha do log obtida.
01628                 erro = LogRotation->InsertLogLine( line );
01629                 // Deleta a linha do log obtida, pois ela nao sera mais usada.
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         // Agora executamos uma das buscas da fila  m_SearchQueue.
01640         if( !LogRotation->m_SearchQueue.empty() )
01641         {
01642             // Obtem a primeira busca da fila.
01643             search = LogRotation->RemoveSearchQueue();
01644             // Libera o acesso exclusivo as filas m_LogLineQueue e 
01645             // m_SearchQueue.
01646             pthread_mutex_unlock( &LogRotation->m_MutexProcessQueues );
01647             if( search != NULL )
01648             {
01649                 // Executa a busca descrita em search.
01650                 erro = LogRotation->SearchLogs( search );
01651                 // Deleta o resgistro da busca, pois ela nao sera mais usado.
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             // Libera o acesso exclusivo as filas m_LogLineQueue e 
01663             // m_SearchQueue.
01664             pthread_mutex_unlock( &LogRotation->m_MutexProcessQueues );
01665         // Agora verificamos se os tamanhos combinados dos logs passaram do 
01666         // tamanho maximo definido pela variavel m_MaxCombinedLogFilesSize. 
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 }        

LogLine * CLogRotation::RemoveLogLineQueue ( void   )  [private]

Funcao para obter e remover o primeiro elemento da fila m_LogLineQueue.

Returns:
ponteiro para o primeiro registro do tipo LogLine da fila m_LogLineQueue.

Definition at line 179 of file LogRotation.cpp.

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 }

RequestRecord * CLogRotation::RemoveRequestQueue ( void   )  [private]

Funcao para obter e remover o primeiro elemento da fila m_RequestQueue.

Returns:
ponteiro para o primeiro registro do tipo RequestRecord da fila m_RequestQueue.

Definition at line 159 of file LogRotation.cpp.

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 }

SearchRecord * CLogRotation::RemoveSearchQueue ( void   )  [private]

Funcao para obter e remover o primeiro elemento da fila m_SearchQueue.

Returns:
ponteiro para o primeiro registro do tipo SearchRecord da fila m_SearchQueue.

Definition at line 199 of file LogRotation.cpp.

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 }

void * CLogRotation::RequestThread ( void *  Param  )  [static, private]

Funcao que implementa a thread que separa as solicitacoes da fila m_RequestQueue nas filas de impressao de logs (m_LogLineQueue) e execucao das buscas (m_SearchQueue), usadas pela thread ProcessThread.

Parameters:
Param ponteiro para o parametro passado a thread. No nosso caso, e um ponteiro para um objeto da classe CLogRotation.
See also:
ProcessThread

Definition at line 1449 of file LogRotation.cpp.

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     // Fica em um laco eterno pegando as solicitacoes de m_RequestQueue, e 
01470     // colocando-as na fila m_SearchQueue ou na fila m_LogLineQueue, de acordo
01471     // Com o tipo da solicitacao.
01472     while( 1 ) 
01473     {
01474         // Obtem o acesso exclusivo a fila m_RequestQueue.
01475         pthread_mutex_lock( &LogRotation->m_MutexRequestQueue );
01476         // Verifica se a fila esta vazia e, se estiver, a thread bloqueia na 
01477         // variavel de condicao m_CondRequestThread esperando que a funcao
01478         // NewRequest insira uma requisicao na fila m_RequestQueue.
01479         //cerr << "a: " << LogRotation->m_RequestQueue.size() << endl;
01480         //fflush( stderr ); 
01481         if( LogRotation->m_RequestQueue.empty() )
01482         {
01483             //cerr << "ad: " << LogRotation->m_RequestQueue.size() << endl;
01484             //fflush( stderr ); 
01485             pthread_cond_wait( &LogRotation->m_CondRequestThread,
01486                                &LogRotation->m_MutexRequestQueue );
01487             //cerr << "ba: " << LogRotation->m_RequestQueue.size() << endl;
01488             //fflush( stderr ); 
01489         }
01490         // Verifica se devemos parar a thread.
01491         if( LogRotation->m_StopRequestThread )
01492         {
01493             
01494             // Libera o acesso exclusivo a fila m_RequestQueue.
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         // Agora que temos certeza de que temos uma solicitacao, a obtemos e 
01504         // verificamos o seu tipo, colocando-a na fila adequada, e acordando a 
01505         // thread ProcessThread caso ambas as filas, m_LogLineQueue e 
01506         // m_SearchQueue, estejam vazias.
01507         //cerr << "b: " << LogRotation->m_RequestQueue.size() << endl;
01508         //fflush( stderr ); 
01509         request = LogRotation->RemoveRequestQueue();
01510         // Libera o acesso exclusivo a fila m_RequestQueue.
01511         pthread_mutex_unlock( &LogRotation->m_MutexRequestQueue );
01512         if( request != NULL )
01513         {
01514             // Obtem o acesso exclusivo as filas m_LogLineQueue e m_SearchQueue.
01515             pthread_mutex_lock( &LogRotation->m_MutexProcessQueues );
01516             // Verifica se ambas as filas estao vazias, pois neste caso a thread
01517             // ProcessThread estara bloqueada na variavel de condicao 
01518             // m_CondProcessThread e precisaremos, portanto, enviar um sinal 
01519             // para acordar a thread.
01520             SendSignal = ( ( LogRotation->m_LogLineQueue.empty() ) && 
01521                            ( LogRotation->m_SearchQueue.empty() ) );
01522             switch( request->Type )
01523             {
01524                 case INSERT_LINE:
01525                     // A solicitacao e a insercao de uma linha no arquivo de 
01526                     // log. Entao, o registro deve ser colocado na fila 
01527                     // m_LogLineQueue.
01528                     line = ( LogLine * ) request->Data;
01529                     LogRotation->m_LogLineQueue.push( line );
01530                     break;
01531                 case EXECUTE_SEARCH:
01532                     // A solicitacao e um pedido de busca nos arquivos de logs
01533                     // Entao, o registro deve ser colocado na fila 
01534                     // m_SearchQueue.
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                     // Se as filas estavam vazias, nao podemos enviar o sinal 
01543                     // neste caso, pois nao inserimos nada nestas filas.
01544                     SendSignal = false;
01545                     break;
01546             }
01547             // Verifica se e necessario enviar o sinal para a thread 
01548             // ProcessThread, e o envia em caso afirmativo.
01549             if( SendSignal )
01550                 pthread_cond_signal( &LogRotation->m_CondProcessThread );
01551             // Libera o acesso exclusivo as filas m_LogLineQueue e 
01552             // m_SearchQueue.
01553             pthread_mutex_unlock( &LogRotation->m_MutexProcessQueues );
01554             // Remove o registro com a solicitacao request da memoria, pois nao 
01555             // sera mais usado.
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 }        

int CLogRotation::SearchLogFiles ( char *  SearchFileName,
time_t  StartTime,
time_t  EndTime,
callback_log  callback,
void *  callbackparam 
) [virtual]

Funcao para criar uma nova solicitacao de busca nos arquivos de log.

Parameters:
SearchFileName nome do arquivo em que o resultado da busca sera salvo, se a busca tiver sucesso. O arquivo sera compactado pelo metodo do programa gzip.
StartTime tempo inicial dos logs a serem buscados (o tempo e o numero de segundos desde o 12:00 PM de 1 de Janeiro de 1970, tempo universal).
EndTime tempo final dos logs a serem buscados (o tempo e o numero de segundos desde o 12:00 PM de 1 de Janeiro de 1970, tempo universal).
callback funcao a ser chamada quando a busca terminar. Quando a funcao for chamada, sera passado para ela, como primeiro parametro o nome do arquivo dado em SearchFileName, como segundo parametro o tempo inicial (dado por StartTime), como terceiro parametro o tempo final (dado por EndTime), e finalmente, como quarto paramerto, o resultado da busca: SEARCH_OK se a busca teve sucesso ou SEARCH_FAILED se a busca nao teve sucesso.
callbackparam valor, dependende de quem chamou a funcao, passado como parametro a callback quando ela for chamada.
Returns:
S_OK se a solicitacao foi criada com sucesso, e um valor diferente de S_OK se algum erro ocorreu ao criarmos a solicitacao.

Definition at line 1968 of file LogRotation.cpp.

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         // Verifica se o nome do caminho do arquivo e muito grande.
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         // Cria uma nova linha no log.
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         // Copia os dados para a estrutura.
02015         strcpy( search->SearchFileName, SearchFileName );
02016         search->StartTime = StartTime;
02017         search->EndTime = EndTime;
02018         search->callback = callback;
02019         search->callbackparam = callbackparam;
02020         // Insere uma nova entrada na fila de requisicoes, acordando a thread
02021         // RequestThread, se necessario.
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 }

int CLogRotation::SearchLogs ( SearchRecord Record  )  [private]

Funcao para buscar, nos arquivos de logs, os tempos definidos pelo ponteiro para a estrutura Record.

Apos fazer a busca, a callback de quem solicitou a busca, dada na estrutura, e chamada com o nome do arquivo (se a busca teve sucesso), e o resultado da busca.

Parameters:
Record ponteiro para a estrutura com as informacoes sobre a busca a ser executada.
Returns:
S_OK se a busca foi executada com sucesso, ou um valor diferente de S_OK em caso contrario.

Definition at line 778 of file LogRotation.cpp.

00779 {
00780     unsigned int PosLog;   
00781     // Identificador para um arquivo compactado com os logs.
00782     gzFile CompacLogFile;
00783     // Identificador para a versao compactada do arquivo de saida com os 
00784     // resultados.
00785     gzFile SearchFile;
00786     // Variavel booleana usada para indicar se salvamos algum log no arquivo
00787     // com os resultados da busca.
00788     bool SearchFileUsed;
00789     // Variavel booleana usada para verificar se um log deve ser verificado.
00790     bool SearchLogFile;
00791     // Valor para armazenar os codigos de erro.
00792     int erro, SearchResult; 
00793     // Buffer para ler uma linha do arquivo de log (nao compactada).
00794     char Line[ MAXLOGLINESIZE + MAXTIMESTRSIZE ];
00795     // Variavel para armazenar um tempo lido do arquivo de log.
00796     time_t LogTime;
00797 
00798     #ifdef RIO_DEBUG1
00799     RioErr << "[CLogRotation - SearchLogs] Start" << endl;
00800     #endif
00801 
00802     #ifdef RIO_DEBUG2
00803     // Variaveis usadas para armazenar o menor e o maior tempo processado dos
00804     // arquivos.
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     // Cria o arquivo compactado com os resultados da busca.
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     // Procura nos logs compactados do vetor m_LogLineQueue (todos os logs, com
00836     // excecao do ultimo, devem necessariamente estar compactados).
00837     SearchFileUsed = false;
00838     // Verificando os arquivos compactados.
00839     //for( PosLog = 0; PosLog < m_FileLogs.size() - 1; PosLog++ ) 
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             // O arquivo de log da posicao atual esta dentro da faixa de 
00860             // valores. Logo, devemos varrer as suas linhas e procurar pelas
00861             // entradas que estao dentro da faixa.
00862             // Tenta abrir o arquivo atual de logs.
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             // Le uma linha do arquivo.
00884             while( gzgets( CompacLogFile, Line, MAXLOGLINESIZE ) != Z_NULL )
00885             {
00886                 // Obtem o tempo do log da linha do log.
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                 // Verifica se o tempo esta entre o tempo inicial e o final da 
00928                 // faixa desejada, e se o tempo estiver na faixa, o insere no
00929                 // arquivo com os resultados da busca.
00930                 if( ( LogTime >= Search->StartTime ) && 
00931                     ( LogTime <= Search->EndTime ) )
00932                 {
00933                     // Insere a linha de log lida no arquivo de saida.
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     // Imprime os tempos verificados.
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     // Fecha o arquivo com o resultado da busca.
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         // Remove o arquivo com as buscas (pois nao foi usado).
01040         remove( Search->SearchFileName );
01041     }
01042     // Chama a callback para informar a quem fez a busca o resultado dela.
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 }


Field Documentation

pthread_cond_t CLogRotation::m_CondProcessThread [private]

Variavel de condicao usada para bloquear a thread que imprime as linhas de log e faz as buscas, caso nao existam linha a serem impressas e buscas a serem executadas.

Definition at line 228 of file LogRotation.h.

pthread_cond_t CLogRotation::m_CondRequestThread [private]

Variavel de condicao usada para bloquear a thread que recebe as solicitacoes externas (de impressao de linhas de log ou de buscas).

Definition at line 223 of file LogRotation.h.

Vetor com os nomes dos arquivos de log, ordenados pelo tempo do primeiro log do arquivo.

Definition at line 181 of file LogRotation.h.

Variavel booleana que indica se a classe foi inicializada.

Definition at line 156 of file LogRotation.h.

Descritor para o arquivo de log atualmente usado.

Se for igual a -1, ou nenhum arquivo de log foi criado, ou a ultima impressao no arquivo de log fez com que ele fosse compactado.

Definition at line 177 of file LogRotation.h.

Fila com as solicitacoes de impressao de logs no arquivo de log atual (nao compactado).

Definition at line 210 of file LogRotation.h.

char CLogRotation::m_LogsFileDirectory[MaxPathSize] [private]

Caminho do diretorio onde estao os logs.

Definition at line 170 of file LogRotation.h.

char CLogRotation::m_LogsFilePrefix[MaxPathSize] [private]

Prefixo dos nomes dos arquivos.

Definition at line 172 of file LogRotation.h.

unsigned long long int CLogRotation::m_MaxCombinedLogFilesSize [private]

Tamanho maximo usado por todos os logs de um objeto da classe LogRotation.

Se o tamanho passar do valor dado neste campo, os logs mais antigos serao removidos ate que o tamanho volte a ser menor do que o valor deste campo. A classe enviara avisos periodicos para o stderr (usando a RioErr) quando o tamanho combinado dos logs for maior do que PERCENTMAXCOMBINEDSIZE deste valor.

Definition at line 191 of file LogRotation.h.

unsigned int CLogRotation::m_MaxLogFileSize [private]

Tamanho maximo para o arquivo de log (antes de ser compactado).

Definition at line 183 of file LogRotation.h.

time_t CLogRotation::m_MinLogTime [private]

Menor tempo disponivel no log.

Este valor sera o tempo obtido do nome do primeiro arquivo de log.

Definition at line 195 of file LogRotation.h.

pthread_mutex_t CLogRotation::m_MutexMinLogTime [private]

Mutex para garantir o acesso exclusivo a variavel m_MinLogTime.

Definition at line 197 of file LogRotation.h.

pthread_mutex_t CLogRotation::m_MutexProcessQueues [private]

Mutex para garantir acesso exclusivo as filas m_LogLineQueue e m_SearchQueue.

Definition at line 219 of file LogRotation.h.

pthread_mutex_t CLogRotation::m_MutexRequestQueue [private]

Mutex para garantir a exclusao mutual ao acessar a fila m_RequisitionRecordQueue.

Definition at line 206 of file LogRotation.h.

pthread_t CLogRotation::m_ProcessThread [private]

Identificador da thread que processa as solicitacoes, ou seja, as impressoes no log atualmente usado (o nao compactado) e as buscas nos arquivos de logs.

Definition at line 239 of file LogRotation.h.

Fila com as solicitacoes de entrada (necessaria para que a geracao dos logs e as buscas nao atrase as threads que imprimem no log ou fazem buscas).

Definition at line 202 of file LogRotation.h.

pthread_t CLogRotation::m_RequestThread [private]

Identificador da thread que recebe as solicitacoes de entrada (impressao do log e as buscas) e as coloca nas filas m_LogLineQueue ou m_SearchQueue de acordo com o tipo de solicitacao (impressao ou busca), para serem processadas pela thread ProcessThread.

Definition at line 234 of file LogRotation.h.

bool CLogRotation::m_SaveLogs [private]

Variavel booleana indicando se a linha de log passada a funcao InsertLogLine deve ser salva nos logs, isto e, se esta variavel for false, a classe somente fara buscas nos logs, e a funcao InsertLogLine retornara imediatamente, sem salvar esta linha nos logs.

Definition at line 168 of file LogRotation.h.

Fila com as solicitacoes de buscas.

Quando a busca terminar, a callback fornecida por quem fez a busca sera chamada com o resultado da busca e com o nome do arquivo compactado com este resultado.

Definition at line 215 of file LogRotation.h.

Nova variavel usada para indicar se o objeto da classe esta associado a um dos servidores ou a um cliente.

Definition at line 243 of file LogRotation.h.

Variavel booleana usada para sabermos se devemos terminar a thread ProcessThread.

Definition at line 162 of file LogRotation.h.

Variavel booleana usada para sabermos se devemos terminar a thread RequestThread.

Definition at line 159 of file LogRotation.h.


The documentation for this class was generated from the following files:
Generated on Wed Jul 4 16:03:31 2012 for RIO by  doxygen 1.6.3