#include <UserLogs.h>
Public Member Functions | |
CClientUserLogs (request_rec *Request) | |
Construtor da classe, usado ao criar um objeto da classe. | |
virtual | ~CClientUserLogs () |
Destrutor da classe, usado ao remover um objeto da classe. | |
virtual RioResult | Initialize (int LogsServerPort) |
Funcao usada para inicializar um objeto da classe CUserLogs. | |
virtual RioResult | NewLogLine (char *LogInfo) |
Funcao para criar uma nova solicitacao de impressao de uma linha no log. | |
Private Member Functions | |
RioResult | SendLogLine (char *LogLine) |
Funcao usada para enviar uma string com um log pelo socket UDP. | |
Private Attributes | |
bool | m_Initialized |
Variavel booleana que indica se a classe foi inicializada. | |
request_rec * | m_Request |
Ponteiro para a requisicao com os dados do pedido HTTP. | |
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. |
Definition at line 157 of file UserLogs.h.
CClientUserLogs::CClientUserLogs | ( | request_rec * | Request | ) |
Construtor da classe, usado ao criar um objeto da classe.
Request | ponteiro para a requisicao associada a conexao http com o cliente. |
Definition at line 696 of file UserLogs.cpp.
00697 { 00698 // Inicializa as variaveis da classe. 00699 m_Initialized = false; 00700 m_Socket = 0; 00701 memset( &m_SocketAddr, 0, sizeof( m_SocketAddr ) ); 00702 m_Request = Request; 00703 m_LogsServerPort = 0; 00704 }
CClientUserLogs::~CClientUserLogs | ( | ) | [virtual] |
Destrutor da classe, usado ao remover um objeto da classe.
Definition at line 707 of file UserLogs.cpp.
RioResult CClientUserLogs::Initialize | ( | int | LogsServerPort | ) | [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_CLIENTUSERLOGS + ERROR_NOT_INITIALIZED).
LogsServerPort | porta UDP (sem ser na ordem da rede) usada pelo servidor que recebe os logs. |
Definition at line 902 of file UserLogs.cpp.
00903 { 00904 // Armazena o endereco do socket UDP. 00905 struct sockaddr_in TempAddr; 00906 // Armazena o tamanho do endereco do socket usado para desbloquear o select. 00907 socklen_t AddrSize; 00908 00909 // Verifica se o objeto da classe ja esta inicializado. 00910 if( m_Initialized ) 00911 { 00912 #ifdef RIO_DEBUG2 00913 if( m_Request != NULL ) 00914 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, 00915 "Objeto ja foi inicializado!" ); 00916 else 00917 RioErr << "Objeto ja foi inicializado!" << endl; 00918 00919 #endif 00920 00921 return ERROR_CLIENTUSERLOGS + ERROR_INITIALIZED; 00922 } 00923 00924 // Cria o socket UDP do objeto, usado para receber linhas de log. 00925 m_Socket = socket( AF_INET, SOCK_DGRAM, 0 ); 00926 if( m_Socket < 0 ) 00927 { 00928 #ifdef RIO_DEBUG2 00929 if( m_Request != NULL ) 00930 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Erro %u (%s) " 00931 "ao criar o socket UDP usado pelo objeto!", errno, 00932 strerror( errno ) ); 00933 else 00934 RioErr << "Erro " << errno << " (" << strerror( errno ) << ") ao " 00935 << "criar o socket UDP usado pelo objeto!" << endl; 00936 #endif 00937 00938 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_CREATE; 00939 } 00940 00941 // Limpa a estrutura TempAddr. 00942 memset( &TempAddr, 0, sizeof( TempAddr ) ); 00943 // associa o socket UDP usado para desbloquear o poll ao IP do servidor e 00944 // a uma porta escolhida aleatoriamente (isso esta bom, ou devemos usar a 00945 // porta do UDP mais 1 - para nao colidir com a porta UDP da RioNeti?). 00946 TempAddr.sin_family = AF_INET; 00947 TempAddr.sin_addr.s_addr = USERLOGS_UDP_IP; // Usando o IP 127.0.0.1. 00948 TempAddr.sin_port = 0; // Escolhe uma porta de modo aleatorio. 00949 if( bind( m_Socket, ( struct sockaddr * ) &TempAddr, 00950 sizeof( TempAddr ) ) < 0 ) 00951 { 00952 #ifdef RIO_DEBUG2 00953 if( m_Request != NULL ) 00954 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Erro %u (%s) " 00955 "ao ligar o socket UDP ao IP %s e a uma porta " 00956 "generica", errno, strerror( errno ), 00957 inet_ntoa( TempAddr.sin_addr ) ); 00958 else 00959 RioErr << "Erro " << errno << " (" << strerror( errno ) << ") ao " 00960 << "ligar o socket UDP ao IP " 00961 << inet_ntoa( TempAddr.sin_addr ) << " e a uma porta " 00962 << "generica" << endl; 00963 #endif 00964 00965 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_BIND; 00966 } 00967 00968 AddrSize = sizeof( m_SocketAddr ); 00969 if( getsockname( m_Socket, ( struct sockaddr * ) &m_SocketAddr, 00970 &AddrSize ) != 0 ) 00971 { 00972 #ifdef RIO_DEBUG2 00973 if( m_Request != NULL ) 00974 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Erro %u (%s) ao " 00975 "obter as informacoes do socket UDP!", errno, 00976 strerror( errno ) ); 00977 else 00978 RioErr << "Erro " << errno << " (" << strerror( errno ) << ") ao " 00979 << "obter as informacoes do socket UDP!" << endl; 00980 #endif 00981 00982 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_OPTIONS; 00983 } 00984 00985 // Inicializa a porta UDP do servidor de logs. 00986 m_LogsServerPort = LogsServerPort; 00987 00988 // Informa que a classe foi inicializada com sucesso. 00989 m_Initialized = true; 00990 00991 00992 return S_OK; 00993 }
RioResult CClientUserLogs::NewLogLine | ( | char * | LogInfo | ) | [virtual] |
Funcao para criar uma nova solicitacao de impressao de uma linha no log.
Esta linha e enviada pelo socket USERLOGS_UDP_PORT.
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. |
Definition at line 996 of file UserLogs.cpp.
00997 { 00998 // Armazena o resultado das execucoes das funcoes da classe e do objeto do 00999 // RIO. 01000 RioResult RioStatus; 01001 01002 // Simplesmente, nesta funcao, verificamos se o objeto esta inicializado e, 01003 // caso esteja, depois chamados a funcao SendLogLine descrita anteriormente. 01004 01005 // Verifica se o objeto da classe esta inicializado. 01006 if( !m_Initialized ) 01007 { 01008 #ifdef RIO_DEBUG2 01009 if( m_Request != NULL ) 01010 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, 01011 "Objeto nao foi inicializado!" ); 01012 else 01013 RioErr << "Objeto ja foi inicializado!" << endl; 01014 #endif 01015 01016 return ERROR_CLIENTUSERLOGS + ERROR_NOT_INITIALIZED; 01017 } 01018 01019 // Verifica se a linha de log e muito grande 01020 if( ( LogInfo != NULL ) && ( strlen( LogInfo ) > MAXLOGLINESIZE ) ) 01021 { 01022 #ifdef RIO_DEBUG2 01023 if( m_Request != NULL ) 01024 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, 01025 "Linha de log com %u bytes muito grande! A linha " 01026 "deve ter ate %u caracteres!", strlen( LogInfo ), 01027 MAXLOGLINESIZE ); 01028 else 01029 RioErr << "Linha de log com " << strlen( LogInfo ) << " bytes " 01030 << "muito grande! A linha deve ter ate " 01031 << MAXLOGLINESIZE << " caracteres!" << endl; 01032 #endif 01033 01034 return ERROR_CLIENTUSERLOGS + ERROR_LOGLINE_TOOLARGE; 01035 } 01036 01037 // Chama a funcao para enviar a mensagem de log. 01038 RioStatus = SendLogLine( LogInfo ); 01039 01040 #ifdef RIO_DEBUG2 01041 if( FAILED( RioStatus ) ) 01042 { 01043 if( m_Request != NULL ) 01044 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error %8x " 01045 "(%s) when executing function SendLogLine! Log " 01046 "ignored!", RioStatus, 01047 GetErrorDescription( RioStatus ).c_str() ); 01048 else 01049 RioErr << "Error 0x" << hex << RioStatus << dec << " (" 01050 << GetErrorDescription( RioStatus ) << ") when executing " 01051 << "function SendLogLine! Log ignored!" << endl; 01052 } 01053 #endif 01054 01055 return RioStatus; 01056 }
RioResult CClientUserLogs::SendLogLine | ( | char * | LogLine | ) | [private] |
Funcao usada para enviar uma string com um log pelo socket UDP.
Log | ponteiro para a string com o log a ser enviado pelo socket UDP para ser salvo. |
Definition at line 718 of file UserLogs.cpp.
00719 { 00720 // Armazena a quantidade de bytes enviados. 00721 ssize_t BytesSent; 00722 // Armazena a quantidade de bytes recebidos. 00723 ssize_t BytesReceived; 00724 // Armazena o endereco de origem do resultado recebido. Somente vamos 00725 // aceitar resultados enviados pela propria maquina em que o modulo esta 00726 // executando. 00727 struct sockaddr_in SourceAddr; 00728 // Armazena o tamanho da estrutura SourceAddr 00729 socklen_t SourceAddrSize; 00730 // Armazena o resultado recebido pelo socket. 00731 int Result; 00732 // Armazena o endereco do socket UDP para o qual enviaremos a mensagem. 00733 struct sockaddr_in DestAddr; 00734 // Armazena a copia da linha no vetor para ser enviada. Se LogLine for NULL, 00735 // sera enviada uma mensagem com uma string vazia, o que fara com que o 00736 // objeto que gerencia os logs seja finalizado. 00737 char SendLogLine[ MAXLOGLINESIZE + 1 ]; 00738 00739 // Inicializa a linha a ser enviada pela conexao UDP (o terminador nao e 00740 // enviado). 00741 memset( SendLogLine, 0, MAXLOGLINESIZE + 1 ); 00742 00743 // Copia LogLine para SendLogLine, se LogLine for diferente de NULL. 00744 if( LogLine != NULL ) 00745 strcpy( SendLogLine, LogLine ); 00746 00747 // Limpa a estrutura m_SocketAddr. 00748 memset( &DestAddr, 0, sizeof( DestAddr ) ); 00749 // Monta o endereco de destino da mensagem. 00750 DestAddr.sin_family = AF_INET; 00751 DestAddr.sin_addr.s_addr = m_SocketAddr.sin_addr.s_addr; // Envia para o 00752 // mesmo IP. 00753 DestAddr.sin_port = htons( m_LogsServerPort ); 00754 00755 #ifdef RIO_DEBUG2 00756 if( m_Request != NULL ) 00757 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Tentando enviar a " 00758 "linha %s pelo socket UDP para o IP %s e a porta %u, a " 00759 "partir do IP %s e da porta %u!", SendLogLine, 00760 inet_ntoa( DestAddr.sin_addr ), 00761 ntohs( DestAddr.sin_port ), 00762 inet_ntoa( m_SocketAddr.sin_addr ), 00763 ntohs( m_SocketAddr.sin_port ) ); 00764 else 00765 RioErr << "Tentando enviar a linha " << SendLogLine << " pelo socket " 00766 << "UDP para o IP " << inet_ntoa( DestAddr.sin_addr ) << " e a " 00767 << "porta " << ntohs( DestAddr.sin_port ) << ", a partir do IP " 00768 << inet_ntoa( m_SocketAddr.sin_addr ) << " e da porta " 00769 << ntohs( m_SocketAddr.sin_port ) << endl; 00770 #endif 00771 00772 // Envia a string com a linha do log, se passamos um ponteiro diferente de 00773 // NULL para a funcao, pois o ponteiro NULL e usado para terminar a thread, 00774 // enviando uma mensagem com tamanho igual a 0. 00775 BytesSent = sendto( m_Socket, SendLogLine, MAXLOGLINESIZE, 00776 UDP_FLAGS_SENDDATA, ( struct sockaddr * ) &DestAddr, 00777 sizeof( DestAddr ) ); 00778 if( BytesSent < 0 ) 00779 { 00780 #ifdef RIO_DEBUG2 00781 if( m_Request != NULL ) 00782 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error %d " 00783 "(%s) when sending log line %s to UDP socket!", 00784 errno, strerror( errno ), SendLogLine ); 00785 else 00786 RioErr << "Erro " << errno << " (" << strerror( errno ) << ") when " 00787 << "sending log line " << SendLogLine << " to UDP socket!" 00788 << endl; 00789 #endif 00790 00791 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_SEND; 00792 } 00793 else if( BytesSent != MAXLOGLINESIZE ) 00794 { 00795 #ifdef RIO_DEBUG2 00796 if( m_Request != NULL ) 00797 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error when " 00798 "sending log line %s to UDP socket! Only %u " 00799 "bytes of %u has sent!", SendLogLine, BytesSent, 00800 MAXLOGLINESIZE ); 00801 else 00802 RioErr << "Error when sending log line " << SendLogLine << " to " 00803 << "UDP socket! Only " << BytesSent << " of " 00804 << MAXLOGLINESIZE << " has sent!" << endl; 00805 #endif 00806 00807 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_SEND; 00808 } 00809 00810 #ifdef RIO_DEBUG2 00811 if( m_Request != NULL ) 00812 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Linha de log %s " 00813 "enviada com sucesso pela conexao UDP! Esperando pelo " 00814 "resultado da operacao! ", SendLogLine ); 00815 else 00816 RioErr << "Linha de log " << SendLogLine << " enviada com sucesso pela " 00817 << "conexao UDP! Esperando pelo resultado da operacao! " << endl; 00818 #endif 00819 00820 00821 // Tenta receber o tamanho da suposta linha de log enviada por um processo 00822 // do apache. 00823 SourceAddrSize = sizeof( SourceAddr ); 00824 BytesReceived = recvfrom( m_Socket, &Result, sizeof( Result ), 00825 UDP_FLAGS_RECEIVE, 00826 ( struct sockaddr * ) &SourceAddr, 00827 &SourceAddrSize ); 00828 if( BytesReceived < 0 ) 00829 { 00830 #ifdef RIO_DEBUG2 00831 if( m_Request != NULL ) 00832 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error %d (%s) " 00833 "when receiving result from UDP socket!", errno, 00834 strerror( errno ) ); 00835 else 00836 RioErr << "Error " << errno << " (" << strerror( errno ) << ") " 00837 << "when receiving result from UDP socket!" << endl; 00838 #endif 00839 00840 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_RECEIVE; 00841 } 00842 else if( ( SourceAddr.sin_addr.s_addr != DestAddr.sin_addr.s_addr ) && 00843 ( SourceAddr.sin_port != DestAddr.sin_port ) ) 00844 { 00845 #ifdef RIO_DEBUG2 00846 if( m_Request != NULL ) 00847 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Result value " 00848 "received from invalid address ip %s and port %u, " 00849 "different from ip %s and port %u!", 00850 inet_ntoa( SourceAddr.sin_addr ), 00851 ntohs( SourceAddr.sin_port ), 00852 inet_ntoa( DestAddr.sin_addr ), 00853 ntohs( DestAddr.sin_port ) ); 00854 else 00855 RioErr << "Result value received from invalid address ip " 00856 << inet_ntoa( SourceAddr.sin_addr ) << " and port " 00857 << inet_ntoa( SourceAddr.sin_addr ) << ", different from ip " 00858 << inet_ntoa( DestAddr.sin_addr ) << " and port " 00859 << ntohs( DestAddr.sin_port ) << "!" << endl; 00860 #endif 00861 00862 return ERROR_CLIENTUSERLOGS + ERROR_INVALID_HOST; 00863 00864 } 00865 else if( BytesReceived != sizeof( Result ) ) 00866 { 00867 #ifdef RIO_DEBUG2 00868 if( m_Request != NULL ) 00869 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "Error " 00870 "receiving result from UDP socket! Only %u bytes of " 00871 "%u has received!", BytesReceived, 00872 sizeof( Result ) ); 00873 else 00874 RioErr << "Error receiving result from UDP socket! Only " 00875 << BytesReceived << " bytes of " << sizeof( Result ) 00876 << " has received!" << endl; 00877 #endif 00878 00879 return ERROR_CLIENTUSERLOGS + ERROR_SOCKET_RECEIVE; 00880 } 00881 00882 #ifdef RIO_DEBUG2 00883 if( m_Request != NULL ) 00884 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, m_Request, "O resultado da " 00885 "operacao foi recebido com sucesso: RioError = %08X " 00886 "(%s)! ", ( RioResult ) Result, 00887 GetErrorDescription( ( RioResult ) Result ).c_str() ); 00888 else 00889 RioErr << "O resultado da operacao foi recebido com sucesso: RioError " 00890 << "= " << hex << ( RioResult ) Result << dec << "(" 00891 << GetErrorDescription( ( RioResult ) Result ) << ")!" << endl; 00892 #endif 00893 00894 // Retorna o resultado da operacao que foi recebido. 00895 return( ( RioResult ) Result ); 00896 }
bool CClientUserLogs::m_Initialized [private] |
Variavel booleana que indica se a classe foi inicializada.
Definition at line 161 of file UserLogs.h.
int CClientUserLogs::m_LogsServerPort [private] |
Armazena a porta usada pela thread que envia os logs.
Definition at line 170 of file UserLogs.h.
request_rec* CClientUserLogs::m_Request [private] |
Ponteiro para a requisicao com os dados do pedido HTTP.
Definition at line 163 of file UserLogs.h.
int CClientUserLogs::m_Socket [private] |
Socket usado para enviar dados para a thread da classe, usando a funcao estatica SendLogLine da classe.
Definition at line 166 of file UserLogs.h.
struct sockaddr_in CClientUserLogs::m_SocketAddr [private] |
Armazena o endereco do socket usado para gerar os logs.
Definition at line 168 of file UserLogs.h.