CClientUserLogs Class Reference

#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.

Detailed Description

Definition at line 157 of file UserLogs.h.


Constructor & Destructor Documentation

CClientUserLogs::CClientUserLogs ( request_rec *  Request  ) 

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

Parameters:
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.

00708 {
00709     // Fecha o socket do cliente.
00710     if( m_Socket != 0 )
00711     {
00712         shutdown( m_Socket, SHUT_RDWR );
00713         close( m_Socket );
00714     }
00715 }


Member Function Documentation

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).

Parameters:
LogsServerPort porta UDP (sem ser na ordem da rede) usada pelo servidor que recebe os logs.
Returns:
S_OK se a inicializacao foi feita com sucesso, e um valor diferente de S_OK em caso contrario.

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.

Parameters:
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 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.

Parameters:
Log ponteiro para a string com o log a ser enviado pelo socket UDP para ser salvo.
Returns:
S_OK se o log foi enviado pelo socket UDP com sucesso, ou o codigo de erro se algum erro ocorrer durante o envio do log.

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 }


Field Documentation

Variavel booleana que indica se a classe foi inicializada.

Definition at line 161 of file UserLogs.h.

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.

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.


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