00001 #ifndef LOGROTATION_H_ 00002 #define LOGROTATION_H_ 00003 00004 #include <time.h> 00005 #include <pthread.h> 00006 // cabecalhos do C++ (STL). 00007 #include <list> 00008 #include <queue> 00009 #include <vector> 00010 00011 #include "RioInterfaceTypes.h" 00012 #include "RioError.h" 00013 00014 using namespace std; 00015 00016 /** Constante necessaria para completar o prefixo dado na funcao Initialize da 00017 * classe com o sufixo ".[tempo_inicial]-[tempo_final].gz", sendo que 00018 * [tempo_inicial] e [tempo_final] sao inteiros do tipo unsigned int e possuem, 00019 * no formato ASCII, ate 10 digitos. 00020 */ 00021 #define MAXSIZESUFFIXFILELOG 25 00022 00023 /** Tamanho do buffer usado ao compactar o arquivo atual com os logs. */ 00024 #define BUFFERCOMPACSIZE 1024 00025 00026 /** Tamanho maximo da linha com os logs. */ 00027 #define MAXLOGLINESIZE 1400 00028 00029 /** Tamanho maximo da string de tempo mais o espaco entre ela e o log mais o 00030 * "\n" ao final do log. 00031 */ 00032 #define MAXTIMESTRSIZE 12 00033 00034 /** Codigo passado a callback quando uma busca dentro dos arquivos de log teve 00035 * sucesso. Isso ocorrera se existirem logs cujos tempos de geracao estao dentro 00036 * da faixa de tempo definida pela busca. 00037 * @see SearchRecord, CLogRotation::SearchLogFiles 00038 */ 00039 #define SEARCH_OK 0 00040 /** Codigo passado a callback quando uma busca dentro dos arquivos de log 00041 * fracassou. Isso ocorrera se nao existir nenhum log dentro da faixa de tempo 00042 * definida pela busca. 00043 * @see SearchRecord, CLogRotation::SearchLogFiles 00044 */ 00045 #define SEARCH_FAILED 1 00046 00047 /** Tipo da solicitacao para inserir uma linha no arquivo de log. Este arquivo 00048 * sera o nao compactado. 00049 * @see LogLine, CLogRotation::NewLogLine 00050 */ 00051 #define INSERT_LINE 0 00052 /** Tipo da solicitacao para executar uma busca nos arquivos de log. 00053 * @see SearchRecord, CLogRotation::SearchLogFiles*/ 00054 #define EXECUTE_SEARCH 1 00055 00056 /** Porcentagem usada para habilitar o envio de avisos (usando a RioErr) 00057 * informando que o espaco disponivel para os logs esta acabando. Um aviso sera 00058 * enviado quando os tamanhos combinados passarem do tamanho maximo dos arquivos 00059 * combinados vezes o valor desta constante (ou seja, se o valor da constante 00060 * for 90, que e o valor default, avisos serao enviados quando o tamanho 00061 * combinado passar de 90% do tamanho maximo combinado dos logs). 00062 */ 00063 00064 #define PERCENTMAXCOMBINEDSIZE 0.9 // 90% 00065 00066 /** Estrutura usada para inserir uma linha de log na fila do log. */ 00067 00068 struct LogLine 00069 { 00070 time_t LogTime; /**< Tempo em que o log foi gerado */ 00071 char LogInfo[ MAXLOGLINESIZE + 1 ]; /**< Linha a ser colocada no log. 00072 * OBS: O +1 no tamanho e para 00073 * contabilizarmos, na string, 00074 * o terminador "\0". 00075 */ 00076 }; 00077 00078 /** Novo tipo para definir a funcao de callback, que sera chamada quando uma 00079 * solicitacao de busca for terminada. 00080 */ 00081 00082 typedef void (*callback_log)( char *SearchFileName, time_t StartTime, 00083 time_t EndTime, int SearchResult, 00084 void *callbackparam ); 00085 00086 /** Estrutura usada para entrar solicitacoes (escritas de linhas de log no arquivo 00087 * de logs e buscas nos arquivos de log) para a classe. 00088 */ 00089 00090 struct RequestRecord 00091 { 00092 unsigned short Type; /**< Tipo da solicitacao. A solicitacao pode ser 00093 * INSERT_LINE, usada para inserir uma linha no log, ou 00094 * EXECUTE_SEARCH, usada para executar uma nova busca. 00095 */ 00096 void *Data; /**< Dado usado pela solicitacao. Se a solicitacao for a 00097 * INSERT_LINE, sera um ponteiro para uma estrutura do tipo 00098 * LogFileRecord, e se a solicitacao for a EXECUTE_SEARCH, um 00099 * ponteiro para uma estrutura do tipo SearchRecord. 00100 */ 00101 }; 00102 00103 /** Estrutura usada para fazer uma busca nos arquivos de log. */ 00104 00105 struct SearchRecord 00106 { 00107 char SearchFileName[ MaxPathSize ]; /**< Nome do arquivo com os resultados 00108 * da busca. Este arquivo estara 00109 * compactado no formato gzip. 00110 */ 00111 time_t StartTime; /**< Tempo inicial dos logs a serem buscados. */ 00112 time_t EndTime; /**< Tempo final dos logs a serem buscados. */ 00113 callback_log callback; /**< Funcao a ser chamada quando a busca acabar de 00114 * ser executada. 00115 */ 00116 void *callbackparam; /* Parametro generico passado a callback, usado para 00117 passar informacoes sobre a origem da busca. */ 00118 }; 00119 00120 /** Estrutura que armazena os nomes dos arquivos de log e os tempos inicial e 00121 * final armazenados neste nome. 00122 */ 00123 00124 struct LogFileRecord 00125 { 00126 char FileName[ MaxPathSize ]; 00127 time_t StartTime; 00128 time_t EndTime; 00129 }; 00130 00131 /** Novo tipo que define a fila com as solicitacoes de entrada (logs ou buscas) 00132 * para a classe LogRotation. 00133 */ 00134 00135 typedef queue< RequestRecord *, list< RequestRecord * > > RequestQueue; 00136 00137 /** Novo tipo que define a fila com as solicitacoes de impressao no log atual. 00138 */ 00139 00140 typedef queue< LogLine *, list< LogLine * > > LogLineQueue; 00141 00142 /** Novo tipo que define a fila com as solicitacoes de busca nos logs. */ 00143 00144 typedef queue< SearchRecord *, list< SearchRecord * > > SearchQueue; 00145 00146 /** Novo tipo que define o vetor com as informacoes dos arquivos de log. */ 00147 00148 typedef vector< LogFileRecord * > FileLogs; 00149 00150 /** Classe que implementa o controle da geracao de um conjunto de logs. */ 00151 00152 class CLogRotation 00153 { 00154 private: 00155 /** Variavel booleana que indica se a classe foi inicializada */ 00156 bool m_Initialized; 00157 /** Variavel booleana usada para sabermos se devemos terminar a thread 00158 * RequestThread. */ 00159 bool m_StopRequestThread; 00160 /** Variavel booleana usada para sabermos se devemos terminar a thread 00161 * ProcessThread. */ 00162 bool m_StopProcessThread; 00163 /** Variavel booleana indicando se a linha de log passada a funcao 00164 * InsertLogLine deve ser salva nos logs, isto e, se esta variavel for 00165 * false, a classe somente fara buscas nos logs, e a funcao 00166 * InsertLogLine retornara imediatamente, sem salvar esta linha nos 00167 * logs. */ 00168 bool m_SaveLogs; 00169 /** Caminho do diretorio onde estao os logs. */ 00170 char m_LogsFileDirectory[ MaxPathSize ]; 00171 /** Prefixo dos nomes dos arquivos. */ 00172 char m_LogsFilePrefix[ MaxPathSize ]; 00173 /** Descritor para o arquivo de log atualmente usado. Se for igual a -1, 00174 * ou nenhum arquivo de log foi criado, ou a ultima impressao no 00175 * arquivo de log fez com que ele fosse compactado. 00176 */ 00177 FILE *m_LogFileDescriptor; 00178 /** Vetor com os nomes dos arquivos de log, ordenados pelo tempo do 00179 * primeiro log do arquivo. 00180 */ 00181 FileLogs m_FileLogs; 00182 /** Tamanho maximo para o arquivo de log (antes de ser compactado). */ 00183 unsigned int m_MaxLogFileSize; 00184 /** Tamanho maximo usado por todos os logs de um objeto da classe 00185 * LogRotation. Se o tamanho passar do valor dado neste campo, os logs 00186 * mais antigos serao removidos ate que o tamanho volte a ser menor do 00187 * que o valor deste campo. A classe enviara avisos periodicos para 00188 * o stderr (usando a RioErr) quando o tamanho combinado dos logs for 00189 * maior do que PERCENTMAXCOMBINEDSIZE deste valor. 00190 */ 00191 unsigned long long int m_MaxCombinedLogFilesSize; 00192 /** Menor tempo disponivel no log. Este valor sera o tempo obtido do 00193 * nome do primeiro arquivo de log. 00194 */ 00195 time_t m_MinLogTime; 00196 /** Mutex para garantir o acesso exclusivo a variavel m_MinLogTime. */ 00197 pthread_mutex_t m_MutexMinLogTime; 00198 /** Fila com as solicitacoes de entrada (necessaria para que a geracao 00199 * dos logs e as buscas nao atrase as threads que imprimem no log ou 00200 * fazem buscas). 00201 */ 00202 RequestQueue m_RequestQueue; 00203 /** Mutex para garantir a exclusao mutual ao acessar a fila 00204 * m_RequisitionRecordQueue. 00205 */ 00206 pthread_mutex_t m_MutexRequestQueue; 00207 /** Fila com as solicitacoes de impressao de logs no arquivo de log 00208 * atual (nao compactado). 00209 */ 00210 LogLineQueue m_LogLineQueue; 00211 /** Fila com as solicitacoes de buscas. Quando a busca terminar, a 00212 * callback fornecida por quem fez a busca sera chamada com o resultado 00213 * da busca e com o nome do arquivo compactado com este resultado. 00214 */ 00215 SearchQueue m_SearchQueue; 00216 /** Mutex para garantir acesso exclusivo as filas m_LogLineQueue e 00217 * m_SearchQueue. 00218 */ 00219 pthread_mutex_t m_MutexProcessQueues; 00220 /** Variavel de condicao usada para bloquear a thread que recebe as 00221 * solicitacoes externas (de impressao de linhas de log ou de buscas). 00222 */ 00223 pthread_cond_t m_CondRequestThread; 00224 /** Variavel de condicao usada para bloquear a thread que imprime as 00225 * linhas de log e faz as buscas, caso nao existam linha a serem 00226 * impressas e buscas a serem executadas. 00227 */ 00228 pthread_cond_t m_CondProcessThread; 00229 /** Identificador da thread que recebe as solicitacoes de entrada 00230 * (impressao do log e as buscas) e as coloca nas filas m_LogLineQueue 00231 * ou m_SearchQueue de acordo com o tipo de solicitacao (impressao ou 00232 * busca), para serem processadas pela thread ProcessThread. 00233 */ 00234 pthread_t m_RequestThread; 00235 /** Identificador da thread que processa as solicitacoes, ou seja, as 00236 * impressoes no log atualmente usado (o nao compactado) e as buscas 00237 * nos arquivos de logs. 00238 */ 00239 pthread_t m_ProcessThread; 00240 /** Nova variavel usada para indicar se o objeto da classe esta 00241 * associado a um dos servidores ou a um cliente. 00242 */ 00243 bool m_ServerInstance; 00244 00245 /** 00246 * Funcao para obter e remover o primeiro elemento da fila 00247 * m_RequestQueue. 00248 * @return ponteiro para o primeiro registro do tipo RequestRecord da 00249 * fila m_RequestQueue. 00250 */ 00251 RequestRecord *RemoveRequestQueue( void ); 00252 /** 00253 * Funcao para obter e remover o primeiro elemento da fila 00254 * m_LogLineQueue. 00255 * @return ponteiro para o primeiro registro do tipo LogLine da fila 00256 * m_LogLineQueue. 00257 */ 00258 LogLine *RemoveLogLineQueue( void ); 00259 /** 00260 * Funcao para obter e remover o primeiro elemento da fila 00261 * m_SearchQueue. 00262 * @return ponteiro para o primeiro registro do tipo SearchRecord da 00263 * fila m_SearchQueue. 00264 */ 00265 SearchRecord *RemoveSearchQueue( void ); 00266 /** 00267 * Funcao para remover os elementos da fila m_RequuestQueue, salvando 00268 * todos os registros que apontem para logs. 00269 */ 00270 void DeleteRequestQueue(); 00271 /** 00272 * Funcao para remover os elementos da fila m_LogLineQueue,salvando 00273 * todas as linhas de log, na ordem dada pela fila, no arquivo atual com 00274 * os logs. 00275 */ 00276 void DeleteLogLineQueue(); 00277 /** 00278 * Funcao para remover os elementos da fila m_SearchQueue. As buscas 00279 * pendentes serao ignoradas. 00280 */ 00281 void DeleteSearchQueue(); 00282 /** 00283 * Cria uma nova solicitacao (de impressao ou de busca) e a coloca no 00284 * final da fila m_RequestQueue. 00285 * @param Type tipo da solicitacao: INSERT_LINE - Data aponta para uma 00286 * estrutura do tipo LogLine com uma nova linha para o log; e 00287 * EXECUTE_SEARCH - Data aponta para uma estrutura do tipo SearchRecord 00288 * com as informacoes sobre a busca a ser executada nos logs. Qualquer 00289 * outro valor e um tipo invalido. 00290 * @param Data ponteiro generico cujo valor dependera do campo Type. 00291 * @return S_OK se a insercao foi feita com sucesso, ou um valor 00292 * diferente de S_OK em caso contrario (isto e, ocorreu um erro de 00293 * alocacao de memoria). 00294 */ 00295 int NewRequest( unsigned short Type, void *Data ); 00296 /** 00297 * Funcao para inserir uma linha no arquivo de log. 00298 * @param line informacoes (tempo, string) da linha a ser armazenada no 00299 * log. Depois de escrever a linha, se o arquivo de log passar do 00300 * tamanho maximo m_MaxLogFileSize, este arquivo sera compactado. 00301 * Obs: se um arquivo de log nao compactado existir (o que ocorrera 00302 * quando o primeiro arquivo de log for criado ou quando acabamos, na 00303 * chamada anterior desta funcao, de compactar o log atual), este 00304 * arquivo sera criado. Isso nao pode ser feito antes (por exemplo, apos 00305 * compactar os logs), pois somente agora sabemos o tempo inicial do 00306 * arquivo, que sera o tempo da linha de log que estamos salvando no 00307 * arquivo. 00308 * @return S_OK se as informacoes foram armazenadas no arquivo com 00309 * sucesso, ou um valor diferente de S_OK em caso contrario. 00310 */ 00311 int InsertLogLine( LogLine *line ); 00312 /** 00313 * Funcao para buscar, nos arquivos de logs, os tempos definidos pelo 00314 * ponteiro para a estrutura Record. Apos fazer a busca, a callback de 00315 * quem solicitou a busca, dada na estrutura, e chamada com o nome do 00316 * arquivo (se a busca teve sucesso), e o resultado da busca. 00317 * @param Record ponteiro para a estrutura com as informacoes sobre a 00318 * busca a ser executada. 00319 * @return S_OK se a busca foi executada com sucesso, ou um valor 00320 * diferente de S_OK em caso contrario. 00321 */ 00322 int SearchLogs( SearchRecord *Record ); 00323 /** 00324 * Funcao para determinar, a partir do nome de arquivo passado como 00325 * parametro, o tempo neste nome de arquivo. 00326 * @param FileName ponteiro para o nome do arquivo. O arquivo deve estar 00327 * no formato [prefixo].[tempo_inicial]-[tempo_final], podendo ter, ao 00328 * final do nome, a extensao opcional ".gz" (quando estiver compactado). 00329 * @param StartTime ponteiro para o valor do tipo time_t onde sera 00330 * retornado o tempo inicial extraido do nome do arquivo. 00331 * @param EndTime ponteiro para o valor do tipo time_t onde sera 00332 * retornado o tempo final extraido do nome do arquivo. 00333 * @return S_OK se os tempos foram obtidos com sucesso do none do 00334 * arquivo (que deve estar no formato acima, o valor diferente de S_OK 00335 * em caso de erro). 00336 */ 00337 int GetTimeStamp( char *FileName, time_t *StartTime, time_t *EndTime ); 00338 /** 00339 * Funcao para preencher o vetor m_FileLogs com os nomes dos arquivos de 00340 * log (que possuem o prefixo m_LogsFilePrefix) do diretorio dado em 00341 * m_LogsFileDirectory). 00342 */ 00343 int GetFileLogs(); 00344 /** 00345 * Verifica se o tamanho combinado de todos os logs passou o tamanho 00346 * maximo dado em m_MaxCombinedLogFilesSize. Se isso ocorrer, os logs 00347 * mais antigos serao removidos ate que o tamanho passe a ser menor do 00348 * que o maximo. A funcao enviara avisos para a stderr (via RioErr) 00349 * quando o tamanho passar de PERCENTMAXCOMBINEDSIZE do valor maximo. 00350 * @return S_OK se a vefiricacao foi feita com sucesso, e um valor 00351 * diferente de S_OK em caso contrario. 00352 */ 00353 int CheckCombinedLogsSizes(); 00354 /** 00355 * Compara duas estrutoras do tipo LogFileRecord. A comparacao e baseada 00356 * nos campos StartTime e EndTime. 00357 * @param x ponteiro para a primeira estrutura do tipo LogFileRecord. 00358 * @param y ponteiro para a primeira estrutura do tipo LogFileRecord. 00359 * @return true se o campo StartTime de x for menor do que o campo 00360 * StartTime de y ou, se estes campos forem identicos, se o campo 00361 * EndTime de x for menor do que o campo Endtime de y. 00362 */ 00363 static bool CompareFileLogs( LogFileRecord* x, LogFileRecord* y ); 00364 /** 00365 * Funcao que implementa a thread que separa as solicitacoes da fila 00366 * m_RequestQueue nas filas de impressao de logs (m_LogLineQueue) e 00367 * execucao das buscas (m_SearchQueue), usadas pela thread 00368 * ProcessThread. 00369 * @param Param ponteiro para o parametro passado a thread. No nosso 00370 * caso, e um ponteiro para um objeto da classe CLogRotation. 00371 * @see ProcessThread 00372 */ 00373 static void *RequestThread( void *Param ); 00374 /** 00375 * Funcao que implementa a thread que processa as solicitacoes de 00376 * impressao de logs colocadas na fila m_LogLineQueue e as buscas 00377 * colocadas na fila m_SearchQueue. 00378 * @param Param ponteiro para o parametro passado a thread. No nosso 00379 * caso, e um ponteiro para um objeto da classe CLogRotation. 00380 */ 00381 static void *ProcessThread( void *Param ); 00382 public: 00383 /** 00384 * Construtor da classe. 00385 * @param ServerInstance novo parametro usado para indicar se o objeto 00386 * da classe esta associado a um servidor ou a um cliente (o novo 00387 * parametro possui a opcao default de true para manter compatibilidade 00388 * com a versao anterior da classe). 00389 */ 00390 CLogRotation( bool ServerInstance = true ); 00391 /** 00392 * Destrutor da classe. 00393 */ 00394 virtual ~CLogRotation(); 00395 /** 00396 * Funcao usada para inicializar um objeto da classe CLogRotation. O 00397 * objeto deve estar inicializado para podermos usar as funcoes 00398 * NewLogLine e SearchLogFiles (caso o objeto nao esteja inicializado, e 00399 * retornado o erro ERROR_LOGROTATION + ERROR_NOT_INITIALIZED). 00400 * @param LogsFilePrefixPath nome do caminho do prefixo para os arquivos 00401 * de log. Este caminho deve incluir, alem do prefixo, o nome do 00402 * diretorio onde os logs serao armazenados. Por exemplo, o parametro 00403 * "/home/xandao/TesteLogs" indica que os logs serao armazenados no 00404 * diretorio "/home/xandao", com nomes com o prefixo de "TesteLogs". 00405 * @param MaxLogFileSize tamanho maximo que o arquivo de log deve ter. 00406 * Quando o tamanho passar do tamanho maximo, o arquivo de log sera 00407 * compactado e um novo arquivo de log (com o prefixo dado) sera criado. 00408 * @param MaxCombinedLogFilesSize valor maximo para o tamanho combinado 00409 * dos arquivos com os logs. 00410 * @param SaveLogs novo parametro booleano, com valor default de true, 00411 * que indica se devemos salvar a linha do log passada a funcao 00412 * NewLogLine nos logs. Caso este parametro seja false, a funcao 00413 * NewLogLine sempre retornara sem fazer nada, ou seja, sem salvar a 00414 * linha passada como parametro nos logs. 00415 * @return S_OK se a inicializacao foi feita com sucesso, e um valor 00416 * diferente de S_OK em caso contrario. 00417 */ 00418 virtual int Initialize( char *LogsFilePrefixPath, 00419 unsigned int MaxLogFileSize, 00420 unsigned long long int MaxCombinedLogFilesSize, 00421 bool SaveLogs = true ); 00422 /** 00423 * Funcao para criar uma nova solicitacao de impressao de uma linha no 00424 * log. 00425 * @param LogTime tempo em que o log foi gerado (o tempo e o numero de 00426 * segundos desde o 12:00 PM de 1 de Janeiro de 1970, tempo universal). 00427 * @param LogInfo linha a ser impressa no log. A linha deve incluir o 00428 * caractere de retorno de carro (o "\n" do comando printf), pois a 00429 * funcao de impressao supoe a existencia do "\n" na linha. 00430 * @return S_OK se a solicitacao foi criada com sucesso, e um valor 00431 * diferente de S_OK se algum erro ocorreu ao criarmos a solicitacao. 00432 */ 00433 virtual int NewLogLine( time_t LogTime, char *LogInfo ); 00434 /** 00435 * Funcao para criar uma nova solicitacao de busca nos arquivos de log. 00436 * @param SearchFileName nome do arquivo em que o resultado da busca 00437 * sera salvo, se a busca tiver sucesso. O arquivo sera compactado pelo 00438 * metodo do programa gzip. 00439 * @param StartTime tempo inicial dos logs a serem buscados (o tempo e o 00440 * numero de segundos desde o 12:00 PM de 1 de Janeiro de 1970, tempo 00441 * universal). 00442 * @param EndTime tempo final dos logs a serem buscados (o tempo e o 00443 * numero de segundos desde o 12:00 PM de 1 de Janeiro de 1970, tempo 00444 * universal). 00445 * @param callback funcao a ser chamada quando a busca terminar. Quando 00446 * a funcao for chamada, sera passado para ela, como primeiro parametro 00447 * o nome do arquivo dado em SearchFileName, como segundo parametro o 00448 * tempo inicial (dado por StartTime), como terceiro parametro o tempo 00449 * final (dado por EndTime), e finalmente, como quarto paramerto, o 00450 * resultado da busca: SEARCH_OK se a busca teve sucesso ou 00451 * SEARCH_FAILED se a busca nao teve sucesso. 00452 * @param callbackparam valor, dependende de quem chamou a funcao, 00453 * passado como parametro a callback quando ela for chamada. 00454 * @return S_OK se a solicitacao foi criada com sucesso, e um valor 00455 * diferente de S_OK se algum erro ocorreu ao criarmos a solicitacao. 00456 */ 00457 virtual int SearchLogFiles( char *SearchFileName, time_t StartTime, 00458 time_t EndTime, callback_log callback, 00459 void *callbackparam ); 00460 /** 00461 * Retorna o tempo do primeira linha salva nos arquivos de log. O valor 00462 * 0 indica que nenhuma linha ainda foi salva no arquivo de log. 00463 * @return tempo em que o primeiro log foi escrito no arquivo de logs. O 00464 * valor 0 indica que ainda nao escrevemos nos arquivos com os logs. 00465 */ 00466 virtual time_t MinLogTime( void ); 00467 }; 00468 00469 #endif /*LOGROTATION_H_*/