Advertisement
jacknpoe

Classe para arquivos log com cache automática

Oct 22nd, 2013
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 31.26 KB | None | 0 0
  1. {############################################################################
  2. #
  3. #   DOCUMENTAÇÃO DA UNIDADE UARQUIVOLOG (UArquivoLog.pas)
  4. #
  5. #   Autor: Ricardo Erick Rebêlo
  6. #   Última Modificação: 29/03/05
  7. #
  8. #############################################################################
  9.  
  10.  
  11. USES
  12. ====
  13.  
  14. Tipos: TArquivoDireto
  15.  
  16. Classes:
  17.  
  18.  
  19. CLASSES
  20. =======
  21.  
  22. TArquivoLog
  23.  
  24.     Descrição: Arquivo de log com uso mínimo de recursos de arquivo,
  25.                com cache e criptografia "mochila" simples.
  26.                Verifica a integridade dos dados.
  27.  
  28.     Autor: Ricardo Erick Rebêlo
  29.  
  30.     Portabilidade: pelo uso de TArquivoDireto (1.4), ver última documentação deste
  31.  
  32.     Versão Atual: 1.3
  33.  
  34.     Alterada em: 29/03/05
  35.  
  36.     Alterações:
  37.         • as entradas geradas pelo próprio objeto estão mais claras
  38.         • as propriedades AutoLog e LogTudo acrescentadas, permitindo o
  39.           controle das entradas geradas pelo próprio objeto
  40.  
  41.     Versões Anteriores:
  42.         • 1.2: 13/03/05 • Ricardo Erick Rebêlo
  43.           • uso de UArquivoDireto para reduzir a complexidade do código e
  44.             permitir criptografia "mochila" simples (aumentando a segurança)
  45.           • Código e Nível alterados para tipos string (aumentando a flexibilidade)
  46.  
  47.         • 1.1: 19/12/03 • Ricardo Erick Rebêlo
  48.           • modificado para usar cache de memória
  49.             (agora, entradas anteriores à criação do arquivo de log podem ser criadas!)
  50.           • função DataHoraPraString alterada para compatibilidade da ordenação em Paradox
  51.  
  52.         • 1.0: 18/12/03 • Ricardo Erick Rebêlo
  53.  
  54.     Métodos:
  55.     Abre: tenta abrir o arquivo para inclusão. Se não conseguir e estiver habilitado
  56.           para sobrescrever, cria um arquivo novo e gera um aviso - retorna erro
  57. Const   Cria: cria o objeto, sem nome de arquivo (overload)
  58. Const   Cria( Pnome): cria o objeto, com nome de arquivo (overload)
  59.     Despeja: despeja a cache de memória (se houver) no arquivo log - retorna erro - versão 1.1 em diante
  60. Destr   Destroi: destrói o objeto, fechando o arquivo, se estiver aberto
  61.              despeja a cache se habilitado (versão 1.1 em diante)
  62.     Fecha: fecha o arquivo, se estiver aberto - retorna erro
  63.            despeja a cache se habilitado (versão 1.1 em diante)
  64.     Grava( PCod, PNiv, PComent): gera uma entrada no arquivo log com a hora atual (overload)
  65.     Grava( PDataHora, PCod, PNiv, PComent): idem, mas a hora pode ser qualquer uma (overload)
  66.     Reseta: Exclui todas as entradas no arquivo log e gera um aviso - retorna erro
  67.     ResetaCache: Destrói a cache de memória - versão 1.1 em diante
  68.  
  69.     Propriedades:
  70.     Aberto (r): boolean que indica se o arquivo está aberto
  71.     AutoLog (rw): boolean que indica se os erros do próprio uso do objeto gerarão entradas no log (publicada)
  72.     Cached (rw): boolean que indica se a cache está habilitada - versão 1.1 em diante (publicada)
  73.     CacheDespeja (rw): boolean que indica se a cache vai ser automaticamente despejada. - versão 1.1 em diante (publicada)
  74.                        Quando True, sempre que houver oportunidade, a cache será despejada no arquivo!
  75.                        (só funciona quando Cached for True)
  76.     Debug (rw): boolean que indica se está em modo Debug. (publicada)
  77.                 No modo debug, todo log gerado automaticamente por ArquivoLog também gera uma mensagem na tela
  78.     LiberaCache (rw): boolean que indica se a cache pode ser descartada à revelia do aplicativo. - versão 1.1 em diante (publicada)
  79.                       Quando True é possível que se perca todos os dados da cache, se ela não for despejada em tempo!
  80.                       (só funciona quando Cached for True)
  81.     LogTudo (rw): boolean que indica se até as operações comuns do objeto gerarão entradas no log (publicada)
  82.                   (só funciona quando AutoLog for True)
  83.     Nome (rw): nome do arquivo (publicada)
  84.     Sobrescreve (rw): boolean que indica se o arquivo log pode ser automaticamente re-criado. (publicada)
  85.                       Se esta propriedade for False, ArquivoLog só funciona em arquivos já existentes!
  86.     UsaCache (r): boolean que indica se a cache está sendo usada - versão 1.1 em diante
  87.  
  88.     Privados:
  89.         function AbreApp: função interna que abre o arquivo para inclusão - retorna erro
  90.         function DataHoraPraString( PDataHora): função interna que retorna a conversão de Data+Hora em string.
  91.                                                 Mude esta função caso a forma de conversão não seja apropriada!
  92.         procedure GravaEmCache( PDataHora, PCod, PNiv, PComent): procedimento interno de uso da cache - versão 1.1 em diante
  93.         procedure SetNome( Pnome): modifica o nome do arquivo (escrita da propriedade Nome)
  94.         procedure SetCached( PCached): modifica o uso da cache (escrita da propriedade Cached) - versão 1.1 em diante
  95.         procedure Zera: procedimento interno que "zera" as variáveis internas na criação do objeto.
  96.                         Veja neste procedimento os valores iniciais de cada propriedade de TArquivoLog!
  97.         SAberto (boolean): interno de Aberto
  98.         SArquivo (TArquivoDireto): objeto que simplifica o código e permite a criptografia "mochila" simples - versão 1.2 em diante
  99.         SAutoLog (boolean): interno de AutoLog - versão 1.3 em diante
  100.         SCache (TStringList): objeto interno que guarda a cache de memória - versão 1.1 em diante
  101.         SCached (boolean): interno de Cached - versão 1.1 em diante
  102.         SCacheDespeja (boolean): interno de CacheDespeja - versão 1.1 em diante
  103.         SDebug (boolean): interno de Debug
  104.         SLiberaCache (boolean): interno de LiberaCache - versão 1.1 em diante
  105.         SLogTudo (boolean): interno de LogTudo - versão 1.3 em diante
  106.         SNome (string): nome interno do arquivo, privado por causa da escrita
  107.         SSobrescreve (boolean): interno de Sobrescreve
  108.         STotCache (integer): indica o número de entradas de log na cache - versão 1.2 em diante
  109.         SUsaCache (boolean): interno de UsaCache - versão 1.1 em diante
  110.  
  111.     Exemplo de Uso:
  112.     (veja TesteLog -- e visualize seus logs com LogViewer 1.1b)
  113.  
  114.     Outras Informações:
  115.         • O arquivo gerado por TArquivoLog é estruturado e protegido contra alterações
  116.           (a partir da versão 1.2, usando TArquivoDireto 1.4).
  117.  
  118.         • Embora teoricamente seja possível gravar mensagens de até 2GB, tente não usar
  119.           strings muito maiores que 64KB, por questões de eficiência e uso de memória.
  120.           Tente ser conciso nas mensagens - eventos em lote acontecem regularmente!
  121.  
  122.         • As funções obsoletas NomeLogCod e NomeLogNiv dão algumas idéias para PCod e PNiv.
  123.           Estas funções estão desabilitadas no código (foram transformadas em comentário)!
  124.  
  125.         • Veja em UArquivoDireto.txt a documentação de TArquivoDireto.
  126. }
  127.  
  128.  
  129. {
  130.     Autor: Ricardo Erick Rebelo
  131.     Versão: 1.3 (terceira versão da primeira implementação)
  132.     Última Modificação: 29/03/05 por Ricardo Erick Rebêlo
  133.     Documentação: UArquivoLog.txt
  134.  
  135.     AVISOS: • a partir da versão 1.3 o padrão é não haver entradas de auto-log  (CUIDADO!)
  136.             • não substituir nos executáveis anteriores a 12/03/05 (*)
  137.             • a partir da versão 1.2, alguns uses foram alterados para compatibilidade com DELPHI 5
  138. }
  139.  
  140. unit UArquivoLog;
  141.  
  142. interface
  143.  
  144. uses Classes, UArquivoDireto;  {para usar TStringList e TArquivoDireto}
  145.  
  146. type
  147.  
  148. { ############### TArquivoLog ############### }
  149.  
  150.   TArquivoLog = class
  151.   private
  152.     STotCache: integer; // versão 1.2
  153.     SNome: string;
  154.     SAberto, SDebug, SSobrescreve, SCached, SUsaCache, SCacheDespeja,
  155.       SLiberaCache: boolean;  // de SCached a SLiberaCache > versão 1.1
  156.     SAutoLog, SLogTudo: boolean;   // controle de auto-log > versão 1.3
  157.     {SArquivo: TextFile; alterado na versão 1.2 para:} SArquivo: TArquivoDireto;
  158.     SCache: TStringList;  // versão 1.1
  159.     procedure   SetNome( PNome: string);
  160.     procedure   SetCached( PCached: boolean);  // versão 1.1
  161.     procedure   Zera;
  162.     function    AbreApp: boolean;
  163. {   function    NomeLogCod( PCod: TLogCod): string;
  164.     function    NomeLogNiv( PNiv: TLogNiv): string; - obsoletas na versão 1.2 }
  165.     function    DataHoraPraString( PDataHora: TDateTime): string;
  166.     procedure   GravaEmCache( PDataHora: TDateTime; PCod, PNiv, PComent: string);
  167.         // versão 1.1 - alterada para usar strings em Código e Nível (versão 1.2)
  168.   public
  169.     constructor Cria; overload;
  170.     constructor Cria( PNome: string); overload;
  171.     function    Abre: boolean;
  172.     function    Fecha: boolean;
  173.     function    Reseta: boolean;
  174.     function    Despeja: boolean; // versão 1.1
  175.     procedure   ResetaCache; // versão 1.1
  176.     procedure   Grava( PCod, PNiv, PComent: string); overload;
  177.     procedure   Grava( PDataHora: TDateTime; PCod, PNiv, PComent: string); overload;
  178.     destructor  Destroi;
  179.  
  180.     property UsaCache: boolean read SUsaCache; // versão 1.1
  181.     property Aberto: boolean read SAberto;
  182.   published
  183.     property Nome: string read SNome write SetNome;
  184.     property Debug: boolean read SDebug write SDebug;
  185.     property Sobrescreve: boolean read SSobrescreve write SSobrescreve;
  186.     property Cached: boolean read SCached write SetCached; // versão 1.1
  187.     property CacheDespeja: boolean read SCacheDespeja write SCacheDespeja; // versão 1.1
  188.     property LiberaCache: boolean read SLiberaCache write SLiberaCache; // versão 1.1
  189.     property AutoLog: boolean read SAutoLog write SAutoLog; // versão 1.3
  190.     property LogTudo: boolean read SLogTudo write SLogTudo; // versão 1.3
  191.   end;
  192.  
  193. {############################################
  194. #   I  M  P  L  E  M  E  N  T  A  Ç  Ã  O   #
  195. ############################################}
  196.  
  197. implementation
  198.  
  199. uses SysUtils, Forms, Windows, UTipos; {para uso de rotinas de I/O, mensagens de erro, rotinas de data, etc...}
  200.  
  201. { ############### TArquivoLog ############### }
  202.  
  203. //===================================== ALTERADA EM 1.1 a 1.3
  204.  
  205. function TArquivoLog.Abre: boolean;
  206. begin
  207.   if SAberto then
  208.   begin
  209.     if (SAutoLog and SLogTudo) then Grava( 'Log-Arquivo', 'Erro Leve', 'Tentando abrir arquivo de Log já aberto: ' + SNome + '!');
  210.     Fecha;
  211.     if SDebug then Application.MessageBox( PChar( 'Tentando abrir arquivo de Log já aberto: ' +
  212.                        SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  213.     { usamos uma mensagem apenas se estivermos no modo de debug }
  214.   end;  { grava Log de erro se tentar abrir arquivo já aberto e fecha arquivo }
  215.  
  216.   if AbreApp then  { tenta abrir para incremento, senão continua }
  217.     if SSobrescreve then  { se pode sobrescrever, tenta abrir sobescrevendo }
  218.       if SArquivo.Grava( SNome) then begin { tenta abrir SArquivo com SNome sobescrevendo }
  219.         SArquivo.SetSementes( -1254553677, 137, 0); {mesmo no erro de abrir, setamos as sementes pra desencargo de consciência}
  220.         if SAutoLog then Grava( 'Log-Arquivo', 'Erro Médio', 'Impossível abrir ou criar arquivo de Log: ' + SNome + '!');
  221.         Abre := True;       { em caso de erro, a função retorna verdadeiro (erros) }
  222.         if SDebug then Application.MessageBox( PChar(
  223.                            'Impossível abrir ou criar arquivo de Log: ' + SNome + '!'),
  224.                            'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  225.         { usamos uma mensagem apenas se estivermos no modo de debug }
  226.       end else begin
  227.         SArquivo.SetSementes( -1254553677, 137, 0); {ao sobrescrever o arquivo, devemos "zerar" as sementes com estes valores}
  228.         SAberto := True;    { no sucesso, SAberto se torna verdadeiro... }
  229.         Abre := False;      { e a função retorna falso (sem erros) }
  230.         if SAutoLog then Grava( 'Log-Arquivo', 'Erro Pesado', 'Reiniciado arquivo de Log: ' + SNome + '!');
  231.         if SUsaCache and SCacheDespeja then Despeja;  { despeja se houver cache }
  232.         if SDebug then Application.MessageBox( PChar( 'Reiniciado arquivo de Log: ' +
  233.                            SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  234.         { usamos uma mensagem apenas se estivermos no modo de debug }
  235.       end
  236.     else begin
  237.       if SAutoLog then Grava( 'Log-Arquivo', 'Erro Médio', 'Impossível abrir arquivo de Log: ' + SNome + '!');
  238.       Abre := True;       { em caso de erro, a função retorna verdadeiro (erros) }
  239.       if SDebug then Application.MessageBox( PChar( 'Impossível abrir arquivo de Log: ' +
  240.                          SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  241.       { usamos uma mensagem apenas se estivermos no modo de debug }
  242.     end
  243.   else Abre := False;  { e a função retorna falso (sem erros) }
  244. end;
  245.  
  246. //===================================== ALTERADA EM 1.1 E 1.2
  247.  
  248. function TArquivoLog.AbreApp: boolean;
  249. var
  250.   temp1, temp2, temp3: integer;
  251.   temp4: string;
  252.   temp5: boolean;
  253. begin
  254.   if  SArquivo.Le( SNome) then begin { tenta abrir SArquivo com SNome }
  255.     AbreApp := True;   { esse é um caso de erro que vai ser tratado por Abre }
  256.     exit;
  257.   end;
  258.  
  259.   SArquivo.SetSementes( -1254553677, 137, 0); {daqui até o fim do while pesquisa das sementes atuais}
  260.   while( not SArquivo.LeInteiro( temp3) ) do  {vamos ler o que tem no arquivo até esta instrução não conseguir ler mais}
  261.   begin                                        // ou seja, até o fim do arquivo
  262.     temp1 := temp3;    // nunca se esquecer que temp3 vai continuar com valor de temp1 até antes do if abaixo
  263.     SArquivo.LeInteiro( temp2);
  264.     SArquivo.SetSementes( temp2, byte(temp1), 0); // a partir daqui, a semente ja é outra...
  265.     SArquivo.LeBoolean( temp5); // esta e a próxima linha lêem dados que agora não são importantes para levar o cursor do arquivo até temp3
  266.     SArquivo.LeString( temp4); SArquivo.LeString( temp4); SArquivo.LeString( temp4); SArquivo.LeString( temp4);
  267.     {Application.MessageBox( PChar( temp4), 'txchum', MB_ICONQUESTION + MB_DEFBUTTON2); //para debugagem}
  268.     SArquivo.LeInteiro( temp3);  // aqui temp3 é lido pra compararmos com o valor de temp1
  269.     if temp3 <> temp1 then begin {verifica-se a integridade da criptografia e do arquivo de uma só vez aqui}
  270.       if SDebug then Application.MessageBox( PChar( 'Arquivo de Log: ' +
  271.                          SNome + ' está corrompido!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  272.       AbreApp := True;   { o arquivo estah corrompido, soh sabemos do erro em debug! }
  273.       exit; {este caso de erro vai ser tratado por Abre }
  274.     end;
  275.   end;
  276.   SArquivo.Fecha; {fecha o arquivo para poder entrar no modo Incluir}
  277.   if not SArquivo.Inclui( SNome) then begin { tenta abrir SArquivo com SNome para incremento }
  278.     SAberto := True;    { no sucesso, SAberto se torna verdadeiro... }
  279.     if (SUsaCache and SCacheDespeja) then Despeja;  { despeja se houver cache }
  280.     AbreApp := False;   { e a função retorna falso (sem erros) }
  281.   end else AbreApp := True; { em caso de erro, a função retorna verdadeiro (erros) }
  282. end;
  283.  
  284. //=====================================
  285.  
  286. constructor TArquivoLog.Cria;
  287. begin
  288.   SNome := '';
  289.   Zera;        { zera nome e executa Zera (variáveis) }
  290. end;
  291.  
  292. //=====================================
  293.  
  294. constructor TArquivoLog.Cria(PNome: string);
  295. begin
  296.   SNome := PNome;
  297.   Zera;           { Seta nome e executa Zera (variáveis) }
  298. end;
  299.  
  300. //===================================== ALTERADA EM 1.1
  301.  
  302. function TArquivoLog.DataHoraPraString(PDataHora: TDateTime): string;
  303. var
  304.   CData: string;
  305.   ano, mes, dia, hora, minuto, segundo, milisegundo: word;
  306. begin
  307.   DecodeDate( PDataHora, ano, mes, dia);
  308.   DecodeTime( PDataHora, hora, minuto, segundo, milisegundo);
  309.   CData := formatfloat('0000', ano) + '/' +
  310.            formatfloat('00', mes) + '/' +
  311.            formatfloat('00', dia) + ' | ' +
  312.            formatfloat('00', hora) + ':' +
  313.            formatfloat('00', minuto) + ':' +
  314.            formatfloat('00', segundo) + '.' +
  315.            formatfloat('000', milisegundo);
  316.   DataHoraPraString := CData;  { converte data e hora em  aaaa/mm/dd | hh:mm:ss:mmmm }
  317. end;   { P.S.: ALTERAR ESTA FUNÇÃO DE ACORDO COM A NECESSIDADE DE INDEXAÇÃO }
  318.  
  319. //===================================== CRIADA EM 1.1 / ALTERADA EM 1.2 e 1.3
  320.  
  321. function TArquivoLog.Despeja: boolean;
  322. var
  323.   contador, temp1, temp2: integer;
  324. begin
  325.   if not SAberto then
  326.   begin
  327.     if SDebug then Application.MessageBox( PChar( 'Tentando despejar arquivo de Log não aberto: '
  328.                      + SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  329.     { usamos uma mensagem apenas se estivermos no modo de debug }
  330.     Abre;
  331.     if (SAutoLog and SLogTudo) then Grava( 'Log-Arquivo', 'Erro Leve', 'Tentando despejar arquivo de Log não aberto: ' + SNome + '!');
  332.     Fecha;            { se o log está fechado, abre, Loga, fecha }
  333.     Despeja := True;  { erro ao tentar despejar }
  334.     exit;             { pára a execução da função }
  335.   end;
  336.  
  337.   if not SCached then
  338.   begin
  339.     if (SAutoLog and SLogTudo) then Grava( 'Log-Arquivo', 'Erro Leve', 'Tentando despejar arquivo de Log não-cacheável: ' + SNome + '!');
  340.     if SDebug then Application.MessageBox( PChar( 'Tentando despejar arquivo de Log não-cacheável: '
  341.                      + SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  342.     { usamos uma mensagem apenas se estivermos no modo de debug }
  343.     Despeja := True;  { erro ao tentar despejar }
  344.     exit;             { pára a execução da função }
  345.   end;
  346.  
  347.   if not SUsaCache then
  348.   begin
  349.     if (SAutoLog and SLogTudo) then Grava( 'Log-Arquivo', 'Aviso', 'Tentando despejar arquivo de Log com cache vazia: ' + SNome + '!');
  350.     if SDebug then Application.MessageBox( PChar( 'Tentando despejar arquivo de Log com cache vazia: '
  351.                      + SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  352.     { usamos uma mensagem apenas se estivermos no modo de debug }
  353.     Despeja := True;  { erro ao tentar despejar }
  354.     exit;             { pára a execução da função }
  355.   end;
  356.  
  357.   for contador := 0 to STotCache-1 do
  358.   begin
  359.     temp1 := trunc ( random( 256));
  360.     temp2 := trunc ( random( 2147483647));  // valores da próxima semente são escolhidos aleatoriamente
  361.     SArquivo.GravaInteiro( temp1); // grava semente de strings na semente anterior
  362.     SArquivo.GravaInteiro( temp2); // grava semente de inteiros na semente anterior
  363.     SArquivo.SetSementes( temp2, byte(temp1), 0); // seta as sementes novas
  364.     SArquivo.GravaBoolean( true); // grava verdadeiro (cacheado) na semente nova
  365.     SArquivo.GravaString( SCache.Strings[ contador*4]); // grava a data na semente nova
  366.     SArquivo.GravaString( SCache.Strings[ contador*4+1]); // grava o código de erro na semente nova
  367.     SArquivo.GravaString( SCache.Strings[ contador*4+2]); // grava o nível de erro na semente nova
  368.     SArquivo.GravaString( SCache.Strings[ contador*4+3]); // grava a mensagem de erro na semente nova
  369.     SArquivo.GravaInteiro( temp1); // grava a semente de strings na semente nova (para verificar integridade)
  370.     if SArquivo.erro <> TENenhum then begin
  371.       if SAutoLog then Grava( 'ErroArquivo', 'ErroMedio', 'Erro ao despejar cache em arquivo de Log: ' + SNome + '!');
  372.       Despeja := True;       { em caso de erro, a função retorna verdadeiro (erros) }
  373.       if SDebug then Application.MessageBox( PChar(
  374.                        'Erro ao despejar cache em arquivo de Log: ' + SNome + '!'),
  375.                        'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  376.                { usamos uma mensagem apenas se estivermos no modo de debug }
  377.       exit;
  378.     end;
  379.   end;
  380.   ResetaCache; { se tudo ok, reseta a cache }
  381.   Despeja := False;      { e a função retorna falso (sem erros) }
  382. end;
  383.  
  384. //===================================== ALTERADA EM 1.1 a 1.3
  385.  
  386.  
  387. destructor TArquivoLog.Destroi;
  388. begin
  389.   if SUsaCache and SCacheDespeja and (not SAberto) then
  390.   begin
  391.     Abre;  { tenta abrir se houver cache e o arquivo estiver fechado }
  392.     if (SAutoLog and SLogTudo) then Grava( 'Log-Arquivo', 'Erro Leve', 'Foi preciso abrir o arquivo para despejar a cache: ' + SNome + '!');
  393.     if SDebug then Application.MessageBox( PChar( 'Foi preciso abrir o arquivo para despejar a cache: '
  394.                      + SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  395.   end;   { se a cache estiver cheia, para despejar, e o arquivo fechado, abre e avisa isso }
  396.  
  397.   if SUsaCache and (not SLiberaCache) and (not SCacheDespeja) then
  398.   begin
  399.     if not SAberto then
  400.     begin
  401.       Abre;  { tenta abrir se houver cache e o arquivo estiver fechado }
  402.       if (SAutoLog and SLogTudo) then Grava( 'Log-Arquivo', 'Erro Leve', 'Foi preciso abrir o arquivo para o próximo erro: ' + SNome + '!');
  403.       if SDebug then Application.MessageBox( PChar( 'Foi preciso abrir o arquivo para o próximo erro: '
  404.                        + SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  405.     end;
  406.  
  407.     if SAutoLog then Grava( 'Log-Arquivo', 'Erro Pesado', 'Cache perdida ao destruir objeto sem opção de despejo e/ou liberação de cache: ' + SNome + '!');
  408.     if SDebug then Application.MessageBox( PChar( 'Cache perdida ao destruir objeto sem opção de despejo e/ou liberação de cache: '
  409.                      + SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);  { erro de tentar fechar com cache sem opções viáveis }
  410.   end;  { se a cache não poder ser liberada nem despejada, haverá erro de liberação indevida }
  411.  
  412.   if SAberto then Fecha;  { fecha o arquivo se ele se encontra aberto }
  413.   SCache.Destroy;
  414.   SArquivo.Destroi; // versão 1.2
  415. end;
  416.  
  417. //===================================== ALTERADA EM 1.1 a 1.3
  418.  
  419. function TArquivoLog.Fecha: boolean;
  420. begin
  421.   if not SAberto then
  422.   begin
  423.     if (SAutoLog and SLogTudo) then Grava( 'Log-Arquivo', 'Erro Leve', 'Tentando fechar arquivo de Log não aberto: ' + SNome + '!');
  424.     if SDebug then Application.MessageBox( PChar( 'Tentando fechar arquivo de Log não aberto: ' +
  425.                        SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  426.     { usamos uma mensagem apenas se estivermos no modo de debug }
  427.     Fecha := True;  {erro ao fechar}
  428.     exit;
  429.   end;  { abre e grava Log de erro se tentar fechar arquivo não aberto }
  430.  
  431.   if SUsaCache and SCacheDespeja then Despeja;  { despeja a cache se houver cache }
  432.  
  433.   if SUsaCache and (not SLiberaCache) then
  434.   begin
  435.     if SAutoLog then Grava( 'Log-Arquivo', 'Erro Leve', 'Fechando o arquivo com cache sem permissão de liberar ou despejar: ' + SNome + '!');
  436.     if SDebug then Application.MessageBox( PChar( 'Fechando o arquivo com cache sem permissão de liberar ou despejar: ' +
  437.                        SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  438.     { usamos uma mensagem apenas se estivermos no modo de debug }
  439.     { erro ao não poder nem despejar nem liberar cache }
  440.   end;
  441.  
  442.   if SArquivo.Fecha then begin { tenta fechar o arquivo... }
  443.     if SAutoLog then Grava( 'Log-Arquivo', 'Erro Médio', 'Erro ao fechar o arquivo de Log' + SNome + '!');
  444.                   { no erro, tenta gravar Log de erro de fechamento do Log }
  445.     Fecha := True;  { em caso de erro, a função retorna verdadeiro (erros) }
  446.     if SDebug then Application.MessageBox( PChar(
  447.                        'Erro ao fechar o arquivo de Log: ' + SNome + '!'),
  448.                        'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  449.     { usamos uma mensagem apenas se estivermos no modo de debug }
  450.   end else begin
  451.     SAberto := False;      { se conseguir, SAberto é falso... }
  452.     Fecha := False;        { e a função retorna falso (sem erros) }
  453.   end;
  454. end;
  455.  
  456. //===================================== ALTERADA EM 1.2 POR COMPATIBILIDADE COM DELPHI 5
  457.  
  458. procedure TArquivoLog.Grava(PCod, PNiv, PComent: string);
  459. begin
  460.   Grava( Now, PCod, PNiv, PComent);  { repassa com o tempo atual } // now é usada por compatibilidade com Delphi 5
  461. end;
  462.  
  463. //===================================== ALTERADA EM 1.1 E 1.2
  464.  
  465. procedure TArquivoLog.Grava(PDataHora: TDateTime; PCod, PNiv, PComent: string);
  466. var
  467.   temp1, temp2: integer;
  468. begin
  469.   if SAberto then
  470.   begin
  471.     if SUsaCache and SCacheDespeja then Despeja;  { despeja a cache se houver cache }
  472.     temp1 := trunc ( random( 256));
  473.     temp2 := trunc ( random( 2147483647));
  474.     SArquivo.GravaInteiro( temp1); // grava semente de strings na semente anterior
  475.     SArquivo.GravaInteiro( temp2); // grava semente de inteiros na semente anterior
  476.     SArquivo.SetSementes( temp2, byte(temp1), 0); // seta as sementes novas
  477.     SArquivo.GravaBoolean( false); // grava falso (não-cacheado) na semente nova
  478.     SArquivo.GravaString( DataHoraPraString( PDataHora)); // grava a data na semente nova
  479.     SArquivo.GravaString( PCod); // grava o código de erro na semente nova
  480.     SArquivo.GravaString( PNiv); // grava o nível de erro na semente nova
  481.     SArquivo.GravaString( PComent); // grava a mensagem de erro na semente nova
  482.     SArquivo.GravaInteiro( temp1); // grava a semente de strings na semente nova (para verificar integridade)
  483.     if SArquivo.erro <> TENenhum then begin
  484.         // esse erro apenas exaure a memória, já que nunca vai gravar nada!!!!
  485.       if SDebug then Application.MessageBox( PChar(
  486.                          'Erro ao tentar gravar no arquivo de Log: ' + SNome + '!'),
  487.                          'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  488.       { usamos uma mensagem apenas se estivermos no modo de debug }
  489.       exit;
  490.     end;
  491.   end else begin
  492.     if SCached then
  493.     begin
  494.       GravaEmCache( PDataHora, PCod, PNiv, PComent);
  495.     end else begin
  496.       if SDebug then Application.MessageBox( PChar(
  497.                          'Tentando gravar em arquivo de Log fechado e não-cacheado: ' + SNome + '!'),
  498.                          'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  499.       { usamos uma mensagem apenas se estivermos no modo de debug }
  500.     end;
  501.   end;
  502. end;
  503.  
  504. //===================================== CRIADA EM 1.1 E ALTERADA EM 1.2
  505.  
  506. procedure TArquivoLog.GravaEmCache(PDataHora: TDateTime; PCod, PNiv, PComent: string);
  507. begin
  508.   if not SCached then
  509.   begin
  510.     if SDebug then Application.MessageBox( PChar( 'Tentando cachear arquivo de Log não-cacheável: '
  511.                      + SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  512.     { usamos uma mensagem apenas se estivermos no modo de debug }
  513.     exit;             { pára a execução da função }
  514.   end;
  515.  
  516.   SCache.Add( DataHoraPraString( PDataHora) );
  517.   SCache.Add( PCod );
  518.   SCache.Add( PNiv );
  519.   SCache.Add( PComent);        { grava em cache o Log }
  520.  
  521.   SUsaCache := True;     { agora, há algo na cache do arquivo }
  522.   Inc( STotCache);
  523. end;
  524.  
  525. (* SUGESTÃO: abaixo estão alguns códigos e níveis de erro anteriormente
  526.              usados no ArquivoLog - podem ser usados como referência
  527.  
  528. //===================================== OBSOLETA NA VERSÃO 1.2
  529.  
  530. function TArquivoLog.NomeLogCod(PCod: TLogCod): string;
  531. begin
  532.   Case PCod of
  533.     LCDebug: NomeLogCod := 'LCDebug';
  534.     LCErroArquivo: NomeLogCod := 'LCErroArquivo';
  535.     LCErroBase: NomeLogCod := 'LCErroBase';
  536.     LCErroDB: NomeLogCod := 'LCErroDB';
  537.     LCEvento: NomeLogCod := 'LCEvento';
  538.     LCPerformance: NomeLogCod := 'LCPerformance';
  539.   else
  540.     NomeLogCod := '<desconhecido>';
  541.   end;                               { retorna o nome do Código de Log }
  542. end;
  543.  
  544. //===================================== OBSOLETA NA VERSÃO 1.2
  545.  
  546. function TArquivoLog.NomeLogNiv(PNiv: TLogNiv): string;
  547. begin
  548.   Case PNiv of
  549.     LNMensagem: NomeLogNiv := 'LNMensagem';
  550.     LNAviso: NomeLogNiv := 'LNAviso';
  551.     LNErroLeve: NomeLogNiv := 'LNErroLeve';
  552.     LNErroMedio: NomeLogNiv := 'LNErroMedio';
  553.     LNErroPesado: NomeLogNiv := 'LNErroPesado';
  554.     LNErroCritico: NomeLogNiv := 'LNErroCritico';
  555.   else
  556.     NomeLogNiv := '<desconhecido>';  { retorna o nome do Nível de Log }
  557.   end;
  558. end; *)
  559.  
  560. //===================================== ALTERADA EM 1.1 a 1.3
  561.  
  562. function TArquivoLog.Reseta: boolean;
  563. var
  564.   CAberto: boolean;
  565. begin
  566.   CAberto := SAberto;
  567.   if SNome = '' then Reseta := True  { se o nome for nulo, erro }
  568.   else begin
  569.     if SAberto then Fecha;  { fecha se arquivo aberto }
  570.     if SArquivo.Grava( SNome) then begin { tenta abrir SArquivo com SNome sobescrevendo }
  571.       if SAutoLog then Grava( 'Log-Arquivo', 'Erro Médio', 'Impossível resetar arquivo de Log: ' + SNome + '!');
  572.       Reseta := True;       { em caso de erro, a função retorna verdadeiro (erros) }
  573.       if SDebug then Application.MessageBox( PChar(
  574.                          'Impossível resetar arquivo de Log: ' + SNome + '!'),
  575.                          'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  576.       { usamos uma mensagem apenas se estivermos no modo de debug }
  577.     end else begin
  578.       SAberto := True;    { no sucesso, SAberto se torna verdadeiro... }
  579.       if SAutoLog then Grava( 'Log', 'Evento', 'Resetado arquivo de Log: ' + SNome + '!');
  580.       if not CAberto then
  581.       begin
  582.         SArquivo.Fecha;
  583.         SAberto := False;  { fecha arquivo }
  584.       end;
  585.       Reseta := False;    { tudo deu certo, função falsa em erro }
  586.       if SDebug then Application.MessageBox( PChar( 'Resetado arquivo de Log: ' +
  587.                          SNome + '!'), 'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  588.       { usamos uma mensagem apenas se estivermos no modo de debug }
  589.     end;
  590.   end;
  591. end;
  592.  
  593. //===================================== CRIADA EM 1.1 E ALTERADA EM 1.2
  594.  
  595. procedure TArquivoLog.ResetaCache;
  596. begin
  597.   SCache.Clear;
  598.   SUsaCache := False;  { limpa a cache, usacache é falso e totcache = 0 }
  599.   STotCache := 0;
  600. end;
  601.  
  602. //===================================== CRIADA EM 1.1 E ALTERADA EM 1.2 e 1.3
  603.  
  604. procedure TArquivoLog.SetCached(PCached: boolean);
  605. begin
  606.   if PCached then SCached := True else
  607.   begin
  608.     if SUsaCache then
  609.     begin
  610.       if (SAutoLog and SLogTudo) then Grava( 'Log-Arquivo', 'Erro Leve', 'Erro ao tentar setar arquivo como não-cacheado com cache ativa: ' + SNome + '!');
  611.                     { no erro, tenta gravar Log de erro ao gravar do Log }
  612.       if SDebug then Application.MessageBox( PChar(
  613.                          'Erro ao tentar setar arquivo como não-cacheado com cache ativa: ' + SNome + '!'),
  614.                          'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  615.       { usamos uma mensagem apenas se estivermos no modo de debug }
  616.     end else SCached := False;
  617.   end;
  618. end;
  619.  
  620. //===================================== ALTERADA NA VERSÃO 1.2 e 1.3
  621.  
  622. procedure TArquivoLog.SetNome(PNome: string);
  623. begin
  624.   if SAberto then
  625.   begin
  626.     if SAutoLog then Grava( 'Log-Arquivo', 'Aviso', 'Erro ao tentar mudar para "' + PNome + '" arquivo de Log já aberto: ' + SNome + '!');
  627.                   { no erro, tenta gravar Log de erro ao gravar do Log }
  628.     if SDebug then Application.MessageBox( PChar(
  629.                        'Erro ao tentar mudar para "' + PNome + '" arquivo de Log já aberto: ' + SNome + '!'),
  630.                        'Debug', MB_ICONQUESTION + MB_DEFBUTTON2);
  631.     { usamos uma mensagem apenas se estivermos no modo de debug }
  632.   end else SNome := PNome;
  633. end;
  634.  
  635. //===================================== ALTERADA EM 1.1 E 1.2
  636.  
  637. procedure TArquivoLog.Zera;
  638. begin
  639.   randomize; // versão 1.2 - para que a criptografia "mochila" simples possa funcionar
  640.   if SArquivo <> nil then SArquivo.Destroi; // versão 1.2 - garante o código se erros nas próximas versões
  641.   SArquivo := TArquivoDireto.Cria;  // versão 1.2 - cria um objeto TArquivoDireto
  642.   STotCache := 0; // versão 1.2 // a cache é vazia na criação
  643.   SAberto := False;
  644.   SDebug := False;
  645.   SSobrescreve := False;
  646.   SAutoLog := False;  // versão 1.3
  647.   SLogTudo := False;  // versão 1.3
  648.   SUsaCache := False; // versão 1.1
  649.   SLiberaCache := False; // versão 1.1
  650.   SCacheDespeja := False; // versão 1.1
  651.   SCached := False; { apenas seta variáveis iniciais } // versão 1.1
  652.   SCache := TStringList.Create;  { cria uma lista de strings nula } // versão 1.1
  653. end;
  654.  
  655. //=====================================
  656.  
  657. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement