• Title: ~45% of programmatic user registrations not recorded in database

    Post:

    We’re experiencing a significant issue where approximately 45% of new user registrations are not being recorded by WP Activity Log at all — not hidden from the viewer, but completely absent from the wp_wsal_occurrences database table.

    Setup:

    • WordPress 6.9.4
    • PHP 8.3.30
    • WP Activity Log 5.6.1 (free version)
    • Hello Elementor theme 3.4.6
    • Custom authentication plugin handling signup/login via OTP

    The numbers:

    • Total WordPress users: 103
    • Distinct users with any activity in wp_wsal_occurrences: 56
    • Missing users: ~47 (45%)
    • All event IDs (1000, 4000, 2101, 6061) are enabled
    • No user exclusions configured

    How we confirmed data is missing:

    SELECT * FROM wp_wsal_occurrences 
    WHERE username = '[email protected]' 
    ORDER BY created_on DESC;
    

    Returns zero rows. This user exists in WordPress with a last_login user meta timestamp confirming our plugin code executed successfully. WP Activity Log simply never recorded anything.

    How account creation works in our plugin:

    $user_id = wp_insert_user([...]);
    wp_set_current_user($user_id);
    $sessions = WP_Session_Tokens::get_instance($user_id);
    $sessions->destroy_all();
    wp_set_auth_cookie($user_id, true);
    update_user_meta($user_id, 'last_login', current_time('mysql'));
    // redirect follows
    

    We do NOT fire do_action('wp_login') because it triggers WooCommerce hooks that interfere with our redirect flow.

    Pattern observed:

    • The missing users are random — not based on time of day, browser, or IP
    • For users that ARE tracked, the full flow appears correctly: Passcode sent (6061) → User Created (4000) → User Login (1000) → Page Viewed (2101)
    • For missing users, there is zero trace — no events of any kind
    • The wp_set_auth_cookie() call should trigger the set_logged_in_cookie action which WP Activity Log hooks into, but it’s clearly not catching it ~45% of the time

    What we’ve tried:

    • Verified all relevant event IDs are enabled
    • Confirmed no user or IP exclusions
    • Confirmed data is missing from the database, not just the viewer
    • Verified our plugin code runs successfully (user meta timestamps exist)

    Questions:

    1. Does WP Activity Log rely on do_action('wp_login') specifically, or does it also hook into set_logged_in_cookie / set_auth_cookie?
    2. Is there a known issue with intermittent logging failures for users created via wp_insert_user() + wp_set_auth_cookie() without an explicit do_action('wp_login')?
    3. Is there a write buffer, queue, or deduplication mechanism that could silently drop events?
    4. Any debugging steps we can take to identify why specific users are not being recorded?

    Thank you.

    The page I need help with: [log in to see the link]

Viewing 3 replies - 1 through 3 (of 3 total)
  • Plugin Support Lucian Padureanu

    (@lucianwpwhite)

    Hello @travisninja22,

    Thanks for the detailed write-up. Before we dig into the logging side, can you clarify a couple of things?

    1. For the ~47 users with no entries in wp_wsal_occurrences — are these users who registered and never came back, or are they users who are actively using the site but WSAL simply never recorded anything for them?
    2. You mentioned last_login user meta confirms your plugin code ran. Does that meta get set at registration, at login, or both? Just want to understand if these 47 users definitely went through the full registration AND login flow, or if some of them may have only partially completed it.

    Now a few answers to your questions – should help for sure:

    On how WSAL hooks work: WSAL does not rely on do_action('wp_login') – it hooks into set_auth_cookie and uses the shutdown hook to write events. So skipping wp_login to avoid WooCommerce conflicts should not, in theory, break login logging.

    On the randomness: The ~45% miss rate being non-deterministic (not tied to time, browser, or IP) is a strong hint toward a race condition or shutdown hook timing issue. If the redirect following wp_set_auth_cookie() happens fast enough, the PHP process may terminate before the shutdown hook fires, dropping the queued events entirely. This would explain the random pattern? (just an educated guess?)

    What we’d suggest checking, on top of the above mentioned 1 and 2:

    1. Can you add a small delay or wp_ob_end_flush_all() before the redirect, just as a test, to see if the miss rate changes? This would help confirm or rule out the shutdown timing theory.
    2. Are you running any object caching (Redis, Memcached)? There is a known edge case where caching layers can interfere with the session/cookie state that WSAL reads at shutdown time.

    If you can share what you find with those two debugging steps, along with answers to my questions above, we can narrow this down further.

    Thread Starter travisninja22

    (@travisninja22)

    answers to your questions:

    1. The 47 missing users are a mix — some registered and never came back, some are actively using the site. We confirmed active users are missing by checking last_login timestamps.
    2. last_login gets set at both registration and login. All 47 went through the full flow — account created, OTP verified, auth cookie set, redirected. The user meta confirms the code executed completely.

    <span style=”font-size: inherit;”>i am testing the </span>wp_ob_end_flush_all()<span style=”font-size: inherit;”> fix and will report back with results.</span>

    thank you very much Lucían!

    Thread Starter travisninja22

    (@travisninja22)

    Hi Lucián,

    Thanks again for the earlier guidance. Here’s a full follow-up.

    How we authenticate (custom Ice Cream OTP Auth 1.0.6)
    On OTP success (signup or login): wp_insert_user when it’s a new account, then wp_set_current_user, destroy session tokens, wp_set_auth_cookieupdate_user_meta for last_login, then redirect. We do not call <code class=””>do_action( ‘wp_login’ ) on that path.

    Your questions (recap)
    The ~47 users with no WSAL rows were a mix of dormant and active users; we used last_login to confirm the OTP path had run (set at both registration and login for our flows).

    Object caching
    We don’t have a definite answer yet: no obvious Redis/Memcached plugin in wp-admin; there may still be host-level object cache—we can confirm with the host and update you.

    Shutdown / buffer test
    Per your suggestion we temporarily set <code class=””>define( ‘ICS_OTP_WSAL_FLUSH_TEST’, true ); in wp-config.php while the OTP plugin called <code class=””>wp_ob_end_flush_all() immediately before post-login redirects (OTP signup, OTP login, password-reset auto-login, account recovery). That constant has been removed from wp-config.php again after the test (flush off in production unless you want it back on).

    Other plugin (transparency)
    “IceCream Access Cookie” hooks set_logged_in_cookie to set a separate ics_access cookie and uses a very late <code class=””>shutdown callback for optional Hola HTML caching. We don’t think it blocks WSAL, but we can disable it for isolation if you want.

    Controlled retest — 4 Feb 2026 (local time = WSAL UI)
    Six manual OTP runs with the flush test on. Every run logged the expected signup chain: 6061 → 4000 → 1000 → 2101. Five of six also went through a second round (logout → OTP sign-in), and those showed 6061 → 1000 → 2101 again. No missing events in what we captured.

    1. [email protected] (~9:51–9:54 pm)
    2. [email protected] (~10:15–10:17 pm)
    3. [email protected] (~10:19–10:24 pm)
    4. [email protected] (~10:26–10:35 pm)
    5. [email protected] (~10:51–10:54 pm)
    6. [email protected] (~10:58–11:00 pm) — same full signup chain in WSAL; our export for this address did not include a second logout + OTP sign-in block like the other five (not that OTP was skipped for signup).

    Historical ~45% gaps vs this test
    The old missing rows line up with real Facebook ad traffic; these six were quiet, manual tests. So load / device / funnel / timing may still matter in production, even though this controlled sample was fully logged.

    SQL (optional check)
    <code class=””>SELECT username, COUNT(*) … FROM wp_wsal_occurrences for those six emails: all > 0 rows. Totals are inflated because we reused and deleted several of those addresses many times over time—not one session per count.

    Ask
    Given flush + 0 misses in this sample, does that fit your shutdown-timing theory for the older misses? Does WSAL 5.6.x document a recommended pattern (buffers, hook priority, deferring redirect) or any internal/debug way to confirm events are queued before the request ends?

    Thanks,
    Travis

Viewing 3 replies - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.