Latest sites

  • 2017-11-26: New Drupal 8 site at Rue du Commerce, architected and tech-led by OSInet, just went throught Black Friday week with flying colors thanks to RabbitMQ
  • 2017-05-26: New headless Drupal 8 / Symfony 3 site at FranceTV Sport, architected and tech-led by OSInet, with RabbitMQ
  • 2017-02-20: New Drupal 8 site galaxy (+/- 70 sites) for Agences Régionales de Santé architected and tech-led by OSInet, delivered by Klee
  • 2015-08-21: 50% less server load with MongoDB on the Drupal 7 site factory at France Télévisions
  • 2015-07-15: Our first Drupal 8 production site at France Télévisions is live
  • 2014-08-18: 400% speedup in 3 weeks for : who said Drupal back-offices had to be slow ?
  • 2014-02-07: Sotchi Olympics traffic not a problem for , which I rearchitected on Drupal 7 in 2013
  • 2011-09-14: Completed migration of FranceInfo.FR from SPIP to Drupal
  • 2011-07-13: The new social network features of Le Figaro are now powered by an OSInet-designed MongoDB implementation

Quick news

  • 2014-03-27: MongoDB Watchdog module ported to Drupal 8 at the Szeged Dev Days.
  • 2014-01-26: My post on the Symfony web profiler in Silex selected in Week of Symfony. w00t !
  • 2013-10-18: My first commit went into MongoDB today. And, guess what ? It's in JavaScript
  • 2013-09-20 to 29: Working on Drupal 8 EntityAPI at the extended code sprints during and around DrupalCon Prague
  • 2012-08-19: Working on Drupal 8 EntityAPI at Drupalcon Munich
  • 2012-06-15: Working on Drupal 8 EntityAPI at DrupalDevDays Barcelona
  • 2012-03-23: Working on the future Drupal Document Oriented Storage at DrupalCon Denver. D8 or later ? Bets are on Later

Logging for Drupal - battle plan

The suggestion

Currently, various modules within core and contrib use various tables to store historical (i.e. "write once, read sometimes, never update") data. The most obvious is the watchdog table, but others exist, including accesslog, and zeitgeist's eponym table.

Logging through a unified API has the potential to reduce the code volume somehow, as all logging functions could be made one, and could also potentially be simplified to automatically record some information so that modules invoking the function don't have to write in some parameters, that could be recorded automatically.

The logging module could be used as a facade between recording modules and modules with data to record, allowing for multiples logging formats (think distributed logging, for instance, or logging to a printer for some physical audit trail situations).

Registering as a recorder

Modules wishing to be registered as potential recorders would use a function like:

global $logging_recorders = array();

* @param string $recordee The name of the function to use the logging mechanism
* @param string $recorder The name of the function offering to record for $recordee
function logging_register_recorder($recordee, $recorder)

$recorders[$recordee][$recorder] = 1;

Notifying recorders

Modules wishing to allow for logging of their call parameters could just use code like:

if (function_exists('logging_record_entry'))
logging_record_entry(); // Notice: no params needed

Matching recorder and recordee

At this point, the logging mechanism would go through the array of recorders, check whether one or more recorders have registered for the calling function, and pass them the calling function information:

fonction logging_record_entry

$recordee = debug_backtrace[0]['function'];
$args = debug_backtrace[0]['args'];
  if (
array_key_exists($recordee, $logging_recorders))
$logging_recorders[$recordee] as $recorder => $count)
      if (
$recorder($recordee, $args);
t("In logging module, non-callable recorder %recorder was registered for recordee %recordee.",
'%recorder' => $recorder, '%recordee => $recordee))) ;

Performing recording

Eventually recorder functions fulfill their recording contract as they wish using the original function arguments. Having the recordee name as first parameter allows the recorder function to be potentially unique for several recordees.

Admin-level tuning

An objection to this mechanism is the obvious cost of logging over situations without logging. This could be alleviated by switching the recording pairs on and off as a logging module setting. Instead of logging pairs and always invoking the recorder, the module could store a "on/off" setting for each pair, defined in admin/settings/logging.

That way, recordee could still send recording notifications, but they would be cut off at the logging module level before reaching the recorders if the site admin thinks he doesn't need them.

Why bother ?

This came from a need initially met with the current Zeitgeist module: there is, as of Drupal 4.7RC2, no formal way to register searches being performed. Chatting on #drupal confirmed that.

The mere idea of adding code to search.module just to support zeitgeist, which is a contrib module (and not even a major one), seemed utterly illogical, although just adding _zeitgeist_store_search() within search.module/do_search() fulfilled zeitgeist's need for a clean way to grab search requests, so I didn't even suggest it.

Considering this, I suggested a hook for search recorders, that could be used by any module wishing to record search queries, and not just zeitgeist. But discussion showed this was not felt to be sufficiently general to be upheld.

I then thought on, and considered what sort of a more general contract-based mechanism could be used, that would both be extremely simple to use by recordees, so as to not affect them, and flexible enough to accomodate more general needs than just recording searches. This is the first draft of the result.

On ...

This is listed amongst the 4.8 battle plans on

D6 logging went that way

Although I eventually didn't pull it off for D5, the watchdog / logging system in D6 has been vastly overhauled with the same goal of increased flexibility, but along different lines.

Loggin for D8: here we go again

It's this time of the Drupal lifecycle again: new thoughts about rebuilding the Drupal watchdog() logging are on their way in: .