xiidea / EasyAuditBundle

A Symfony Bundle To Log Selective Events
http://xiidea.github.io/EasyAuditBundle/
MIT License
89 stars 22 forks source link

Need to find wich field changed or data inserted #9

Open mjanbazi opened 8 years ago

mjanbazi commented 8 years ago

hello i want to find when i updated entity,which fields changed with changed value , like this Table1 and Field1 This Value V1 Changed to V2 (parameter: Table1,Field1,V1,V2)

and when i inserted a data in table this log: Table1 and Field1 This Value V1 Inserted,Field2 This Value V2 Insertet (parameter: Table1,Field1,Field2,V1,V2)

for each field in table all of them in one string stored in a row in audit_log table

thank you

ronisaha commented 8 years ago

You can add as many row as you need in your audit entity. And use pre-persist listener to filled the data like this

Or you can use your own entity event resolver like this

braianj commented 6 years ago

Hi @ronisaha do you have an example for saving old_data / new_data as json or something similar?

ronisaha commented 6 years ago

You can check sample implementation to store the changed data. You can create your own entity event resolver following that sample.

braianj commented 6 years ago

@ronisaha with the example it throw

The file "/project/app/config/services.yml" does not contain valid YAML in /project/app/config/services.yml (which is being imported from "/project/app/config/config.yml"). with

    audit_trail.entity_event_resolver:
        class: AppBundle\Resolver\EntityEventResolver
        calls:
            - [ setContainer,[ @service_container ] ]

So then I change it to

    audit_trail.entity_event_resolver:
        class: AppBundle/Resolver/EntityEventResolver
        calls:
            - [ setContainer, ['@service_container' ]]

and I got this error

You have requested a non-existent service "audit_trail.entity_event_resolver".

ronisaha commented 6 years ago

The class definition was not the reason for previous error. The previous error happen if there is problem in yaml formating. The class namespace should use \ instead of /. And the service definition must be under the services block

braianj commented 6 years ago

The service definition is under service block in service.yml file. And i try both / and .

ronisaha commented 6 years ago

Do you have sample project that i can check? Another thing, if you are using autowire configuration with latest version of symfony, you may need to add public: true parameter

services:
    audit_trail.entity_event_resolver:
        class: MyProject\Bundle\MyBundle\Resolver\EntityEventResolver
        public: true
        calls:
            - [ setContainer, [ "@service_container" ] ]

braianj commented 6 years ago

@ronisaha with that change and writing service_container like '@service_container' but I can't understand how to save the new and old data, can you explain that? I already add the resolver but don't know how to use it

ronisaha commented 6 years ago

Check the code here. By calling this function you can get the change set.

And in the sample event resolver you can see the exta fields. you have to add some more field in you audit log entity to store the data. You havve the full control how you can save the data, in single field or in separate field. You have to do two thing:

  1. Add some field in your entity you want to store
  2. Return the values as a array key from **getEventLogInfo** function.

Thats it.

braianj commented 6 years ago

@ronisaha I got one more question: how do I get the data when created, because $changesMetaData came empty

ronisaha commented 6 years ago

On create operation there is no change set, the full object data is new. if you like to store that also you can store the full data by accessing the entity object :)

braianj commented 6 years ago

can you give me an example? Sorry i'm new on symfony

ronisaha commented 6 years ago

Its nothing to do with symfony or this library, you can store serialize string of the entity object. you can implement your serialize method, __toString method, or jms serializer library to get the object data as string and store it in a field.

pribeirojtm commented 6 years ago

Hi @ronisaha ,

Regarding this topic, the method of saving object - to created and updated events - (or the changeSets - to updated events) data as string in another field of my auditLog entity (called, for example: changeSets), that I'm using is other: only the serialize() php method. What do you think about it in terms of possible problems/advantages/disadvantages?

Inside getEventLogInfo() method I have:

        // .....
        $changeSets = $this->getChangeSets($this->entity);//delta (old and new values)

        if ($this->isUpdateEvent() && null === $changeSets) {
            return null;
        }

        if($this->getEventShortName() === 'deleted' OR $this->getEventShortName() === 'created') {
            $changeSets = $this->getUnitOfWork()->getOriginalEntityData($this->entity);
        }

        $entityClass = $this->getReflectionClassFromObject($this->entity);  

        $auditLog = new AuditLog();
        $auditLog->setDescription($this->getDescription($entityClass));
        $auditLog->setType($this->getEventType($entityClass->getShortName()));
        $auditLog->setChangeSets(serialize($changeSets));

        return $auditLog;

Thanks for your view

ronisaha commented 6 years ago

Hi @pribeirojtm ,

I think there is no problem using php serialize for change set. even the example i've provided used serialize function to convert change set to string. But if you want to store whole entity object reference then serialize/unserialize may have some side effect for reference value.

Happy coding.

pribeirojtm commented 6 years ago

Thanks for your view @ronisaha ,

Indeed, I want also to store original entity data when creating new entities or when deleting existent one. I've tried and unserialized correctly the data, I haven't found any side effect till now. What do you mean by "side effect for reference value" ?

Other thing I've stepped in is that sometimes, actions fails... for example, deleting an entity that has its PK present as FK in other entity and it has onDelete restrict, and it fails to delete the parent entity record. In these cases of failure, the log is still registered. Do you recommend a way to tackle this issue?

Thanks in advance,

ronisaha commented 6 years ago

Hi @pribeirojtm ,

Could you please create another issue with the delete functionality. I'll try to look into that. It would be helpful if you could provide a sample code repository to reproduce the bug.

Thanks.