[AsteriskBrasil] queue_log -> PostgreSQL rotina em C...sugestao.

Claudio Polegato Junior cpolegatojr.asterisk em gmail.com
Segunda Outubro 23 11:04:12 BRT 2006


j u n i o u escreveu:
>
> Claudio boa tarde..
>
> Encontrei uma rotina sua escrita em C no fórum da Conectiva... e 
> imaginei que vc poderia me ajudar..
>
> Esse código era sobre inverter as colunas em um arquivo CSV...
>
> A minha ideia o seguinte...
>
> Escrever este trecho do queueLoader.pl que vem no QueueMetrics em C.. 
> (faz um “upload” do queue_conf para uma tabela no banco de dados)..
>
> Ou seja monitorar e gerar relatórios das filas do Asterisk em um BD. 
> Ao invés de ler o log em txt..
>
> open F, $qlog or die "$! $qlog";
>
> while (<F>) {
>
> chomp;
>
> # (split /\|/, $_)
>
> my ($tst, $cid, $que, $age, $verb, $d1, $d2, $d3) = map { myQuote($_) 
> } (((split /\|/, $_)), ( "", "", "", "", "", "", "")) ;
>
> $sql = " INSERT INTO `queue_log`
>
> ( `partition` , `time_id` , `call_id` , `queue` , `agent` , `verb` , 
> `data1` , `data2` , `data3` , `data4` )
>
> VALUES
>
> ( '$part', $tst, $cid, $que, $age, $verb, $d1, $d2, $d3, '' );";
>
> Ou seja nesse trecho ele já abriru o arquivo 
> /var/log/asterisk/queue_log e esta gerando um “SQL” com cada campo no 
> caso separado por um “ | ”..
>
> O problema é que não estou conseguindo fazer isso em c...
>
> Segue o que eu já consegui fazer.. (estou começando a brincar com 
> c\c++ agora..=] )..
>
> Neste caso já consegui interagir com o banco e com o arquivo queue_log..
>
> O problema esta na lógica para separar os campos delimitados por “ | ” 
> e inserir linha a linha (registros) no banco..
>
> #include <stdio.h>
>
> #include <libpq-fe.h>
>
> /*###########################################################*/
>
> /*#Conversor do queue_log para PostgreSQL */
>
> /*#Data: 20-10-2006 */
>
> /* gcc -o motorlog -I/usr/include/postgresql motorlog.c -lpq */
>
> /*###########################################################*/
>
> /*Objeto de conexão*/
>
> PGconn *conn = NULL;
>
> /*Ponteiro de resultado*/
>
> PGresult *result;
>
> int main()
>
> {
>
> /*realiza a conexão*/
>
> conn = PQconnectdb("host=localhost user=asterisk password=asterisk 
> dbname=asterisk");
>
> if(PQstatus(conn) == CONNECTION_OK)
>
> {
>
> printf("Conexão com efetuada com sucesso. ");
>
> }
>
> else
>
> {
>
> printf("Falha na conexão. Erro: %s", PQerrorMessage(conn));
>
> PQfinish(conn);
>
> return -1;
>
> }
>
> FILE *arquivo;
>
> char letra;
>
> char string[1024]; //string onde ficara a linha
>
> int x = 0;
>
> int i = 0;
>
> arquivo = fopen("/var/log/asterisk/queue_log, "rt");
>
> // abre o arquivo e imprime na tela..
>
> while(fgets(string, sizeof(string), arquivo)){ //le arquivo
>
> x = x+1;
>
> printf("Linha:%d : %s",x, string); //imprime na tela as linhas
>
> }
>
> fclose(arquivo); //fecha arquivo
>
> /*Query para execucao no BANCO!!!!.*/
>
> result = PQexec(conn, "SELECT * FROM queue_log");
>
> if(!result)
>
> {
>
> printf("Erro executando comando. ");
>
> }
>
> else
>
> {
>
> switch(PQresultStatus(result))
>
> {
>
> case PGRES_EMPTY_QUERY:
>
> printf("Nada aconteceu. ");
>
> break;
>
> case PGRES_FATAL_ERROR:
>
> printf("Error in query: %s ", PQresultErrorMessage(result));
>
> break;
>
> case PGRES_COMMAND_OK:
>
> printf("%s linhas afetadas. ", PQcmdTuples(result));
>
> break;
>
> default:
>
> printf("Algum outro resultado ocorreu. ");
>
> break;
>
> }
>
> /*Libera objeto*/
>
> PQclear(result);
>
> }
>
> /*encerra conexao se aberta*/
>
> if(conn != NULL)
>
> PQfinish(conn);
>
> }
>
> Se vc tem ai algum material (bibliografia) que possa me ajudar será 
> bem vindo.
>
> Obrigado.
>
> Rosilto Junior.
>
> Porto Velho –RO.
>
Olá,

Posso te dar uma pequena mãozinha sim...

Primeiramente devemos separa a linha (terminada com \n e não \r\n) e
depois separar os campos nesta linha. Uso uma técnica que é carregar
todo o arquivo na memória e então "manuseá-lo"com ponteiros. Depois é só
incluir os campos no BD, que fica por sua conta. Posta ae o código final.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_CAMPOS 10
#define DELIMITADOR '|'

char* campos[MAX_CAMPOS];

int Preencher_Campos(char *linha){
char *inicio, *delimitador;
int campo_atual = 0;
inicio = linha;
delimitador = strchr(inicio, DELIMITADOR);
while (delimitador && campo_atual < MAX_CAMPOS-1){
*delimitador = '\0';
campos[campo_atual++] = inicio;
inicio = delimitador + 1;
delimitador = strchr(inicio, DELIMITADOR);
}
campos[campo_atual++] = inicio;
return campo_atual;
}

int Por_Arquivo_Memoria(char **memoria){
FILE *arquivo;
int tamanho;

if ((arquivo = fopen("/var/log/asterisk/queue_log", "rt")) == NULL){
perror("Erro");
return 0;
}
fseek(arquivo, 0, SEEK_END);
tamanho = ftell(arquivo);
rewind(arquivo);
*memoria = (char*)malloc(tamanho + 1);
fread(*memoria, tamanho, 1, arquivo);
fclose(arquivo);
(*memoria)[tamanho] = '\0';
return 1;
}

int main(int argc, char* argv[]){
char *memoria, *inicio, *delimitador;
int campos_lidos;

if (!Por_Arquivo_Memoria(&memoria)){
// Erro
return -1;
}

inicio = memoria;
delimitador = strchr(inicio, '\n');
while (delimitador){
*delimitador = '\0';
// printf("\n\n\nLinha: %s\n\n", inicio);
campos_lidos = Preencher_Campos(inicio);

// printf("Campos Lidos: %d\n", campos_lidos);
// int i;
// for (i=0; i<campos_lidos; i++)
// printf("Campo %2i: %s\n", i, campos[i]);
// getchar();

// Banco de dados
// De posse dos campos desta linha, incluo-os no banco de dados
// Sendo a variável "campos_lidos" especificando quantos campos
// foram encontrados
// E o vetor "campos" apontando para o início de cada campo
// desta linha na memória terminados por '\0'

// Aqui é contigo! ;-)

inicio = delimitador + 1;
delimitador = strchr(inicio, '\n');
}
return 0;
}


Abraços.

-- 
Atenciosamente

            Claudio Polegato Junior

            Engenheiro Autônomo - Ribeirão Preto e Região
            Mestre em Física Aplicada à Medicina e Biologia - USP
            Engenheiro Computacional - USP
            Engenheiro Eletrônico - USP

Um peregrino de problemas; Um pergaminho de soluções!


Mais detalhes sobre a lista de discussão AsteriskBrasil