lonnieezell / monarch

A back-to-basics framework for the modern web.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Log Engine

lonnieezell opened this issue · comments

Incorporate Monolog for logging.

Also provide logging via a PHP attribute on a Control method:

#[Loggable]
public function get()
{
    //
}

This simply says that if any Throwable is thrown during this method, it should be logged, then re-thrown.

You can pass in an array of specific exceptions it should catch to limit what is logged.

#[Loggable(catch: [DatabaseException, RuntimeException])]

This can be used multiple times to specify the severity for different exceptions:

#[Loggable(catch: [DatabaseException], level: 'critical'), Loggable(catch: [RuntimeException], level: 'error')]

Have you tried https://tracy.nette.org for error debugging/logging?

For me it is the most valuable of all the Nette packages. Really lightweight and well thought through tool.

It is easy to integrate monolog:

https://tracy.nette.org/en/recipes#toc-monolog-integration

Have you tried https://tracy.nette.org/ for error debugging/logging?

I've glanced at it. Not sure what I want to use yet. Might have to build something custom since this framework is going to have a heavy integration with HTMX. No decisions yet, though.

Thanks for the suggestion!

I've never actually used Nette before, but have known of it for awhile and been impressed with several of the parts. The handful of pieces I'm bringing over seems to suit the goals of this experiment just fine.

I've had a chance to look Tracy over and it looks perfect. Replaces Kint, and includes basic profiling tools, error emailing, scrubbing, plus all of the addons! Sounds like a definite yes from me. Thanks for pointing it out @eydun

The bdump()-function is really handy when debugging the application (https://tracy.nette.org/en/dumper). Also for ajax-requests.

Working through attempting to integrate now. It's being a little challenging to work well with HTMX but I'm still trying.

Let me know if I can be of any assistance.

I would love it if you could take a look. It seems to be working fine on a fresh page load, but boosted pages aren't currently working. You can find my current state in this PR.

Thanks.

The issue is that Tracy does not get loaded, when using boosted attributes. I think it is because that the <head>-section does not get loaded with boosted pages. Maybe this can be solved with the htmx head-support extension.

But the easiest solution, is to add Tracy to the <head>-section with Tracy\Debugger::renderLoader();.

As a test I modified +layout.php (without the latest pull-request), and it worked:

<!doctype html>
<html class="no-js" lang="en-US" data-bs-theme="dark">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?= viewMeta()->title() ?></title>
    <?= viewMeta()->output('meta') ?>

    <?= Tracy\Debugger::renderLoader(); ?>

    <link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">

I got the idea to use renderLoader() from this example:
https://github.com/nette/tracy/blob/master/examples/preloading.php

Instead of only enabling Tracy under development:

if (getenv('DEBUG')) {
    Debugger::enable(Debugger::Development);
}

you can choose to always enable Tracy:

Debugger::enable(getenv('DEBUG') ? Debugger::Development : Debugger::Production, WRITEPATH.'logs');

When 'mode' is set to "Debugger::Development", then the Tracy-bar is visible, and errors are shown on page.
When 'mode' is set to "Debugger::Production", then the Tracy-bar is hidden, and errors are logged to files (WRITEPATH.'logs').

But the easiest solution, is to add Tracy to the -section with Tracy\Debugger::renderLoader();

Hm. Could have sworn I tried that. I'll take a look later. My weekdays area pretty slammed between day job I've picked up a freelance project, too....

Any idea if this allows Tracy to show the other AJAX requests? You can checkout the API tab to see. That's part of what I was hoping the solution I was attempting in the middleware would help with.

Thanks for taking a look into this!

Yes - it works for all other Ajax-request also:

image

Here I added Debugger::barDump() to the response:

    protected function respond(array $body): static
    {
        $this->body = $body;
        Debugger::barDump($this->body);
        return $this;
    }

I have not tried with the new middleware yet. But I am quite sure, that you are not required to add the hx-headers: <body hx-headers="{'X-Tracy-Ajax': Tracy.getAjaxHeader() }">.

I have not tried with the new middleware yet. But I am quite sure, that you are not required to add the hx-headers: .

This was to instruct HTMX to send headers that would manually instruct Tracy to capture each AJAX request. Probably not required but was one of my attempts to get it to capture everything.

Trying to get the middleware to insert the debugger automatically so people don't need to remember to put it in their layouts. Haven't gotten it working yet, but I've only had about 15 minutes tonight. And now I need to hit the sack. Gotta get up in a little under 6 hours.

Here's my current version of the middleware. This does successfully insert the toolbar on a fresh page load. But then clicking any of the menu items doesn't refresh it. Well, with the top part commented out, it adds the AJAX row, but then stops updating. Sometimes. Other times, it doesn't refresh at all with an error in the console about Tracy object being null.

<?php

namespace Monarch\HTTP\Middleware;

use Closure;
use Monarch\HTTP\Header;
use Monarch\HTTP\Request;
use Monarch\HTTP\Response;
use Tracy\Debugger as TracyDebugger;

class Debugger
{
    public function handle(Request $request, Response $response, Closure $next)
    {
        // Attach Tracy to the end of the content if it's enabled
        if (DEBUG && $request->isHtmx()) {
            // TracyDebugger::dispatch();
            //$response->withHeader(new Header('X-Tracy-Ajax', '1'));
        }

        $html = $next($request, $response);

        // Insert Tracy into the content if it's enabled
        if (DEBUG && ! $request->isHtmx()) {
            $html = str_replace('</title>', "</title>\n". TracyDebugger::renderLoader(), $html);
            );
        }

        return $html;
    }
}

Seems that renderLoader() is returning null for some reason here when I step through it.

Could it be related to getenv('DEBUG') not returning true in index.php?

And now I need to hit the sack. Gotta get up in a little under 6 hours.

Sleep is important 🙂

Here's my current version of the middleware.

I just tested your version, and it seems to working perfectly on my machine.

Are there perhaps other code-changes, that you have made, that have not been added to the pull-request?

Alright, I got something that works well enough for now, I believe.

The one thing that I couldn't get working yet was for it to show up on links viewed through HTMX-boosted links in the navbar. AJAX works fine, it logs to the WRITEABLE/logs folder, and the error screen shows up as expected.

Good enough to integrate. I'll wait a day or two to merge that branch in if you want to give it a once over and see if you have any recommendations.

Looking good! Like the option to configure Tracy in config-folder 👍

I just set debug: false in .env, and debugger is still active. Maybe change index.php like this:

if (! defined('DEBUG')) {
    define('DEBUG', strtolower((getenv('DEBUG')) === "true")  ?? false);
}

and in startTracy() use the defined constant:

        Debugger::enable(constant('DEBUG') ? Debugger::Development : Debugger::Production);

When using ajax on "/api", I get this error:

image

Strange. I'm not seeing that, and I don't think anything should be rewriting a header there. That's just the default API page?

I think I'm going to go ahead and merge this branch and we can sort out any bugs from there.

Thanks. I get the errors when clicking on the buttons "GET JSON", "Post JSON", "Put JSON" and "Delete JSON".

Can the properties $name and $value be readonly, and also be set in the constructor?

namespace Monarch\HTTP;

class Header
{
    public function __construct(
        public readonly string $name,
        public readonly string|array $value
    ) {
        $this->name = $name;
        $this->value = $value;
    }
}