CServerUserLogs Class Reference

#include <UserLogs.h>

Public Member Functions

 CServerUserLogs (server_rec *Server)
 Construtor da classe, usado ao criar um objeto da classe.
virtual ~CServerUserLogs ()
 Destrutor da classe, usado ao remover um objeto da classe.
virtual RioResult Initialize (char *LogsFilePrefixPath, unsigned int MaxLogFileSize, unsigned long long int MaxCombinedLogFilesSize, int LogsPort)
 Funcao usada para inicializar um objeto da classe CUserLogs.
void JoinThread ()
 Funcao para bloquear o processo ate a thread que recebe os logs termine de executar.

Private Member Functions

RioResult ReceiveLogLine (char *LogLine, int *LogLinePort)
 Funcao usada para receber uma string com um log pelo socket UDP.
RioResult SendResult (int Port, int Result)
 Funcao para enviar o resultado dado como parametro para o socket UDP cuja porta tambem e dada como parametro.
bool ServerUserLogsThread ()
 Funcao executada pela thread da classe.

Static Private Member Functions

static void * ServerUserLogsThreadEp (void *Param)
 Funcao que chama a funcao executada pela thread da classe, usada quando a thread e criada.

Private Attributes

bool m_Initialized
 Variavel booleana que indica se a classe foi inicializada.
pthread_t m_ServerUserLogsThread
 Identificador da thread que recebe os dados a serem colocados no log.
server_rec * m_Server
 Ponteiro para a estrutura com as informacoes do servidor.
CLogRotationm_LogRotation
 Ponteiro para o objeto da classe de gerenciamento de logs usada por esta classe.
int m_Socket
 Socket usado para enviar dados para a thread da classe, usando a funcao estatica SendLogLine da classe.
struct sockaddr_in m_SocketAddr
 Armazena o endereco do socket usado para gerar os logs.
int m_LogsServerPort
 Armazena a porta usada pela thread que envia os logs.

Detailed Description

Definition at line 54 of file UserLogs.h.


Constructor & Destructor Documentation

CServerUserLogs::CServerUserLogs ( server_rec *  Server  ) 

Construtor da classe, usado ao criar um objeto da classe.

Parameters:
Server ponteiro para a requisicao associada a conexao http com o servidor.

Definition at line 41 of file UserLogs.cpp.

00042 {
00043     // Inicializa as variaveis da classe.
00044     m_Initialized = false;
00045     m_ServerUserLogsThread = 0;
00046     m_LogRotation = NULL;
00047     m_Socket = 0;
00048     memset( &m_SocketAddr, 0, sizeof( m_SocketAddr ) );
00049     m_Server = Server;
00050     m_LogsServerPort = 0;
00051 }

CServerUserLogs::~CServerUserLogs (  )  [virtual]

Destrutor da classe, usado ao remover um objeto da classe.

Definition at line 54 of file UserLogs.cpp.

00055 {
00056     // Cria uma string temporaria, toda preenchida com 0, para ser enviada pelo
00057     // socket e ser recebida como uma string vazia.
00058     char NullStr[ MAXLOGLINESIZE ];
00059 
00060     // Armazena uma copia do identificador da thread.
00061     pthread_t ServerUserLogsThread;
00062 
00063     // Envia a mensagem de finalizacao (um dado com tamanho igual a 0) pelo 
00064     // socket UDP, para finalizar a thread, se a thread ainda estiver
00065     // executando.
00066     if( m_ServerUserLogsThread != 0 )
00067     {
00068         // Salva o ID da thread para ser usado nos comandos a seguir.
00069         ServerUserLogsThread = m_ServerUserLogsThread;
00070         // Inicializa a string temporaria com 0, para que ela seja vazia.
00071         memset( NullStr, 0, MAXLOGLINESIZE );
00072 
00073         // Envia a mensagem com somente um byte, para destravar o poll.
00074         if( sendto( m_Socket, NullStr, MAXLOGLINESIZE, UDP_FLAGS_SENDDATA,
00075                     ( struct sockaddr * ) &m_SocketAddr,
00076                     sizeof( m_SocketAddr ) ) < 0 )
00077         {
00078             // Ocorreu um erro ao enviarmos a mensagem, Entao vamos cancelar a
00079             // thread.
00080             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error %u (%s) "
00081                           "when finalizing object! killing the thread!", errno,
00082             strerror( errno ) );
00083             pthread_cancel( ServerUserLogsThread );
00084         }
00085         else
00086         {
00087             #ifdef RIO_DEBUG2
00088             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Esperando a "
00089                           "thread que recebe os logs terminar de executar!" );
00090             #endif
00091             // Espera a thread terminar a sua execucao.
00092             pthread_join( ServerUserLogsThread, NULL );
00093         }
00094     }
00095 
00096     // Deleta o objeto que gerencia os logs.
00097     if( m_LogRotation != NULL )
00098         delete m_LogRotation;
00099 
00100     // Fecha o socket do servidor.
00101     if( m_Socket != 0 )
00102     {
00103         shutdown( m_Socket, SHUT_RDWR );
00104         close( m_Socket );
00105     }
00106 }


Member Function Documentation

int CServerUserLogs::Initialize ( char *  LogsFilePrefixPath,
unsigned int  MaxLogFileSize,
unsigned long long int  MaxCombinedLogFilesSize,
int  LogsPort 
) [virtual]

Funcao usada para inicializar um objeto da classe CUserLogs.

O objeto deve estar inicializado para podermos usar a funcao NewLogLine (caso o objeto nao esteja inicializado, e retornado o erro ERROR_SERVERUSERLOGS + 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.
LogsPort Porta UDP a ser usada (sem ser na ordem de rede).
Returns:
S_OK se a inicializacao foi feita com sucesso, e um valor diferente de S_OK em caso contrario.

Definition at line 512 of file UserLogs.cpp.

00516 {
00517     // Atributos da thread de gerenciamento das conexoes TCP.
00518     pthread_attr_t attribServerUserLogsThread;
00519     // Armazena o endereco do socket UDP.
00520     struct sockaddr_in TempAddr;
00521     // Armazena o tamanho do endereco do socket usado para desbloquear o select.
00522     socklen_t AddrSize;
00523     // Armazena o resultado das execucoes das funcoes da classe e do objeto do
00524     // RIO.
00525     RioResult RioStatus;
00526 
00527     // Verifica se o objeto da classe ja esta inicializado.
00528     if( m_Initialized )
00529     {
00530         #ifdef RIO_DEBUG2
00531         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00532                       "Objeto ja foi inicializado!" );
00533         #endif
00534 
00535         return ERROR_SERVERUSERLOGS + ERROR_INITIALIZED;
00536     }
00537 
00538     // Cria o socket UDP do objeto, usado para receber linhas de log.
00539     m_Socket = socket( AF_INET, SOCK_DGRAM, 0 );
00540     if( m_Socket < 0 )
00541     {
00542         #ifdef RIO_DEBUG2
00543         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00544                       "criaro socket UDP usado pelo objeto!", errno,
00545                       strerror( errno ) );
00546         #endif
00547 
00548         return ERROR_SERVERUSERLOGS + ERROR_SOCKET_CREATE;
00549     }
00550 
00551     // Faz com que o socket seja exclusivo do processo, e nao seja passado
00552     // para um outro processo criado pelo processo que abriu o socket.
00553     //
00554     // Obs: Sera que isso e necessario?
00555     //
00556     if( fcntl( m_Socket, F_SETFD, FD_CLOEXEC ) < 0 )
00557     {
00558         #ifdef RIO_DEBUG2
00559         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00560                       "fazer o socket UDP recem criado ser exclusivo ao "
00561                       "processo!", errno, strerror( errno ) );
00562         #endif
00563 
00564         return ERROR_SERVERUSERLOGS + ERROR_SOCKET_OPTIONS;
00565     }
00566 
00567     // Inicializa a porta do servidor.
00568     m_LogsServerPort = LogsPort;
00569 
00570     // Limpa a estrutura TempAddr.
00571     memset( &TempAddr, 0, sizeof( TempAddr ) );
00572     // associa o socket UDP usado para desbloquear o poll ao IP do servidor e
00573     // a uma porta escolhida aleatoriamente (isso esta bom, ou devemos usar a
00574     // porta do UDP mais 1 - para nao colidir com a porta UDP da RioNeti?).
00575     TempAddr.sin_family = AF_INET;
00576     TempAddr.sin_addr.s_addr = INADDR_ANY; // Faz o sistema definir o IP. A
00577                                            // estrutura server tinha diversos
00578                                            // IPs, mas eu nao sabia qual deles
00579                                            // deveria ser usado.
00580     TempAddr.sin_addr.s_addr = USERLOGS_UDP_IP; // Usando o IP 127.0.0.1
00581     TempAddr.sin_port = htons( m_LogsServerPort );
00582 
00583     if( bind( m_Socket, ( struct sockaddr * ) &TempAddr,
00584               sizeof( TempAddr ) ) < 0 )
00585     {
00586         #ifdef RIO_DEBUG2
00587         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00588                       "ligar o socket UDP a uma porta %u!", errno,
00589                       strerror( errno ), m_LogsServerPort );
00590         #endif
00591 
00592         return ERROR_SERVERUSERLOGS + ERROR_SOCKET_BIND;
00593     }
00594 
00595     AddrSize = sizeof( m_SocketAddr );
00596     if( getsockname( m_Socket, ( struct sockaddr * ) &m_SocketAddr,
00597                      &AddrSize ) != 0 )
00598     {
00599         #ifdef RIO_DEBUG2
00600         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00601                       "obter as informacoes do socket UDP!", errno,
00602                       strerror( errno ) );
00603         #endif
00604 
00605         return ERROR_SERVERUSERLOGS + ERROR_SOCKET_OPTIONS;
00606     }
00607 
00608 
00609     // Tenta criar um novo objeto da classe CLogRotation;
00610     try
00611     {
00612         m_LogRotation = new CLogRotation( false );
00613     }
00614     catch( bad_alloc &ba )
00615     {
00616         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Memory error ("
00617                       "bad_alloc, error = %s) when allocating log rotation "
00618                       "object!", ba.what() );
00619 
00620         m_LogRotation = NULL;
00621 
00622         // Fecha o socket UDP criado.
00623         shutdown( m_Socket, SHUT_RDWR );
00624         close( m_Socket );
00625 
00626         return ERROR_SERVERUSERLOGS + ERROR_MEMORY;
00627     }
00628 
00629     #ifdef RIO_DEBUG2
00630     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Tentando inicializar o "
00631                   "objeto de gerenciamento de logs!" );
00632     #endif
00633 
00634     // Tenta inicializar o objeto da classe CLogRotation criado.
00635     RioStatus = m_LogRotation->Initialize( LogsFilePrefixPath, MaxLogFileSize,
00636                                            MaxCombinedLogFilesSize );
00637     if( FAILED( RioStatus ) )
00638     {
00639         #ifdef RIO_DEBUG2
00640         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %8x (%s) ao "
00641                       "inicializar o objeto de gerenciamento dos logs!",
00642                       RioStatus, GetErrorDescription( RioStatus ).c_str() );
00643         #endif
00644 
00645         return RioStatus;
00646     }
00647     #ifdef RIO_DEBUG2
00648     else
00649         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Objeto de "
00650                       "gerenciamento de logs inicializado com sucesso! Tentando "
00651                       "criar a thread!" );
00652     #endif
00653 
00654     // Agora tentamos criar a thread do objeto da classe CUserLogs, responsavel
00655     // por receber as mensagens que serao salvas no log.
00656     // Inicializa os atributos da thread usada para gerenciar as transferencias
00657     // de dados.
00658     pthread_attr_init( &attribServerUserLogsThread );
00659     // Inicializa a pilha da thread usada para gerenciar as transferencias de
00660     // dados.
00661     pthread_attr_setstacksize( &attribServerUserLogsThread,
00662                                2 * PTHREAD_STACK_MIN );
00663 
00664     // Cria a thread usada para gerenciar as transferencias de dados.
00665     if( pthread_create( &m_ServerUserLogsThread, &attribServerUserLogsThread,
00666                         ServerUserLogsThreadEp, ( void * ) this ) != 0 )
00667     {
00668         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u (%s) ao "
00669                       "criar a thread que recebe as mensagens via UDP!",
00670                       errno, strerror( errno ) );
00671 
00672         return ERROR_TCPCONNECTION + ERROR_CREATE_THREAD;
00673     }
00674     #ifdef RIO_DEBUG2
00675     else
00676         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Thread criada com "
00677                       "sucesso! O ID da thread e igual a %u",
00678                       ( unsigned int ) m_ServerUserLogsThread );
00679     #endif
00680 
00681     // Informa que a classe foi inicializada com sucesso.
00682     m_Initialized = true;
00683 
00684     return S_OK;
00685 }

void CServerUserLogs::JoinThread (  ) 

Funcao para bloquear o processo ate a thread que recebe os logs termine de executar.

Definition at line 689 of file UserLogs.cpp.

00690 {
00691     pthread_join( m_ServerUserLogsThread, NULL );
00692 }

RioResult CServerUserLogs::ReceiveLogLine ( char *  LogLine,
int *  LogLinePort 
) [private]

Funcao usada para receber uma string com um log pelo socket UDP.

Parameters:
Log ponteiro a string que armazenara a linha de log recebida. Se algum erro ocorrer, sera retornada uma string vazia, com tamanho 0. Em caso contrario sera retornada a string recebida, que pode ser vazia quando uma mensagem de termino de conexao for recebida.
Port ponteiro para armazenar a porta da qual se originou a mensagem com a linha do log.
Returns:
S_OK se o log foi recebido pelo socket UDP com sucesso, ou o codigo de erro se algum erro ocorrer durante o recebimento do log.

Definition at line 109 of file UserLogs.cpp.

00110 {
00111     // Armazena a quantidade de bytes recebidos.
00112     ssize_t BytesReceived;
00113     // Armazena o endereco de origem da linha de log redebida. Somente vamos
00114     // aceitar dados (com supostas linhas para o log) enviadas pela propria
00115     // maquina em que o modulo esta executando.
00116     struct sockaddr_in SourceAddr;
00117     // Armazena o tamanho da estrutura SourceAddr
00118     socklen_t SourceAddrSize;
00119 
00120     // Inicializa o buffer que recebera a linha dos logs. Note que estamos
00121     // supondo que ele possui pelo menos espaco para MAXLOGLINESIZE + 1 bytes.
00122     memset( LogLine, 0, MAXLOGLINESIZE + 1 );
00123 
00124     // Tenta receber a linha de log pelo socket UDP.
00125     #ifdef RIO_DEBUG2
00126     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Tentando receber a "
00127                   "linha com %u bytes pelo socket UDP!", MAXLOGLINESIZE );
00128     #endif
00129 
00130     SourceAddrSize = sizeof( SourceAddr );
00131     BytesReceived = recvfrom( m_Socket, LogLine, MAXLOGLINESIZE,
00132                               UDP_FLAGS_RECEIVE,
00133                               ( struct sockaddr * ) &SourceAddr,
00134                               &SourceAddrSize );
00135     // Copia a porta do socket UDP do qual a conexao se originou.
00136     *Port = SourceAddr.sin_port;
00137 
00138     if( BytesReceived < 0 )
00139     {
00140         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error %d (%s) "
00141                       "receiving log line from UDP socket!", errno,
00142                       strerror( errno ) );
00143 
00144         return ERROR_SERVERUSERLOGS + ERROR_SOCKET_RECEIVE;
00145     }
00146     else if( SourceAddr.sin_addr.s_addr != m_SocketAddr.sin_addr.s_addr )
00147     {
00148         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Log Line "
00149                       "received from invalid address ip %s and port %u, "
00150                       "different from ip %s and port %u!",
00151                       inet_ntoa( SourceAddr.sin_addr ),
00152                       ntohs( SourceAddr.sin_port ),
00153                       inet_ntoa( m_SocketAddr.sin_addr ),
00154                       ntohs( m_SocketAddr.sin_port ) );
00155 
00156         return ERROR_SERVERUSERLOGS + ERROR_INVALID_HOST;
00157 
00158     }
00159     else if( ( unsigned int ) BytesReceived != MAXLOGLINESIZE )
00160     {
00161         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error receiving "
00162                       "log line from UDP socket! Only %u bytes of %u has "
00163                       "received!", BytesReceived, MAXLOGLINESIZE );
00164 
00165         return ERROR_SERVERUSERLOGS + ERROR_SOCKET_RECEIVE;
00166      }
00167 
00168     #ifdef RIO_DEBUG2
00169     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Linha de log %s "
00170                   "recebida com sucesso pela conexao UDP pela porta %u!",
00171                   LogLine, ntohs( *Port ) );
00172     #endif
00173 
00174     return S_OK;
00175 }

RioResult CServerUserLogs::SendResult ( int  Port,
int  Result 
) [private]

Funcao para enviar o resultado dado como parametro para o socket UDP cuja porta tambem e dada como parametro.

Parameters:
Port porta UDP para a qual o resultado deve ser enviado.
RioResult Resultado (codigo de erro) a ser enviado.
Returns:
S_OK se o resultado foi enviado pelo socket UDP com sucesso, ou o codigo de erro se algum erro ocorrer durante o envio do resultado.

Definition at line 179 of file UserLogs.cpp.

00180 {
00181     // Armazena o endereco do socket UDP para o qual desejamos enviar os dados.
00182     struct sockaddr_in DestAddr;
00183     // Armazena a quantidade de bytes enviados.
00184     ssize_t BytesSent;
00185 
00186     // Limpa a estrutura TempAddr.
00187     memset( &DestAddr, 0, sizeof( DestAddr ) );
00188     // Inicializa a estrutura temporaria do endereco com o IP local e a porta
00189     // passada como parametro.
00190     DestAddr.sin_family = AF_INET;
00191     DestAddr.sin_addr.s_addr = m_SocketAddr.sin_addr.s_addr;
00192     DestAddr.sin_port = Port;
00193 
00194     #ifdef RIO_DEBUG2
00195     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Tentando enviar o "
00196                   "resultado %08X pelo socket UDP para o IP %s e a porta %u, a "
00197                   "partir do IP %s e da porta %u!", Result,
00198                   inet_ntoa( DestAddr.sin_addr ), ntohs( DestAddr.sin_port ),
00199                   inet_ntoa( m_SocketAddr.sin_addr ),
00200                   ntohs( m_SocketAddr.sin_port ) );
00201     #endif
00202 
00203     // Tenta enviar o Resultado para o socket UDP.
00204     BytesSent = sendto( m_Socket, &Result, sizeof( Result ),
00205                         UDP_FLAGS_SENDDATA, ( struct sockaddr * ) &DestAddr,
00206                         sizeof( DestAddr ) );
00207     if( BytesSent < 0 )
00208     {
00209         #ifdef RIO_DEBUG2
00210         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error %d (%s) "
00211                       "sending result value %08X to UDP socket!", errno,
00212                        strerror( errno ), Result );
00213         #endif
00214 
00215         return ERROR_SERVERUSERLOGS + ERROR_SOCKET_SEND;
00216     }
00217     else if( BytesSent != sizeof( Result ) )
00218     {
00219         #ifdef RIO_DEBUG2
00220         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error sending "
00221                       "result value %08X to UDP socket! Only %u bytes of "
00222                       "%u has sent!", Result, BytesSent, sizeof( Result ) );
00223         #endif
00224 
00225         return ERROR_SERVERUSERLOGS + ERROR_SOCKET_SEND;
00226     }
00227 
00228     #ifdef RIO_DEBUG2
00229     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Erro %u enviado com "
00230                   "sucesso a porta %u!", Result, ntohs( Port ) );
00231     #endif
00232 
00233     // Como enviamos corretamente o resultado, retornamos S_OK.
00234     return S_OK;
00235 }

bool CServerUserLogs::ServerUserLogsThread (  )  [private]

Funcao executada pela thread da classe.

Returns:
true se o objeto deve ser removido antes de a thread ser finalizada (quando a thread for finalizada por uma mensagem especial enviada por um objeto da classe cliente) ou false em caso contrario (quando a thread for finalizada pelo destrutor do objeto).

Definition at line 238 of file UserLogs.cpp.

00239 {
00240     // Armazena o resultado das execucoes das funcoes da classe e do objeto do
00241     // RIO.
00242     RioResult RioStatus, RioStatus2;
00243     // Armazena o resultado da execucao das funcoes da biblioteca do C.
00244     int SystemStatus;
00245     // Variavel usada para indicar se devemos continuar
00246     bool ExecuteThread;
00247     // Variavel para armazenar se, ao retornarmos da thread, deveremos ou nao
00248     // deletar o objeto (se a mensagem for recebida da mesma porta da classe,
00249     // indicando que o destrutor foi chamado, nao devemos remover o objeto).
00250     bool RemoveObject;
00251     // Variavel para armazenar uma linha de log recebida pela conexao UDP.
00252     char LogLine[ MAXLOGLINESIZE + 1 ];
00253     // Vetor de sockes usado pelo comando poll
00254     struct pollfd SoketsInfo[ USERLOGSSOCKETSNUMBER ];
00255     // Armazena a porta do socket UDP do qual recebemos uma linha de log.
00256     int LogLinePort;
00257 
00258     #ifdef RIO_DEBUG2
00259     RioErr << "SERVERUSERLOGSTHREADID " << syscall( SYS_gettid ) << endl;
00260     #endif
00261 
00262     // Inicializa a variavel usada para indicar que a thread esta em execucao.
00263     // Esta variavel se tornara false quando recebermos uma linha de log com
00264     // tamanho igual a 0.
00265     ExecuteThread = true;
00266 
00267     // Inicializa a variavel usada para indicar se o objeto deve ou nao ser
00268     // removido ao retornarmos da funcao (por default, nao fazemos isso, pois
00269     // precisamos enviar uma mensagem de resposta se removermos o objeto pela
00270     // mensagem especial (uma linha de log com tamanho nulo).
00271     RemoveObject = false;
00272 
00273     // Inicializa o vetor usado pelo comando poll.
00274     SoketsInfo[ USERLOGSSOCKETUDP ].fd = m_Socket;
00275     SoketsInfo[ USERLOGSSOCKETUDP ].events = POLLIN;
00276 
00277     while( ExecuteThread )
00278     {
00279         #ifdef RIO_DEBUG2
00280         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Antes de executar "
00281                       "a funcao poll, com o socket %u!", m_Socket );
00282         #endif
00283 
00284         // Espera por mensagens (linhas de log) pelo socket UDP, usando o
00285         // comando poll. O valor negativo no tempo do comando indica que nao
00286         // existe um timeout.
00287         SystemStatus = poll( SoketsInfo, USERLOGSSOCKETSNUMBER, -1 );
00288         if( SystemStatus < 0 )
00289         {
00290             // Se ocorrer algum erro ao executar o poll, reporta este erro no
00291             // log e tenta executar novamente o comando.
00292             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error %d (%s) "
00293                           "when executing poll function. Trying again!", errno,
00294                           strerror( errno ) );
00295 
00296         }
00297         else
00298         {
00299             #ifdef RIO_DEBUG2
00300             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Sucesso ao "
00301                           "executar a funcao poll!" );
00302             #endif
00303             // Nao ocorreu um erro ao executar o poll. Devemos agora entao ver
00304             // se recebemos dados pelo socket que sera, caso tenha vindo da
00305             // maquina local, uma linha para ser salva no log.
00306             if( ( SoketsInfo[ USERLOGSSOCKETUDP ].revents & POLLIN ) != 0 )
00307             {
00308                 #ifdef RIO_DEBUG2
00309                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Existem "
00310                               "mensagens a serem recebidas!" );
00311                 #endif
00312                 // Existem dados no socket UDP. Tentamos entao receber uma
00313                 // mensagem que, se correta, contera uma linha a ser salva no
00314                 // log.
00315                 RioStatus = ReceiveLogLine( LogLine, &LogLinePort );
00316                 if( FAILED( RioStatus ) )
00317                 {
00318                     // Neste caso, ocorreu um erro ao tentarmos receber uma
00319                     // linha de log. Simplesmente mostramos uma mensagem e
00320                     // executamos novamente a funcao poll.
00321                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server, "Error "
00322                                   "%8x (%s) when executing "
00323                                   "ReceiveLogLinefunction!", RioStatus,
00324                                   GetErrorDescription( RioStatus ).c_str() );
00325                 }
00326                 else if( strlen( LogLine ) == 0 )
00327                 {
00328                     #ifdef RIO_DEBUG2
00329                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00330                                   "Recebida uma mensagem para finalizar a "
00331                                   "classe! Mensagem recebida %s! Finalizando a "
00332                                   "thread!",
00333                                   ( LogLinePort != ntohs( m_LogsServerPort ) ) ?
00334                                   "de um cliente" : "do destrutor" );
00335                     #endif
00336                     // Recebemos uma mensagem indicando para terminarmos a
00337                     // conexao. Simplesmente fazermos ExecuteThread ser false.
00338                     ExecuteThread = false;
00339                     // Deleta o objeto da classe CLogRotation
00340                     delete m_LogRotation;
00341                     m_LogRotation = NULL;
00342 
00343                     // Envia uma mensagem de estado, se Port for diferente de
00344                     // m_LogsServerPort.
00345                     if( LogLinePort != ntohs( m_LogsServerPort ) )
00346                     {
00347                         // Como a mensagem foi recebida de um objeto associado a
00348                         // um cliente, definimos entao que o objeto deve ser
00349                         // removido.
00350                         RemoveObject = true;
00351 
00352                         // Envia a mensagem de estado ao cliente, informando que
00353                         // a delecao esta sendo processada e que a classe de
00354                         // logs ja foi finalizada.
00355                         RioStatus = SendResult( S_OK, LogLinePort );
00356                         if( FAILED( RioStatus ) )
00357                         {
00358                             // Ocorreu um erro ao tentarmos salvar uma linha no log.
00359                             // Neste caso, tambem ignoramos o erro e tentamos
00360                             // receber outras linhas de log.
00361                             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00362                                           "Error %8x (%s) when executing "
00363                                           "SendResult to send result S_OK!",
00364                                           RioStatus,
00365                                           GetErrorDescription( RioStatus ).
00366                                                                       c_str() );
00367                         }
00368                         #ifdef RIO_DEBUG2
00369                         else
00370                             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00371                                           "Resposta S_OK a mensagem de "
00372                                           "finalizacao enviada com sucesso ao "
00373                                           "objeto cliente!"
00374                                         );
00375                         #endif
00376                     }
00377                 }
00378                 else
00379                 {
00380                     #ifdef RIO_DEBUG2
00381                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00382                                   "Recebida a linha %s para o log da porta %u. "
00383                                   "Tentando repassa-la ao objeto que gerencia "
00384                                   "os logs!", LogLine, ntohs( LogLinePort ) );
00385                     #endif
00386 
00387                     // Recebemos uma linha de log pela conexao UDP. Vamos agora
00388                     // tentar inseri-la no log.
00389                     RioStatus = m_LogRotation->NewLogLine( time( NULL ),
00390                                                            LogLine );
00391                     if( FAILED( RioStatus ) )
00392                     {
00393                         // Ocorreu um erro ao tentarmos salvar uma linha no log.
00394                         // Neste caso, tambem ignoramos o erro e tentamos
00395                         // receber outras linhas de log.
00396                         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00397                                       "Error %8x (%s) when executing "
00398                                       "NewLogLine to insert log line %s!",
00399                                       RioStatus,
00400                                       GetErrorDescription( RioStatus ).c_str(),
00401                                       LogLine );
00402                     }
00403                     #ifdef RIO_DEBUG2
00404                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00405                                   "Linha %s recebida da porta UDP %u passada "
00406                                   "com sucesso para o objeto de gerenciamento "
00407                                   "dos logs!", LogLine, ntohs( LogLinePort ) );
00408                     #endif
00409 
00410                     #ifdef RIO_DEBUG2
00411                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00412                                   "Linha de log removida com sucesso!" );
00413                     #endif
00414 
00415                     // Envia uma mensagem de estado, se Port for diferente de
00416                     // m_LogsServerPort.
00417                     if( LogLinePort != ntohs( m_LogsServerPort ) )
00418                     {
00419                         RioStatus2 = SendResult( RioStatus, LogLinePort );
00420                         if( FAILED( RioStatus2 ) )
00421                         {
00422                             // Ocorreu um erro ao tentarmos salvar uma linha no log.
00423                             // Neste caso, tambem ignoramos o erro e tentamos
00424                             // receber outras linhas de log.
00425                             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00426                                           "Error %8x (%s) when executing "
00427                                           "SendResult to send result %8X (%s)!",
00428                                           RioStatus2,
00429                                           GetErrorDescription( RioStatus2 ).
00430                                                                       c_str(),
00431                                           RioStatus,
00432                                           GetErrorDescription( RioStatus2 ).
00433                                                                       c_str() );
00434                         }
00435                         #ifdef RIO_DEBUG2
00436                         else
00437                             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00438                                           "Resposta %u (%s) ao envio de uma "
00439                                           "linha de log enviada com sucesso "
00440                                           "ao objeto cliente!", RioStatus,
00441                                         GetErrorDescription( RioStatus ).c_str()
00442                                         );
00443                         #endif
00444                     }
00445                     #ifdef RIO_DEBUG2
00446                     else
00447                         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00448                                       "Erro! Linha de log recebida da porta "
00449                                       "%u somente usada para finalizar a "
00450                                       "thread! Mensagem ignorada!",
00451                                       m_LogsServerPort );
00452                     #endif
00453                 }
00454             }
00455         }
00456     }
00457 
00458     // Fecha o socket do servidor.
00459     shutdown( m_Socket, SHUT_RDWR );
00460     close( m_Socket );
00461     m_Socket = 0;
00462 
00463     // Altera o indicador da ID da thread, para informar que a thread ja foi
00464     // finalizada (para evitar que o destrutor envie uma mensagem de termino).
00465     m_ServerUserLogsThread = 0;
00466 
00467     // Retorna da thread informando se devemos ou nao remover o objeto.
00468     return RemoveObject;
00469 }

void * CServerUserLogs::ServerUserLogsThreadEp ( void *  Param  )  [static, private]

Funcao que chama a funcao executada pela thread da classe, usada quando a thread e criada.

Parameters:
Param ponteiro para o parametro da thread (no caso, um ponteiro para um objeto da classe), passado ao criar a thread.

Definition at line 473 of file UserLogs.cpp.

00474 {
00475     CServerUserLogs *ServerUserLogs;
00476 
00477     // Converte o ponteito para um objeto da classe.
00478     ServerUserLogs = ( CServerUserLogs * ) Param;
00479 
00480     #ifdef RIO_DEBUG2
00481     RioErr << "CServerUserLogs::ServerUserLogsThreadEp chamando a funcao "
00482            << "ServerUserLogsThread do objeto que executa a thread!" << endl;
00483     #endif
00484 
00485     // Chama a funcao da classe, removendo o objeto somente se o retorno da
00486     // funcao for true (se for false, a thread foi finalizada pelo destrutor do
00487     // objeto e, neste caso, a remocao nao e necessaria).
00488     if( ServerUserLogs->ServerUserLogsThread() )
00489     {
00490         #ifdef RIO_DEBUG2
00491         RioErr << "CServerUserLogs::ServerUserLogsThreadEp a funcao retornou "
00492                << "true! Deletando o objeto!" << endl;
00493         #endif
00494 
00495         // Como a funcao retornou true (termino por uma mensagem com tamanho 0),
00496         // deveremos deletar o objeto.
00497         delete ServerUserLogs;
00498     }
00499 
00500     #ifdef RIO_DEBUG2
00501     RioErr << "CServerUserLogs::ServerUserLogsThreadEp depois de executar a "
00502            << "funcao ServerUserLogsThread!" << endl;
00503     #endif
00504 
00505     return NULL;
00506 }


Field Documentation

Variavel booleana que indica se a classe foi inicializada.

Definition at line 58 of file UserLogs.h.

Ponteiro para o objeto da classe de gerenciamento de logs usada por esta classe.

Definition at line 66 of file UserLogs.h.

Armazena a porta usada pela thread que envia os logs.

Definition at line 73 of file UserLogs.h.

server_rec* CServerUserLogs::m_Server [private]

Ponteiro para a estrutura com as informacoes do servidor.

Definition at line 63 of file UserLogs.h.

Identificador da thread que recebe os dados a serem colocados no log.

Definition at line 61 of file UserLogs.h.

Socket usado para enviar dados para a thread da classe, usando a funcao estatica SendLogLine da classe.

Definition at line 69 of file UserLogs.h.

struct sockaddr_in CServerUserLogs::m_SocketAddr [private]

Armazena o endereco do socket usado para gerar os logs.

Definition at line 71 of file UserLogs.h.


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