Skip to content

Commit

Permalink
Add logger API (#1113)
Browse files Browse the repository at this point in the history
This PR adds a logger API endpoint to Playground.WordPress.net.

## What problem is it solving?

It creates a standard place where users can send crash reports.

## How is the problem addressed?

A PHP script accepts the log message, validates the format, and sends
the log message to a Making WordPress Slack channel.

## Testing Instructions

- Start a local PHP server 
- Copy the `logger.php` file to the server
- Follow the readme to get the token and replace the token and channel
ID [with these values in
logger.php](https://github.com/WordPress/wordpress-playground/pull/1113/files#diff-40d926630e2b7f17f2bff83810ab64c7beb5b2f5333f1c94ee2e3fbb2b0afb2cR3-R4)
- Send a request and confirm a message was sent to the Slack channel
(replace _http://localhost:10013/logger.php_ with your path)
```
curl --location 'http://localhost:10013/logger.php' \
--form 'message="What happened?

Ut consequuntur esse sint sequi sapiente corrupti. Suscipit est facere voluptatem omnis earum necessitatibus molestiae. Exercitationem odio id ut alias voluptatum.

Dolor ut dolores labore hic at. Aspernatur provident voluptatem dignissimos et aut minima et aut. Eaque odio aut consequatur quam quidem.

Logs

[02-Jan-2024 08:08:06 UTC] PHP-WASM Fatal: null function or function signature mismatch Error: null function or function signature mismatch
    at #handleRequest (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/base-php.ts?t=1710835676492:518:24)
    at async WebPHP.run (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/base-php.ts?t=1710835676492:211:24)
    at async #dispatchToPHP (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/php-request-handler.ts?t=1710835676492:178:14)
    at async PHPRequestHandler.request (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/php-request-handler.ts?t=1710835676492:84:14)
    at async PHPBrowser.request (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/php-browser.ts:32:22)
[19-Mar-2024 08:08:06 UTC] PHP-WASM Fatal: null function or function signature mismatch Error: null function or function signature mismatch
    at #handleRequest (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/base-php.ts?t=1710835676492:518:24)
    at async WebPHP.run (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/base-php.ts?t=1710835676492:211:24)
    at async #dispatchToPHP (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/php-request-handler.ts?t=1710835676492:178:14)
    at async PHPRequestHandler.request (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/php-request-handler.ts?t=1710835676492:84:14)
    at async PHPBrowser.request (http://localhost:5400/@fs/Users/bero/Projects/wordpress-playground/packages/php-wasm/universal/src/lib/php-browser.ts:32:22)

Url

http://localhost:5400/website-server/?php=8.0&wp=latest&storage=none&networking=yes#%7B%20%22landingPage%22:%20%22/wp-admin/%22,%20%22features%22:%20%7B%20%22networking%22:%20true%20%7D,%20%22steps%22:%20%5B%20%7B%20%22step%22:%20%22login%22%20%7D,%20%7B%20%22step%22:%20%22writeFile%22,%20%22path%22:%20%22/wordpress/wp-content/mu-plugins/rewrite.php%22,%20%22data%22:%20%22%3C?php%20add_action(%20'\''shutdown'\'',%20function()%20%7B%20post_message_to_js('\''test'\'');%20%7D%20);%22%20%7D%20%5D%20%7D"'
```
  • Loading branch information
bgrgicak authored Mar 20, 2024
1 parent c988f06 commit 8aedfa8
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/docs/site/docs/13-contributing/07-crash-reports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
sidebar_position: 7
title: Crash Reports
---

# Playground.WordPress.net Crash Reports

When Playground crashes on Playground.WordPress.net users are able to submit a crash report. These reports are stored in the [#playground-logs channel on the Making WordPress Slack](https://wordpress.slack.com/archives/C06Q5DCKZ3L).

**Playground doesn't collect crash reports automatically.** Instead, users are prompted to submit a crash report when a crash occurs and are able to modify it before submitting. The crash report includes a Playground logs, a description, and the url.

## Development

Logs are sent to the [logger API on Playground.WordPress.net](https://github.com/WordPress/wordpress-playground/blob/c52d7dbd94dbe3ffc57adde4d9844545ade97f93/packages/playground/website/public/logger.php). The logger API is a simple REST API that accepts a POST request with a `message` parameter.
The API validates the message and then sends it to the [#playground-logs channel on the Making WordPress Slack(https://wordpress.slack.com/archives/C06Q5DCKZ3L).

### Slack app

[We use the Playground Slack app](https://api.slack.com/apps/A06PEFZ00SG) to send logs to the #playground-logs channel.

The [Slack app OAuth token](https://api.slack.com/apps/A06PEFZ00SG/oauth?) and channel id are stored on Playground.WordPress.net as environment variables in `.htaccess`.
96 changes: 96 additions & 0 deletions packages/playground/website/public/logger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php
// Disable error reporting
error_reporting(0);

header('Content-Type: application/json');

$channel = getenv('SLACK_CHANNEL');
$token = getenv('SLACK_TOKEN');

/**
* Send response to the client
*
* @param bool $ok - If the request was successful
* @param string|null $error - Error message if the request was not successful
*/
function response($ok, $error = null)
{
$response_data = array(
'ok' => $ok,
);
if ($error) {
$response_data['error'] = $error;
}
die(json_encode($response_data));
}

/**
* Validate the message format
*
* @param string $message - The message to validate
* @return bool - If the message is valid
*/
function validate_message($message)
{
// Validate description. Description is required
preg_match('/(?<=What happened\?\n\n)(.*?)(?=\n\nLogs)/s', $message, $description);
if (empty($description)) {
return false;
}

// Validate logs if exists. Logs need to match the PHP error log format
preg_match('/(?<=Logs\n\n)(.*?)(?=\n\nUrl)/s', $message, $logs);
if (!empty($logs)) {
$logs = $logs[0];
if (preg_match('/\[\d{2}-[A-Za-z]{3}-\d{4} \d{2}:\d{2}:\d{2} UTC\](.*)/s', $logs) !== 1) {
return false;
}
}

// Validate URL if exists
preg_match('/(?<=Url\n\n)(.*)/s', $message, $url);
if (!empty($url)) {
$url = $url[0];
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
return false;
}
}

return true;
}

if (empty($token)) {
response(false, 'No token provided');
}

if (!isset($_POST['message'])) {
response(false, 'No message provided');
}
$text = $_POST['message'];

if (!validate_message($text)) {
response(false, 'Invalid message');
}
$text = urlencode($text);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://slack.com/api/chat.postMessage?channel=$channel&text=$text");
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer $token"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($ch);
$errors = curl_error($ch);
$response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);


if ($response_code !== 200) {
response(false, 'HTTP Error: ' . $errors);
}

$response_data = json_decode($response, true);
if ($response_data['ok'] !== true) {
response(false, 'Slack Error: ' . $response_data['error']);
}

response(true);

0 comments on commit 8aedfa8

Please sign in to comment.