Drupal is a registered trademark of Dries Buytaert
Protected Pages 3.0.0 Major update available for module protected_pages (3.0.0). Commerce Core 3.3.8 Minor update available for module commerce (3.3.8). Layout Builder Reorder 2.0.1 Minor update available for module layout_builder_reorder (2.0.1). Ban 1.1.0 Minor update available for module ban (1.1.0). Field Formatter Range 2.0.0 Major update available for module field_formatter_range (2.0.0). Field Formatter Range 8.x-1.8 Minor update available for module field_formatter_range (8.x-1.8). UI Patterns (SDC in Drupal UI) 2.0.18 Minor update available for module ui_patterns (2.0.18). Varbase FAQs 9.2.1 Minor update available for module varbase_faqs (9.2.1). Search API Solr 4.3.11 Module search_api_solr updated after 14 months of inactivity (4.3.11). Provus Mega Menu Module provus_mega_menu crossed 1,000 active installs.

This module allows decoupled applications and mobile apps to send frontend error logs directly to Drupal. It provides a private, self-hosted logging solution without third-party dependencies, storing logs as entities that can be managed with Drupal's existing tools like Views. The module includes features like rate limiting and payload size restrictions to prevent abuse and manage resources effectively.

Overview

Collect frontend error logs from your decoupled/mobile app directly into Drupal to realize self-hosted, private logging with no third-party dependencies or per-event billing.

This module is intended for small-scale apps so that you can handle your own logging and users' crash data never leaves your server. Also, it might save you a little money.

The module provides a JSON Log entity type (machine name: log_json) and REST/JSON:API endpoints for uploading the logs. You can log the device info and a log payload (errors are included by default, but you can add whatever you want).

Features

  • Send a JSON payload via REST or JSON:API from your frontend (mobile app) to log data in Drupal.
  • Non admins can only create logs; secure configuration by default.
  • Logs are just entities, so you can use Views, bulk operations, and other Drupal contrib modules (e.g., ECA) for emails and other alerts.
  • Categorize logs by creating new entity types (e.g., warning, notification) to fit your logging needs.
  • Endpoint rate limiting and payload size limiting can be customized to your situation.

Dependencies

This module stores log entries as JSON, so it uses the JSON Field module.

Post-Installation

Go to /admin/people/permissions and give the Create json logs permission to all roles that should be able to create logs.

Determine what you want to log. By default, this module provides an error bundle for logging errors. You can add other log types at /admin/structure/log_json_types.

Go to /admin/config/decoupled_json_log and confirm the rate limit and payload size settings, described below.

Configuration

Rate limiting

To stop a buggy or malicious frontend from flooding your site with log entries, each user is limited to a maximum number of log entries per rolling time interval:

  • Count for anonymous users (rate_limit.count_anon, default 500): the maximum number of entries the anonymous user can create during the interval. Because every anonymous visitor shares the anonymous account, this limit is shared across all of them, so it is usually set higher than the authenticated limit.
  • Count for authenticated users (rate_limit.count_auth, default 50): the maximum number of entries each authenticated user can create during the interval.
  • Interval (rate_limit.interval_seconds, default 86400, i.e. one day): the length of the rolling window, in seconds, over which entries are counted.

The author (uid) and creation time (created) of each entry are always stamped by the server, so clients cannot evade the rate limit by spoofing them.

Payload size limits

To stop oversized entries from bloating your database, the two JSON fields are capped by byte size. An entry that exceeds the limit is rejected, and the oversized payload is recorded in the module's log channel.

  • Maximum log size (max_payload_bytes.log, default 65536, i.e. 64KB): the maximum size in bytes of the log field.
  • Maximum device info size (max_payload_bytes.device_info, default 8192, i.e. 8KB): the maximum size in bytes of the device_info field.

Assumptions

This module assumes you want to let users log events but limit access to managing those logged events to admins.

For this reason, you can only POST log entities via REST and JSON:API; you cannot GET, PATCH, or DELETE them. If you object to this, open a feature request and I will make it configurable.

Sample TS Code

You can create log entries in the standard way with JSON:API.

  /**
   * Stringifies an Error object, since error.toString() doesn't.
   *
   * https://stackoverflow.com/a/30604852
   */
  const stringifyError = (error: Error) =>
      JSON.stringify(error, [
        'message',
        'arguments',
        'type',
        'name',
        'cause',
      ]);

  // Use a function in your frontend to get device info.
  // For example, capacitor has a nice function:
  // https://capacitorjs.com/docs/apis/device#getinfo
  const deviceInfo = await Device.getInfo();

  // Log the error with axios.
  axiosInstance({
    url: 'https://www.example.com/jsonapi/log_json--error',
    data: {
      data: {
        type: 'error',
        attributes: {
          label: 'FrontendFatalError',
          log: stringifyError(error),
          device_info: deviceInfo,
        }
      }
    },
    headers: {
      Accept: application/vnd.api+json,
      'Content-Type': application/vnd.api+json,
      'X-CSRF-Token': 'you_must_get_csrf_token_from_drupal',
    },
    method: 'POST',
  })

Supporting This Module

All contributions are welcome. Please submit MRs, not patches, so that the CI tests are run. Please add tests if possible.

AI Development Disclosure

I use AI agents (Claude Code and Codex) to develop this module. It was originally written by hand, but most of the tests and some security features were implemented with AI assistance.

Activity

Total releases
3
First release
Jul 2025
Latest release
1 week ago
Releases (12 mo)
3 ▲ from 0
Maintenance
Active

Release Timeline

Releases

Version Type Release date
1.1.0 Stable Jul 4, 2026
1.0.0 Stable Jun 21, 2026
1.0.0-beta1 Pre-release Jul 23, 2025