Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-62907

Logging: Standard log table 'other' field should use JSON format, not PHP serialize

    XMLWordPrintable

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 3.7
    • 3.7
    • Logging
    • MOODLE_37_STABLE
    • MOODLE_37_STABLE
    • MDL-62907-master
    • Hide
      1. Using an existing Moodle install (i.e. you did not install it freshly after this patch), check the new setting 'JSON format' in the site settings under the logstore_standard plugin. It should be OFF.
      2. Using a fresh Moodle install that was installed after this patch (e.g. a Behat test environment), check the same setting. It should be ON.
      3. With either install, turn the setting OFF and carry out some actions in a test course. I suggest viewing a course page, viewing a forum, and starting a forum discussion.
      4. Now turn the setting ON and carry out the same actions again.
      5. Look at the log report for the course.
        • EXPECTED: You should see the actions you carried out, both times (there should be no difference).
      6. Look in the database and find the relevant rows from the mdl_logstore_standard_log table, for example SELECT * FROM mdl_logstore_standard_log WHERE courseid = 1234 ORDER BY id DESC LIMIT 20;
      7. Look at the 'other' field in these results.
        • EXPECTED: The older rows should have the data in PHP serialised format, usually beginning 'a:'. The newer rows should have the data in JSON format, usually beginning '{'.

      Now test for the logstore_database plugin:

      1. Turn off standard logging.
      2. Turn on database logging and set the configuration so that it points to a suitable Moodle database that contains the (mdl_)logstore_standard_log table. (If you don't have a different install, I think it's OK to set the database fields so that it points to the same database.)
      3. Repeat steps 3-7 from the above steps, looking in the selected remote database when finished (if not using the same one).
      Show
      Using an existing Moodle install (i.e. you did not install it freshly after this patch), check the new setting 'JSON format' in the site settings under the logstore_standard plugin. It should be OFF. Using a fresh Moodle install that was installed after this patch (e.g. a Behat test environment), check the same setting. It should be ON. With either install, turn the setting OFF and carry out some actions in a test course. I suggest viewing a course page, viewing a forum, and starting a forum discussion. Now turn the setting ON and carry out the same actions again. Look at the log report for the course. EXPECTED: You should see the actions you carried out, both times (there should be no difference). Look in the database and find the relevant rows from the mdl_logstore_standard_log table, for example SELECT * FROM mdl_logstore_standard_log WHERE courseid = 1234 ORDER BY id DESC LIMIT 20; Look at the 'other' field in these results. EXPECTED: The older rows should have the data in PHP serialised format, usually beginning 'a:'. The newer rows should have the data in JSON format, usually beginning '{'. Now test for the logstore_database plugin: Turn off standard logging. Turn on database logging and set the configuration so that it points to a suitable Moodle database that contains the (mdl_)logstore_standard_log table. (If you don't have a different install, I think it's OK to set the database fields so that it points to the same database.) Repeat steps 3-7 from the above steps, looking in the selected remote database when finished (if not using the same one).

    Description

      The standard log table (mdl_logstore_standard_log) uses an 'other' field to store arbitrary data provided by events. This field is currently serialised using PHP serialisation, for example:

      'a:2:{s:7:"modname";s:12:"htmlactivity";s:4:"info";s:11:"default: id";}'
      

      PHP serialisation is not widely supported, whereas JSON serialisation is very well supported. For example, if you are writing a database report and you want to get the info field out of that object serialized into 'other', here is how you can do it using Postgres with PHP serialisation (this is a bodge job and doesn't handle some edge cases):

      regexp_replace(other, '^.*?"info";s:[0-9]+:"(.*?)".*$', E'\\1')
      

      But here is how you could do it if the data were stored in JSON format:

      other::json->'info'
      

      Changing the log format at this point could cause problems for integrations, but it might be worth having an admin setting - which could default to true for new installations, false for existing ones - to use JSON format in this field. The code that deserializes could support both formats ('a:' or 'N;' at the start of the field identifies PHP format) so that it still works OK if you switch it on/off.

      I don't think I have time to write this at the moment, sadly, but am creating a tracker entry in case of interest from others!

      Attachments

        Issue Links

          Activity

            People

              quen Sam Marshall
              quen Sam Marshall
              Tim Hunt Tim Hunt
              Eloy Lafuente (stronk7) Eloy Lafuente (stronk7)
              Ryan Wyllie Ryan Wyllie
              David Woloszyn, Huong Nguyen, Jake Dallimore, Meirza, Michael Hawkins, Raquel Ortega, Safat Shahin, Stevani Andolo
              Votes:
              3 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                20/May/19

                Time Tracking

                  Estimated:
                  Original Estimate - 0 minutes
                  0m
                  Remaining:
                  Remaining Estimate - 0 minutes
                  0m
                  Logged:
                  Time Spent - 1 hour, 40 minutes
                  1h 40m