Página 1 de 1

Geração de Log de Alteração de Registro

Enviado: 30 Abr 2016 11:35
por frazato
Bom dia!
Fiz um rotina pra gravar as alterações que o usuário faz no registro (DBF) pra efeito de auditoria, até tenho uma pra campos especificos mais nada até então para alteração em dados de cadastro, gostaria de compartilhar, pra mim serviu bem.

Frazato

Código: Selecionar todos

	use produto 
	Go 3
	cMatrizAntes := CarregaDadosRegistro()
	Go 5
	cMatrizDepois:= CarregaDadosRegistro()
	wAlterados   := AnaliseDiferenca(cMatrizAntes,cMatrizDepois)
	
	
	? Len(wAlterados )
	*Inkey(0)
	For x:= 1 to Len(wAlterados)
	   ? wAlterados[x,1]+' '+wAlterados[x,2]
	Next
	*? 'Registrando o Log de Alterados'
	*Grav_Log_Produto_DBF(wAlterados)
	CLose All
Return nil	
	
//--------------------------------------------------------	
Static Function AnaliseDiferenca(cVar1,cVar2)
Local i , cAlteracao
Local cAlterados := {}
For i:= 1 to Len(cVar1)
    If cVar1[i,2]#cVar2[i,2]
       cAlteracao  := 'De..:'+cVar1[i,2]+' Para:'+cVar2[i,2]
       Aadd(cAlterados,{cVar1[i,1],cAlteracao } )
    Endif
Next
If Len(cAlterados) > 0
	// Gravando as alteracoes em arquivo txt
   Grav_Log_Produto_DBF(cAlterados)
Endif   
Return cAlterados
	
//--------------------------------------------------------	
Static Function CarregaDadosRegistro()	
Local i,cNomeCampos,cValorCampo,wValoresCampos := {}
	For i:= 1 to Fcount()
	  cNomeCampos := FieldName(i)
	  If FieldType(i)=='D'
	         cValorCampo := Dtoc(&cNomeCampos)
	  ElseIf FieldType(i)=='N'
	  	      cValorCampo := Str(&cNomeCampos,13,5)
	  ElseIf FieldType(i)=='L'
	  		   cValorCampo := Iif(&cNomeCampos==.t.,'S','N')
     Else	  
     		   cValorCampo := &cNomeCampos
     Endif	  
	  Aadd(wValoresCampos,{cNomeCampos,cValorCampo})
	NExt
Return wValoresCampos	

	
//--------------------------------------------
Static Function Grav_Log_Produto_DBF(wAlterados)
Local cFileName := "LogJaf\Log_Produto.txt"
Local hFile, cLine := "", n
Local cFieldAnt
Local CRLF    := Chr(13)+Chr(10)
Local i
For i:= 1 to Len(wAlterados)
    cLine += Alltrim(mUsr)+' '+Dtoc(Date())+' '+Time()+Space(2)+;
	       	'Campo.:'+wAlterados[i,1]+' Valor:'+wAlterados[i,2] +CRLF
Next
If ! File( cFileName )    // Caso nao tenha cria o arquivo
     FClose( FCreate( cFileName ) )
Endif

Do Whil .T.
	If ( ( hFile := FOpen( cFileName, 1+16 ) ) # -1 )
		FSeek( hFile, 0, 2 )
		FWrite( hFile, cLine, Len( cLine ) )
		FClose( hFile )
		Exit
	Else
           Exit
	Endif
Enddo

Retu(.T.)	
	

Geração de Log de Alteração de Registro

Enviado: 30 Abr 2016 12:11
por JoséQuintas
Legal.

Faço isso também, mas gravo em base de dados.
Gravo também o nome do arquivo e a chave de acesso daquele registro.

Por exemplo, num determinado pedido, posso mostrar tudo que aconteceu com aquele pedido.
O mesmo com clientes, financeiro, etc.

Usei uma classe pra facilitar no fonte.

Código: Selecionar todos

oRecValues := RecValues():New()
//.... alterações
oRecValues:WriteLog( cArquivo, xChave )
Ao criar a classe, salva tudo.
Ao chamar depois, é feita a comparação se alterou algo pra registrar no log.

A classe só reduziu tudo a uma única variável no fonte, de resto é o mesmo que sua rotina faz.

Isso é muito útil.

A última coisa que aconteceu comigo, foi a dona da empresa reclamar que o sistema deixou alguém autorizar um pedido errado.
Ao consultar o log, adivinha quem tinha autorizado.... mesmo com o sistema avisando do problema.... rs

Geração de Log de Alteração de Registro

Enviado: 30 Abr 2016 17:44
por fladimir
Uma outra forma é fazer uma alteração em algum CH q componha todos os PRGs e mudar o comando Append, Delete etc..

Exemplo:

Código: Selecionar todos

        #command PACK          => __dbPack()        ; dbCommitLog( 'P', PROCNAME(), PROCLINE(), cDBCommitLog )
	#command ZAP           => __dbZap()         ; dbCommitLog( 'Z', PROCNAME(), PROCLINE(), cDBCommitLog )
	#command DELETE        => My_DBDelete()
	#command DBDELETE()    => My_DbDelete()
	 #command APPEND BLANK  => dbAppend( 0 )     ; dbCommitLog( 'I', PROCNAME(), PROCLINE(), cDBCommitLog )
	 #command REGLOCK       => dbRegLock( 0 )    ; dbCommitLog( 'M', PROCNAME(), PROCLINE(), cDBCommitLog )
	 #command RLOCK()       => dbRegLock( 0 )    ; dbCommitLog( 'M', PROCNAME(), PROCLINE(), cDBCommitLog )
	 #command REGLOCK <n>   => dbRegLock( <n> )  ; dbCommitLog( 'M', PROCNAME(), PROCLINE(), cDBCommitLog )
	 #command FILELOCK      => dbFileLock( 0 )   ; dbCommitLog( 'M', PROCNAME(), PROCLINE(), cDBCommitLog )
	 #command FILELOCK <n>  => dbFileLock( <n> ) ; dbCommitLog( 'M', PROCNAME(), PROCLINE(), cDBCommitLog )

*************************************************
function dbCommitLog( LOG_TIPO, PROCNAME, PROCLINE, EXTRA )
 LOCAL ret_line := "chr(13)+chr(10)", errfile := 'LOG\LOG_'+strzero(Month(date()),2)+STR(year(date()),4)+'.TXT'

 DirMake('LOG')

	default ProcName  := 'MODULO NAO DEFINIDO'
 	default ProcLine  := 'LINHA MOD. NAO DEF.'
 	default Extra     := ' '

	if  LOG_TIPO = 'A'
		M->MINHA_INFO  := 'ABERTURA  '
	elseif LOG_TIPO = 'I'
		M->MINHA_INFO  := 'INCLUSAO  '
	elseif LOG_TIPO = 'B'
		M->MINHA_INFO  := 'BLOQ REG  '
	elseif LOG_TIPO = 'F'
		M->MINHA_INFO  := 'BLOQ FILE '
	elseif LOG_TIPO = 'E'
		M->MINHA_INFO  := 'EXCLUSAO  '
	elseif LOG_TIPO = 'M'
		M->MINHA_INFO  := 'MANUTENCAO'
	elseif LOG_TIPO = 'P'
		M->MINHA_INFO  := 'PACK'
	elseif LOG_TIPO = 'Z'
		M->MINHA_INFO  := 'ZAP'
	else
		M->MINHA_INFO  := 'OUTROS    '
	endif
	M->MODULO     := PadR(PROCNAME, 15,' ')
	M->LINHAMOD   := STR(PROCLINE,5)
	M->Extra      := Extra
	M->Operador   := " "

 if !FILE(errfile)
    errhandle = FCREATE(errfile)
    FWRITE(errhandle,"Nome do executavel....: " + lower(ExeName()) +&ret_line.)
    FWRITE(errhandle,"Segue lista de processos detectados."+&ret_line.+&ret_line.)
    FWRITE(errhandle,"Data       Hora       Processo        Linha  Tipo    Inf. Adicional"+&ret_line.)
    FWRITE(errhandle,replicate("-",80)+&ret_line.+&ret_line.)
 else
    errhandle = FOPEN(errfile,1)
    length  = FSEEK(errhandle,0,2)
    FSEEK(errhandle,length)
 endif

 //-- Caminho Rotinas
 aRoteiro:={}
 Local1:= 2
 while (!Empty(procname(Local1)))
    if (procline(Local1) != 0)
       AAdd(aRoteiro, padr(procname(Local1), 12) + "(" + strzero(procline(Local1), 4) + ")")
    endif
    Local1++
 end
 for Local1:= 1 to Len(aRoteiro)
   cRoteiro := aRoteiro[Local1]
   cRoteiro := Alltrim(cRoteiro)
	if Local1==1
  	   cRoteiro := PADR( cRoteiro, 20, [ ])
	   FWRITE( errhandle, DTOC(DATE()) + " " + TIME() + " " + M->OPERADOR + " "  + cRoteiro + " " + M->MINHA_INFO + " " + M->EXTRA + "Dt. EXE: " + DToC(FileDate(ExeNAME())) + " as " + Filetime(ExeName()) + " Hs." + ' ' + &ret_line)
 	else
  	   FWRITE(errhandle,'                      '+ PADR(ALLTRIM(aRoteiro[Local1]),31,' ')  + SPACE(15)+ &ret_line)
	endif 	
 next

  //-- Nome da Tela Capturada
  FWRITE(errhandle,'                      TELA CAPTURADA.....: '+ 'TELA_'+dtos(date()) + '-' + LEFT(Strtran(time(),":",""),4) + '__'+'.TXT' + &ret_line + &ret_line)
  FCLOSE(errhandle)

   cDBCommitLog:= ' '
return(.T.)

Essa é uma ideia q o amigo Rochinha uma vez compartilhou e na época achei mais prática pq eu tinha pensado q fora isso (não tive outra ideia) teria q alterar rotina por rotina e jogando no CH q tenho em todos apenas fiz algumas alterações e criei uma função unica.


[]´s

Geração de Log de Alteração de Registro

Enviado: 30 Abr 2016 19:43
por JoséQuintas
Realmente interessante.
Pode ser um complemento ao log normal.
Uma coisa é saber que aquilo foi alterado na rotina de pedidos, e outra coisa é saber qual foi o pedido que causou a alteração.
Então um misto vai ser necessário, ou algo assim.