PHP: Arquivo de log personalizado

 

PHP: http://www.php.net/
PHP: http://www.php.net/

Semana passada, estive fazendo num pequeno site, uma área de login. Foi então que fiz uma funçãozinha no PHP que gera logs diários dos eventos ocorridos desde o login até o logoff, como por exemplo, ações tomadas pelos usuários na parte administrativa.

Abaixo, vocês poderão conferir o código que utilizei, logicamente adaptado para que fosse publicado aqui.

Os arquivos de log são gerados baseado no dia em que se encontra. Como os arquivos estão em formato .txt, utilizei um prefixo no arquivo, para que o acesso não seja tão óbvio por pessoas desautorizadas.

A função armazena no arquivo a hora da ocorrência, seguido pelo IP da máquina do cliente e a mensagem definida por você.

Vamos então seguir para o código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
 
date_default_timezone_set('America/Sao_Paulo');
 
function Logger($msg){
 
$data = date("d-m-y");
$hora = date("H:i:s");
$ip = $_SERVER['REMOTE_ADDR'];
 
//Nome do arquivo:
$arquivo = "Logger_$data.txt";
 
//Texto a ser impresso no log:
$texto = "[$hora][$ip]> $msg \n";
 
$manipular = fopen("$arquivo", "a+b");
fwrite($manipular, $texto);
fclose($manipular);
 
}
 
?>

Salve o arquivo acima como logger.php

Na linha 3 estou declarando o timezone para São Paulo, mesmo estando no Rio de Janeiro, o horário é o mesmo. Isso serve para configurar a data para minha localidade, já que no meu caso, o servidor se encontra em outro fuso horário.

Nas linhas 7, 8 e 9 estou declarando as variáveis de data, hora e ip da máquina que gerou o log (cliente).

Na linha 12 está o nome do arquivo. Será algo do tipo Logger_19-06-2009.txt (dia-mês-ano). Caso deseje armazenar o log em uma pasta já existente, altere a linha para:
$arquivo = “minhapasta/Logger_$data.txt”;

Na linha 17 está a função de abertura do arquivo.  Passando o “a+” como parâmetro, apenas nos dias que tiver alguma coisa para ser inserida no log, é que o arquivo será criado ou se já existir, escreverá o registro no fim do arquivo. O parâmetro “b” serve para questões de portabilidade ( inserção recomendado no manual do php )

As linhas 18 e 19 manipulam e fecham o arquivo definido na linha 12.

Agora vamos para o código onde vamos utilizar nossa função:

1
2
3
4
5
6
7
8
9
<?php
 
include "logger.php";
 
Logger("Testando a função logger !");
Logger("Como você pode ver, estou logando uma informação !");
Logger("Teste 1, Teste 2, Teste 3!");
 
?>

Salve o arquivo acima como teste.php na mesma página onde se encontra o logger.php.

Pronto. O Script acima gera 3 saídas consecutivas no seu arquivo de log.
Conferindo o resultado:
Nome do arquivo gerado:
Logger_19-06-09.txt

Conteúdo:
[21:57:36][201.7.xxx.xxx]> Testando a função logger !
[21:57:36][201.7.xxx.xxx]> Como você pode ver, estou logando uma informação !
[21:57:36][201.7.xxx.xxx]> Teste 1, Teste 2, Teste 3!

Bom, espero que o script sirva para mais alguém. 🙂

===========================================

Atualização em 13/abril/2011

A leitora Renata nos comentários de hoje (13/04/11) deixou uma dúvida muito boa… Vale a pena editar a matéria e acrescentar a solução dela aqui…

Ela estava encontrando problemas para centralizar os arquivos de log em um só lugar. Ela trabalhava com pastas para organizar seus arquivos, e ao incluir a função logger nos arquivos, fazia com que os logs fossem gravados separadamente em cada pasta.

Por que isso ocorreu ?

Ela estava incluindo a função da maneira correta: include “../logger.php”; mas o problema estava mesmo dentro da função Logger.

Na variável $arquivo, onde definimos o nome do arquivo de log, a função parte do princípio que o arquivo .txt está do lado do arquivo .php que contém a função…

Consideremos o seguinte path de diretórios:

/
/logs/Logger.txt
/logger.php
/folder1/pagina1.php

Ao incluir a função logger de dentro da “pagina1”, chamando a função como a Renata fez (“../logger.php”), faz com que ao definir a variavel $arquivo = “teste.txt” o PHP vai salvar o arquivo dentro da pasta “folder1” pois ele interpreta o codigo a partir daquele contexto.

Para resolver isso, ao entrar na função Logger, voce precisa mudar o contexto da execução para ele salvar o log corretamente na pasta log (independente de onde ela estiver), e no final da função, você precisa voltar o contexto para onde ele estava, para evitar possiveis problemas.

Segue então o novo código que resolve o problema:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
 
date_default_timezone_set('America/Sao_Paulo');
 
function Logger($msg){
 
//pega o path completo de onde esta executanto
$caminho_atual = getcwd(); 
 
//muda o contexto de execução para a pasta logs
chdir("/home/rafaelbiriba/public_html/logs");
 
$data = date("d-m-y");
$hora = date("H:i:s");
$ip = $_SERVER['REMOTE_ADDR'];
 
//Nome do arquivo:
$arquivo = "Logger_$data.txt";
 
//Texto a ser impresso no log:
$texto = "[$hora][$ip]> $msg \n";
 
$manipular = fopen("$arquivo", "a+b");
fwrite($manipular, $texto);
fclose($manipular);
 
//Volta o contexto de execução para o caminho em que estava antes
chdir($caminho_atual);
 
}
 
?>
Share
  • Show de bola esse seu código, o unico q encontrei e funcionou 100%, agora vem a dúvida. Gostaria de colocar as seguintes msgs. [21:57:36][201.7.xxx.xxx]> FULANO DE TAL logou na página !
    [22:03:14][201.7.xxx.xxx]> FULANO DE TAL fechou sessão!

    Se puder ajudar pelo menos como fazer o nome do usuário aparecer ja agradeço d++… tentei colocar sessão e um monte de gambiarra mas nada deu… 🙁

    Abraço

  • Olá Nataniel,

    Que bom que funcionou como o desejado !
    Vamos ver se condigo ajudá-lo:

    No seu código php, antes de você redirecionar o “Fulano de Tal” para a “área restrita”, coloque o seguinte código:

    Logger(“FULANO DE TAL logou na página !”);

    E na página onde você vai processar o logoff, ou o término da sessão, coloque:

    Logger(“FULANO DE TAL fechou sessão!”);

    Sua dúvida é essa mesmo ?

    Obrigado pela visita e volte sempre !

  • Quase… se fosse só isso seria fácil! Tenho 300 usuários cadastrados, então qro que no log de acesso apareça cada usuário q logou na página… exemplo:

    [22:03:14][201.7.xxx.xxx]> Rafael logou no site!
    [22:43:58][201.7.xxx.xxx]> Jeff logou no site!
    [23:07:35][201.7.xxx.xxx]> Tulio logou no site!

    Vlw!

    • Rafaelo Munhoz

      BOa Tarde.. Para conseguir o que você quer, utilize a questão de sessão

  • Olá Nataniel,

    Mas é só isso, basta inserir a função logger nos lugares certos…

    Para isso você deve analisar seu código para saber o lugar mais adequado para coloca-los !

    Abraços,

  • Rodrigo

    Muito bom mesmo esse seu codigo agora eu tenho uma duvida como e que eu faço para consultar os dados gerados pelo log e outra duvida como e que eu faço pra colocar o que o usuario fez tipo fulano de tal cadastro
    fulano de tal deleto

  • Olá Rodrigo,

    Você pode acessar o arquivo de log na mesma pasta que roda o php… você pode gravar em outra pasta conforme mostro abaixo:

    $arquivo = “../logs/Logger_$data.txt”;

    Para logar que um usuário se cadastrou veja em:
    https://rafaelbiriba.com/2009/07/02/php-arquivo-de-log-personalizado.html#comment-249
    No seu php, onde você grava o usuário, basta incluir o logger e chamar a função, como mostro no exemplo que passei…

    Boa sorte,
    Abraços,

  • Marcelo Grimberg

    Olá esse exemplo da para fazer na hora de consultar, atualizar e deletar ??

    Obrigado

  • Marcelo Grimberg

    Rafael

    Um seguinte a principio funcionou corretamente, mas fiz uma pequena mudança

    na minha página executar.php (onde esta localizado insert, update e delete)
    como deve colocar o teste.php apenas registrar inserir ??

    abaixo código
    [code]
    if($_GET[ ‘funcao’ ] == “insert”){

    $sql_gravar = mysql_query(“insert into petshop_peteka.cliente (nome, endereco, cep, cidade, estado, telefone, rg, cpf, email, datanasc, civil, sexo, naturalidade ) values (‘$grava_nome’, ‘$grava_endereco’, ‘$grava_cep’, ‘$grava_cidade’, ‘$grava_estado’, ‘$grava_telefone’, ‘$grava_rg’, ‘$grava_cpf’, ‘$grava_email’, ‘$grava_datanasc’, ‘$grava_estadocivil’, ‘$grava_sexo’, ‘$grava_naturalidade’)”);
    echo “alert(‘Cadastro realizado com sucesso’);window.location=’form.php'”;
    }
    [/code]

  • Olá Marcelo,
    Para loggar as informações, basta inserir o arquivo logger.php em sua página executar.php e depois chamas a função Logger…

    Baseado no trecho de código que você passou, segue o exemplo (em negrito a parte que eu adicionei):


    include “logger.php”;

    if($_GET[ ‘funcao’ ] == “insert”){
    Logger(“Gravando dados no banco referente ao nome: $grava_nome”);

    $sql_gravar = mysql_query(“insert into petshop_peteka.cliente (nome, endereco, cep, cidade, estado, telefone, rg, cpf, email, datanasc, civil, sexo, naturalidade ) values (‘$grava_nome’, ‘$grava_endereco’, ‘$grava_cep’, ‘$grava_cidade’, ‘$grava_estado’, ‘$grava_telefone’, ‘$grava_rg’, ‘$grava_cpf’, ‘$grava_email’, ‘$grava_datanasc’, ‘$grava_estadocivil’, ‘$grava_sexo’, ‘$grava_naturalidade’)”);
    echo “alert(‘Cadastro realizado com sucesso’);window.location=’form.php'”;
    }

    Conseguiu entender? Basta importar (usando o include) o arquivo que contem a função e chamar ela durante o seu arquivo…

    Dica: Para evitar que você inclua muitas vezes o mesmo arquivo, ao invés de usar include, você pode usar include_once !!

    Abraços,

  • Marcelo Grimberg

    Rafa,

    Obrigado, por responder e dando uma força, funcionou mas esse que você passou esta dando erro de sintaxe, então fiz assim:

    funciou esse código no executar.php

    $logger = Logger_insert($msg);

    onde Logger passei usar Logger_insert
    e para gravar usei essa sintaxe no seu exemplo era teste.php passei chamar log_insert.php

    abraços

    Muito obrigado pela ajuda.

  • Que bom que conseguiu…
    Não deve ter funcionado porque o arquivo da função logger estava com outro nome…

    Só um detalhe: na linha abaixo, você não precisa jogar numa variável não…
    $logger = Logger_insert($msg);

    Se você executar da forma abaixo, deveria funcionar, porque a função logger não retorna nada, então não precisa jogar numa variável…
    Logger_insert($msg);

    Abraços,

  • Nossa!! Pq só o meu não funciona???

    
    Warning: fopen(Logger_12-04-11.txt) [function.fopen]: failed to open stream: Permission denied in /home/regratecnologia/www/siesa/logger.php on line 17

    Warning: fwrite(): supplied argument is not a valid stream resource in /home/regratecnologia/www/siesa/logger.php on line 18

    Warning: fclose(): supplied argument is not a valid stream resource in /home/regratecnologia/www/siesa/logger.php on line 19

    Warning: fopen(Logger_12-04-11.txt) [function.fopen]: failed to open stream: Permission denied in /home/regratecnologia/www/siesa/logger.php on line 17

    Warning: fwrite(): supplied argument is not a valid stream resource in /home/regratecnologia/www/siesa/logger.php on line 18

    Warning: fclose(): supplied argument is not a valid stream resource in /home/regratecnologia/www/siesa/logger.php on line 19

    Warning: fopen(Logger_12-04-11.txt) [function.fopen]: failed to open stream: Permission denied in /home/regratecnologia/www/siesa/logger.php on line 17

    Warning: fwrite(): supplied argument is not a valid stream resource in /home/regratecnologia/www/siesa/logger.php on line 18

    Warning: fclose(): supplied argument is not a valid stream resource in /home/regratecnologia/www/siesa/logger.php on line 19

    • Olá Renata,

      Acho que você está com problemas de permissão de escrita…

      O seu web server (exemplo: apache) não está com permissão de abrir o arquivo e escrever o log…

      Tente dar um chmod para dar permissao de leitura e escrita neste arquivo, ou mude o dono do arquivo (chown), para que seja o mesmo usuário que o apache está rodando…

      Abraços,

      • Olá, Rafael!

        É verdade! Desculpe a falta de atenção (e inexperiencia). Resolvido! Muito obrigada!!!

        Aproveitando… O arquivo logger.php indica uma pasta “LOG” para salvar os arquivos. Se chamarmos essa função em uma pasta diferente, os arquivos serão gravados nesta outra pasta. Não dá pra deixar tudo sendo salvo em uma única pasta do diretório?

        Mais uma vez, obrigada!

        • Bom,

          você pode especificar uma pasta para ele colocar todos os logs dentro… Essa pasta tem que estar no mesmo nivel diretório do arquivo logger.php.

          Se estiver em outro lugar, basta especificar o onde o arquivo .txt está, em relação a localização do arquivo logger.php Exemplo:
          $arquivo = “../../pasta1/logs/Logger_$data.txt”;

          Para chamar a função logger em arquivos em outros diretorios, na hora de voce incluir usando include “logger.php”; voce deve sempre fazer referencia para onde o arquivo de logger.php está a partir do caminho atual…

          Se o arquivo que voce esta editando estiver dentro de outra pasta, voce pode incluir a função logger voltando os diretorios. Exemplo: include “../../../logger.php”;

          Deu para compreender ? Acho que ficou meio confuso…

          Abraços,

          • Então… isso tudo eu fiz direitinho… o include está apontando de acordo com a localização do logger.php certinho. Só que assim: Se eu chamar a função em uma pasta de um subdiretório, o arquivo será guardado lá, e não na pasta LOG.

            Ex.: Log/logger.php
            chamo a função logger() no Comercial/cliente/cadastro.php

            O arquivo será salvo assim:
            Comercial/cliente/logger_13-04-2011 e eu queria que fosse salvo em Log/logger_13-04-2011.

            Desculpe, não sei se fui clara.

            • O arquivo logger.php está exatamente igual ao exemplo acima ?

              Você seguiu essa recomendação:
              Na linha 12 está o nome do arquivo. Será algo do tipo Logger_19-06-2009.txt (dia-mês-ano). Caso deseje armazenar o log em uma pasta já existente, altere a linha para:
              $arquivo = “minhapasta/Logger_$data.txt”;

              Fico no aguardo…

              • Não é bem isso… mas desisti de tentar salvar tudo numa única pasta.

                Estou salvando em pastas separadas, conforme você descreveu acima.

                Assim:
                financeiro/logs/logger_13-04-11.php
                comercial/logs/logger_13-04-11.php
                manutencao/logs/logger_13-04-11.php
                login/logs/logger_13-04-11.php

                Rafael,
                Muito obrigada pela ajuda e atenção. E parabéns pelo site!

                • Tem certeza que prefere deixar assim ?

                  Se quiser, entra no bate-papo (na barra azul abaixo)…

                  Estou online agora, talvez possa te ajudar melhor por la…

                  Abraços,

  • Deu certo!!! Nossa! Nem acredito que eu ia desistir!

    Valeu mesmo pela ajuda, pela atenção e pela boa vontade. E desculpe pela minha inexperiência.

    Coloca aí o resultado para caso alguém tenha a mesma necessidade.

    Obrigada!!!

    • Matéria atualizada com a resolução do seu problema…

      Obrigado por visitar o blog 😉

  • Cairo

    Olá, desculpem a minha ignorância mais, pra que serve esse script? É só pra armazenar o IP de quem loga, é isso?

  • Antonio

    Como fazer para que os log sejem salvos no mesmo arquivo txt?
    A função abriria o mesmo arquivo, somente inserindo os dados retirados do session, cada usuario diferente seria escrito numa nova linha.

    Desja agradeço a ajuda.

    • Implementa o exemplo pra você entender… A função vai abrir o mesmo arquivo de log e adicionar uma nova linha ao final dele toda vez que você chamar a função de logger… 🙂

  • Caio

    no arquivo .txt gerado fica gravado o texto na mesma linha, teria como ficar um em cada linha?

    • Acredito que um \n ao final da linha deve resolver o problema.

  • Felipe

    Obrigado, por compartilhar… Serviu como uma luga em um projeto que estou fazendo. Obrigao.

  • Olá, tenho um servidor de um jogo e tem bastante players, meu objetivo é colocar no site uma lista com rolagem dos logs , quando um player abre uma chest no jogo, no system mostra que ele abriu tal chest e ganhou tal item, tenho o arquivo de logs que mostra tudo exemplo : [o3/07/2016 09:14:04] Event Box Received the award! 1x Ash lance apparel chest], queria colocar isso no meu website e mostrar em uma lista com rolagem os players que abriu as chests igual nos logs , acho que o seu script acima da para fazer isso porém queria saber como posso colocar isso em uma lista com rolagem, poderia me ajudar? , se nao for muito incomodo. ficarei muito grato meu email é [email protected]

  • Jonny

    Olá,

    Em quais arquivos incluo esse código?

    Tenho um arquivo para logar na área restrita, tenho um arquivo para validar a sessão