Claude Skill

wc-logging

Add production-safe WooCommerce logs with `wc_get_logger()`. Covers stable sources, severity levels and thresholds, structured JSON context, correlation IDs, sensitive-data redaction, WooCommerce 11.0 file-v2 formatting and batched retention cleanup, volume control, custom handle

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download lonsdale201-wp-agent-skills-woocommerce_wc-logging-52f6020.zip · 3 KB
Part of lonsdale201/wp-agent-skills — 226 skills

Install

skills CLI npx skills add https://github.com/Lonsdale201/wp-agent-skills/tree/main/woocommerce/wc-logging
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lonsdale201-wp-agent-skills@llmmart
Git git clone https://github.com/Lonsdale201/wp-agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole lonsdale201/wp-agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

WooCommerce logging

Use WooCommerce's shared logger for operational diagnostics that merchants can inspect in WooCommerce Status logs. Logs are disposable observability data, never the only record that a payment, migration, export, or webhook completed.

Basic pattern

$logger = wc_get_logger();

$logger->info(
    'Order export queued.',
    array(
        'source'         => 'myplugin-export',
        'order_id'       => $order_id,
        'correlation_id' => $correlation_id,
        'attempt'        => $attempt,
    )
);

Always set a stable, plugin-prefixed source. Current file logging sanitizes it and expects at least three characters. Do not generate one source per order, user, request, or date; that fragments log browsing and creates excessive files/source records.

Levels

Level Use
debug Detailed development diagnostics; high volume and normally thresholded in production
info Normal lifecycle milestones useful for operations
notice Significant but expected condition
warning Recoverable anomaly, fallback, retry, deprecation, or degraded behavior
error Operation failed but the application remains usable
critical A component or important workflow is unavailable
alert Immediate operator action is required
emergency Store/system is unusable

Use the level methods (debug(), info(), warning(), error()) or log(). WC_Logger::add() is legacy and explicitly not the preferred API.

WooCommerce can disable logging globally and can set a minimum severity threshold. In 11.0.0 the default threshold is none, meaning all levels are accepted, but site settings or WC_LOG_THRESHOLD can change that. Never make application correctness depend on a log entry being handled.

Structured context

Prefer a constant message plus small, allowlisted context:

$logger->error(
    'Provider capture failed.',
    array(
        'source'             => 'myplugin-gateway',
        'order_id'           => $order->get_id(),
        'provider_reference' => myplugin_mask_reference( $provider_reference ),
        'provider_code'      => sanitize_key( $provider_code ),
        'correlation_id'     => $correlation_id,
    )
);

Current file-v2 handling JSON-encodes context other than source. WooCommerce 11.0 writes that JSON without adding/removing slashes and preserves unescaped Unicode and URL slashes. Pass ordinary unslashed PHP values; do not call addslashes()/stripslashes() around logger context. Other handlers may format it differently, so pass serializable scalars/small arrays, not WC_Order, HTTP response objects, exceptions, resources, or closures.

Use a request/job correlation ID that is random and non-secret. Carry it across the initial request, Action Scheduler args, provider metadata, and log context where practical. It should help joins without identifying a customer.

Sensitive-data boundary

Never log:

  • passwords, API keys, OAuth secrets, bearer/provider tokens;
  • cookies, Cart-Tokens, nonces, webhook signatures, authorization headers;
  • PAN/card numbers, CVV, bank credentials, magnetic-stripe data;
  • complete provider/webhook/REST request or response bodies;
  • full email, phone, postal address, IP address, or unnecessary customer text;
  • URLs containing secret or personal query parameters;
  • raw SQL containing personal values.

Redact before calling the logger. A later filter is defense in depth, not permission to send secrets into the logging pipeline. Prefer provider error codes and masked references over $exception->getMessage() or exception objects because messages/stacks can contain request payloads, credentials, filesystem paths, and PII.

function myplugin_mask_reference( string $value ): string {
    $value = preg_replace( '/[^A-Za-z0-9_-]/', '', $value );
    return strlen( $value ) > 6 ? '...' . substr( $value, -6 ) : '[redacted]';
}

Gateway and webhook example

try {
    $result = $client->capture( $provider_payment_id, $amount );
} catch ( Throwable $error ) {
    wc_get_logger()->error(
        'Capture request failed.',
        array(
            'source'          => 'myplugin-gateway',
            'order_id'        => $order_id,
            'exception_class' => get_class( $error ),
            'correlation_id'  => $correlation_id,
        )
    );

    throw new RuntimeException( 'Provider capture failed.' );
}

Do not return log detail to the customer. Customer/admin messages, private order notes, and diagnostic logs have different audiences.

Volume and hot paths

  • Do not log every product, cart calculation, price getter, REST schema call, or session read at info.
  • Log batch/job start, aggregate result, retry, and final failure; use debug for bounded per-item detail.
  • Avoid backtrace => true except targeted debugging: backtraces cost CPU/memory and expose paths.
  • Do not serialize large arrays to context.
  • Rate-limit repeated warnings for the same root cause.
  • Remove temporary debug logging before release or keep it behind a plugin debug setting disabled by default.

Logging itself can fail because of permissions, disk, database, handler, or global settings. Never let a logging failure replace or mask the primary business exception.

Retention and handlers

WooCommerce 11.0.0 defaults to file-v2 handling and 30-day retention, but merchants can change logging enabled state, handler, retention, and threshold. Cleanup runs on woocommerce_cleanup_logs through wc_cleanup_logs(). File-v2 cleanup now scans/deletes expired files in batches of 100, continuing past vetoed files; a retention filter can preserve a file without causing later expired pages to be skipped.

Do not delete or rotate WooCommerce log files directly. Do not assume file paths; the active handler may use database storage or a custom implementation.

To add a handler, filter instances through woocommerce_register_log_handlers and implement WC_Log_Handler_Interface. Keep the default handler unless replacement is an explicit store policy. A custom remote handler must have strict timeouts/queueing, redaction, bounded retries, and must never block checkout.

woocommerce_logging_class replaces the shared logger and affects every WooCommerce extension. Do not use it for a plugin-local transport unless you intentionally own the store-wide logging contract.

Filtering and suppression

woocommerce_logger_log_message runs per handler and returning null suppresses that entry for that handler. Global filters can affect unrelated plugins, so scope by context['source'] and avoid broad message rewriting.

Use suppression only for deliberate redaction/volume policy. Do not hide payment or migration failures to make logs appear clean.

Logs versus durable state

Store these in an owned model/order metadata, not only logs:

  • provider event IDs and idempotency claims;
  • migration/schema version and completed steps;
  • export/import cursor and completion state;
  • external order/payment identifiers;
  • retry count when it controls business behavior;
  • audit records required by policy.

The log can reference the durable record with an ID.

Critical rules

  • Always use a stable plugin-prefixed source.
  • Log allowlisted structured context, not raw objects/payloads.
  • Redact before logging and keep PII to the minimum.
  • Choose levels semantically; production thresholds may drop low-severity entries.
  • Keep logs bounded in hot paths and background loops.
  • Never depend on a log as durable state or an idempotency lock.
  • Never expose diagnostic messages directly to customers.

Cross-references

  • wc-action-scheduler-jobs for job retries and aggregate logging.
  • wc-order-lifecycle-and-items for durable order notes/meta versus diagnostics.

References

  • Shared logger and cleanup: includes/wc-core-functions.php.
  • levels, thresholds, handlers, and filters: includes/class-wc-logger.php.
  • default settings and retention: src/Internal/Admin/Logging/Settings.php.
  • Verified source paths:
    • wp-content/plugins/woocommerce/includes/class-wc-log-levels.php
    • wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-log-handler.php
    • wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-db.php
    • wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php
    • wp-content/plugins/woocommerce/src/Utilities/LoggingUtil.php
Files (wp-agent-skills)
  • SKILL.md 9 KB
    ---
    name: wc-logging
    description: Add production-safe WooCommerce logs with `wc_get_logger()`. Covers stable sources, severity levels and thresholds, structured JSON context, correlation IDs, sensitive-data redaction, WooCommerce 11.0 file-v2 formatting and batched retention cleanup, volume control, custom handlers, and why logs are not durable business state. Use when adding diagnostics to gateways, webhooks, background jobs, imports, REST endpoints, or order integrations.
    metadata:
      wp-skills-author: "Soczó Kristóf"
      wp-skills-contact: "mailto:lonsdale201@hotmail.com"
      wp-skills-plugin: "woocommerce"
      wp-skills-plugin-version-tested: "11.0.0"
      wp-skills-php-min: "7.4"
      wp-skills-last-updated: "2026-08-05"
    ---
    
    # WooCommerce logging
    
    Use WooCommerce's shared logger for operational diagnostics that merchants can inspect in WooCommerce Status logs. Logs are disposable observability data, never the only record that a payment, migration, export, or webhook completed.
    
    ## Basic pattern
    
    ```php
    $logger = wc_get_logger();
    
    $logger->info(
        'Order export queued.',
        array(
            'source'         => 'myplugin-export',
            'order_id'       => $order_id,
            'correlation_id' => $correlation_id,
            'attempt'        => $attempt,
        )
    );
    ```
    
    Always set a stable, plugin-prefixed `source`. Current file logging sanitizes it and expects at least three characters. Do not generate one source per order, user, request, or date; that fragments log browsing and creates excessive files/source records.
    
    ## Levels
    
    | Level | Use |
    |---|---|
    | `debug` | Detailed development diagnostics; high volume and normally thresholded in production |
    | `info` | Normal lifecycle milestones useful for operations |
    | `notice` | Significant but expected condition |
    | `warning` | Recoverable anomaly, fallback, retry, deprecation, or degraded behavior |
    | `error` | Operation failed but the application remains usable |
    | `critical` | A component or important workflow is unavailable |
    | `alert` | Immediate operator action is required |
    | `emergency` | Store/system is unusable |
    
    Use the level methods (`debug()`, `info()`, `warning()`, `error()`) or `log()`. `WC_Logger::add()` is legacy and explicitly not the preferred API.
    
    WooCommerce can disable logging globally and can set a minimum severity threshold. In 11.0.0 the default threshold is `none`, meaning all levels are accepted, but site settings or `WC_LOG_THRESHOLD` can change that. Never make application correctness depend on a log entry being handled.
    
    ## Structured context
    
    Prefer a constant message plus small, allowlisted context:
    
    ```php
    $logger->error(
        'Provider capture failed.',
        array(
            'source'             => 'myplugin-gateway',
            'order_id'           => $order->get_id(),
            'provider_reference' => myplugin_mask_reference( $provider_reference ),
            'provider_code'      => sanitize_key( $provider_code ),
            'correlation_id'     => $correlation_id,
        )
    );
    ```
    
    Current file-v2 handling JSON-encodes context other than `source`. WooCommerce 11.0 writes that JSON without adding/removing slashes and preserves unescaped Unicode and URL slashes. Pass ordinary unslashed PHP values; do not call `addslashes()`/`stripslashes()` around logger context. Other handlers may format it differently, so pass serializable scalars/small arrays, not `WC_Order`, HTTP response objects, exceptions, resources, or closures.
    
    Use a request/job correlation ID that is random and non-secret. Carry it across the initial request, Action Scheduler args, provider metadata, and log context where practical. It should help joins without identifying a customer.
    
    ## Sensitive-data boundary
    
    Never log:
    
    - passwords, API keys, OAuth secrets, bearer/provider tokens;
    - cookies, Cart-Tokens, nonces, webhook signatures, authorization headers;
    - PAN/card numbers, CVV, bank credentials, magnetic-stripe data;
    - complete provider/webhook/REST request or response bodies;
    - full email, phone, postal address, IP address, or unnecessary customer text;
    - URLs containing secret or personal query parameters;
    - raw SQL containing personal values.
    
    Redact before calling the logger. A later filter is defense in depth, not permission to send secrets into the logging pipeline. Prefer provider error codes and masked references over `$exception->getMessage()` or exception objects because messages/stacks can contain request payloads, credentials, filesystem paths, and PII.
    
    ```php
    function myplugin_mask_reference( string $value ): string {
        $value = preg_replace( '/[^A-Za-z0-9_-]/', '', $value );
        return strlen( $value ) > 6 ? '...' . substr( $value, -6 ) : '[redacted]';
    }
    ```
    
    ## Gateway and webhook example
    
    ```php
    try {
        $result = $client->capture( $provider_payment_id, $amount );
    } catch ( Throwable $error ) {
        wc_get_logger()->error(
            'Capture request failed.',
            array(
                'source'          => 'myplugin-gateway',
                'order_id'        => $order_id,
                'exception_class' => get_class( $error ),
                'correlation_id'  => $correlation_id,
            )
        );
    
        throw new RuntimeException( 'Provider capture failed.' );
    }
    ```
    
    Do not return log detail to the customer. Customer/admin messages, private order notes, and diagnostic logs have different audiences.
    
    ## Volume and hot paths
    
    - Do not log every product, cart calculation, price getter, REST schema call, or session read at `info`.
    - Log batch/job start, aggregate result, retry, and final failure; use `debug` for bounded per-item detail.
    - Avoid `backtrace => true` except targeted debugging: backtraces cost CPU/memory and expose paths.
    - Do not serialize large arrays to context.
    - Rate-limit repeated warnings for the same root cause.
    - Remove temporary debug logging before release or keep it behind a plugin debug setting disabled by default.
    
    Logging itself can fail because of permissions, disk, database, handler, or global settings. Never let a logging failure replace or mask the primary business exception.
    
    ## Retention and handlers
    
    WooCommerce 11.0.0 defaults to file-v2 handling and 30-day retention, but merchants can change logging enabled state, handler, retention, and threshold. Cleanup runs on `woocommerce_cleanup_logs` through `wc_cleanup_logs()`. File-v2 cleanup now scans/deletes expired files in batches of 100, continuing past vetoed files; a retention filter can preserve a file without causing later expired pages to be skipped.
    
    Do not delete or rotate WooCommerce log files directly. Do not assume file paths; the active handler may use database storage or a custom implementation.
    
    To add a handler, filter instances through `woocommerce_register_log_handlers` and implement `WC_Log_Handler_Interface`. Keep the default handler unless replacement is an explicit store policy. A custom remote handler must have strict timeouts/queueing, redaction, bounded retries, and must never block checkout.
    
    `woocommerce_logging_class` replaces the shared logger and affects every WooCommerce extension. Do not use it for a plugin-local transport unless you intentionally own the store-wide logging contract.
    
    ## Filtering and suppression
    
    `woocommerce_logger_log_message` runs per handler and returning `null` suppresses that entry for that handler. Global filters can affect unrelated plugins, so scope by `context['source']` and avoid broad message rewriting.
    
    Use suppression only for deliberate redaction/volume policy. Do not hide payment or migration failures to make logs appear clean.
    
    ## Logs versus durable state
    
    Store these in an owned model/order metadata, not only logs:
    
    - provider event IDs and idempotency claims;
    - migration/schema version and completed steps;
    - export/import cursor and completion state;
    - external order/payment identifiers;
    - retry count when it controls business behavior;
    - audit records required by policy.
    
    The log can reference the durable record with an ID.
    
    ## Critical rules
    
    - Always use a stable plugin-prefixed source.
    - Log allowlisted structured context, not raw objects/payloads.
    - Redact before logging and keep PII to the minimum.
    - Choose levels semantically; production thresholds may drop low-severity entries.
    - Keep logs bounded in hot paths and background loops.
    - Never depend on a log as durable state or an idempotency lock.
    - Never expose diagnostic messages directly to customers.
    
    ## Cross-references
    
    - `wc-action-scheduler-jobs` for job retries and aggregate logging.
    - `wc-order-lifecycle-and-items` for durable order notes/meta versus diagnostics.
    
    ## References
    
    - Shared logger and cleanup: `includes/wc-core-functions.php`.
    - levels, thresholds, handlers, and filters: `includes/class-wc-logger.php`.
    - default settings and retention: `src/Internal/Admin/Logging/Settings.php`.
    - Verified source paths:
      - `wp-content/plugins/woocommerce/includes/class-wc-log-levels.php`
      - `wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-log-handler.php`
      - `wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-db.php`
      - `wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php`
      - `wp-content/plugins/woocommerce/src/Utilities/LoggingUtil.php`
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related