Page MenuHomePhabricator

[SPIKE] Reading Lists - Total saved articles (PHP) instrumentation
Closed, ResolvedPublicSpike

Description

As part of the instrumentation for the Reading Lists experiment T397532, we want to log the total number of articles that a user saves throughout the experiment.

After discussing this metrics with the Reader Experience team engineers & product analytics (meeting notes), we decided the most performant and stable way of logging this metrics would be by sending an eventLogging event whenever an API add/delete event occurs.

We discussed different options of how to send this data. Client-side, in browser, we don't have access to the users total number of saved articles, so instead, we opted to send this event from PHP in the Reading List extension. Experiment Lab PHP API.

User story

As a product team, we want to know how many articles users save during this experiment.


Requirements

Screenshot 2025-08-19 at 1.15.13 PM.png (708×652 px, 379 KB)

Whenever someone clicks the bookmark icon, we want to log an event containing the total number of pages they have saved.

User flow

  1. A user is bucketed into the experiment
  2. They save or remove an article
  3. That user behaviour triggers an API call.
  4. When the API is called in the backend, we log an eventLogging event that contains the total number of saved articles.
  • Article save or remove event (backend)
action: TBD
action_subtype:  save_article_to_reading_list / remove_article_from_reading_list
action_source: reading_list_api
action_context: {article_count: <INT>}

Acceptance criteria

Since this event will be sent from PHP, it will not be visible in the browser console. Instead, we have to inspect the eventlogging end-point to see if the event was sent.

  • Verify the feasibility of this approach with a POC patch.

BDD

Feature: Backend instrumentation for total saved articles

  Scenario: User saves an article
    Given I am bucketed into the Reading List experiment
    When I save an article (bookmark icon triggers API)
    Then the backend API logs an EventLogging event
    And the event includes action_subtype = save_article_to_reading_list
    And action_context includes the updated article_count

  Scenario: User removes an article
    Given I am bucketed into the Reading List experiment
    When I remove an article from my saved list
    Then the backend API logs an EventLogging event
    And the event includes action_subtype = remove_article_from_reading_list
    And action_context includes the updated article_count

Test Steps

Test Case 1: Save article logs event with total count

  1. Log in as a user bucketed into the Reading List experiment.
  2. Save an article using the bookmark icon.
  3. Inspect the network tab for a request to the EventLogging endpoint.
  4. AC1: An event is sent when the article is saved.
  5. AC2: The event includes action_subtype = save_article_to_reading_list.
  6. AC3: The event includes action_source = reading_list_api.
  7. AC4: The event includes action_context with article_count as an integer (updated total).

Test Case 2: Remove article logs event with total count

  1. While logged in, remove a previously saved article.
  2. Inspect the network tab for a request to the EventLogging endpoint.
  3. AC5: An event is sent when the article is removed.
  4. AC6: The event includes action_subtype = remove_article_from_reading_list.
  5. AC7: The event includes action_source = reading_list_api.
  6. AC8: The event includes action_context with article_count as an integer (updated total).

This task was created by Version 1.0.0 of the Reader Experience team task template using phabulous.

Event Timeline

Jdrewniak moved this task from Incoming to Needs refinement on the Reader Experience Team board.

meeting notes: @aude to reach out to metrics platform to verify how the PHP SKD works with the same front-end schema.

Jdrewniak renamed this task from Reading Lists - Total saved articles (PHP) instrumentation to [SPIKE] Reading Lists - Total saved articles (PHP) instrumentation.Aug 20 2025, 5:22 PM
Jdrewniak assigned this task to aude.
Jdrewniak updated the task description. (Show Details)

@jwang @Jdrewniak is it necessary that these add / remove page (to reading list) events have the session_id?

@jwang I am looking at the contextual attributes:

https://phabricator.wikimedia.org/T402320

For the contextual attributes, should we also include "performer_id"? I think this is the central auth global id of the user.

https://wikitech.wikimedia.org/wiki/Experimentation_Lab/Contextual_attributes

Would including performer_id allow us to do hybrid backend (php) and client side instrumentation? or is having session id mandatory.

Change #1181192 had a related patch set uploaded (by Aude; author: Aude):

[mediawiki/extensions/ReadingLists@master] POC - experiment instrumentation for reading lists add/remove page

https://gerrit.wikimedia.org/r/1181192

In my LocalSettings.php, I have:

$wgEventStreams = [
    'product_metrics.web_base_reading_list' => [
        'schema_title' => '/analytics/product_metrics/web/base/1.4.2',
        'destination_event_service' => 'eventgate-analytics-external',
        'producers' => [
            'metrics_platform_client' => [
                'provide_values' => [
                    'agent_client_platform',
                    'agent_client_platform_family',
                    'page_content_language',
                    'page_namespace_id',
                    'mediawiki_skin',
                    'mediawiki_database',
                    'performer_is_logged_in',
                    'performer_is_temp',
                    'performer_is_bot',
                    'performer_edit_count_bucket',
                    'performer_session_id'
                ],
            ],
        ],
    ],
];

After discussion with the experiment platform team and technical investigation, we think it is best to keep all instrumentation on the client side.

The reading_listdatabase table has a column rl_size which keeps track of the size of the reading list. One possible solution could be to return this in the api response when a user adds or removes a page from their reading list. Then we can send an event for the experiment after the reading list add or removal action.

We are not supporting batch add/remove at this time on web, but that could be a consideration in the future with the instrumentation.

Here is a proof of concept of how this could work:

https://gerrit.wikimedia.org/r/c/mediawiki/extensions/ReadingLists/+/1181192

By keeping instrumentation on the client-side, this brings more simplicity to the implementation and analysis. With php instrumentation, we do not have the session_id and would need another way to join the event data with the client side events. In the future, this will be possible for experiments with logged-in users.

LocalSettings.php

$wgMetricsPlatformExperiments = [
    'rwe-3-3-4-reading-list-test1' => [
        'name' => 'rwe-3-3-4-reading-list-test1',
        'sample' => [
            'unit' => 'user',
            'rate' => 1
        ],
        'groups' => [
            'control',
            'treatment'
        ]
    ]
];

I am seeing the event in eventlogging:

"event": {
    "action": "reading_list_change_xlab",
    "action_subtype": "remove_article_from_reading_list",
    "action_source": "reading_list_api",
    "action_context": "{\"article_count\":0}",
    "experiment": {
        "enrolled": "rwe-3-3-4-reading-list-test1",
        "assigned": "treatment",
        "subject_id": "fcaa63b95334e5fc2397ad74bab68aa3a2dec4245b477f0644649da22b69ce09",
        "sampling_unit": "mw-user",
        "coordinator": "xLab"
    }
}

Change #1183160 had a related patch set uploaded (by Aude; author: Aude):

[mediawiki/extensions/WikimediaEvents@master] POC - Add ReadingLists experiment

https://gerrit.wikimedia.org/r/1183160

Change #1181192 merged by jenkins-bot:

[mediawiki/extensions/ReadingLists@master] Add data-mw-list-page-count data attribute for add/remove page instrumentation

https://gerrit.wikimedia.org/r/1181192

In summary we decided not to use any PHP instrumentation for this experiment due to the complexity involved in managing that code, as well as some uncertainty about the ability to join the PHP instrumentation with the JS instrumentation with the same identifier.
Instead, we added the reading list length, rl_size to the HTML output by placing it on an html attribute on the reading list button. That will allow us to send that value with each click event as originally described in the instrumentation spec.

Restricted Application changed the subtype of this task from "Task" to "Spike". · View Herald TranscriptSep 12 2025, 8:12 PM

Change #1183160 abandoned by Aude:

[mediawiki/extensions/WikimediaEvents@master] Add ReadingLists experiment, instrument page add/remove

Reason:

done in another patch

https://gerrit.wikimedia.org/r/1183160

Edtadros subscribed.

@Jdrewniak, is this something testable in prod? I did check out the events but I don't recall how to get bucketed.

@Edtadros We won't have prod testing abilities until the test is configured with xlab in T402320. I think maybe we can wait for that and then do a round of dedicated QA for the event instrumentation.