Debugging a custom php app in production

Hi. New to

I have created a simple php app with a sqlite database. The app is deployed and works as intended. Almost. The app works in development but acts differently in production (hosted on

How can I debug my functions? Currently, I’m writing a log with fopen() but that is pretty hacky and doesn’t always work. The logs also get deleted quickly.

Is there a way to log/print the output of a function to the monitor/log?

Bear in mind that I’m not using a Laravel template but a custom-made php app.

Hello @erik-lindberg! Welcome to!

There are two things we can inspect in your setup above:

1. Logs are getting deleted quickly

  • Reads like you’re writing/printing logs to a file, right? Have you persisted data in the folder this file is located in? If not, every re-deployment of your Fly app is going to re-create your app from scratch, resulting in the loss of any generated files from your app’s previous run!

  • You can persist data in a folder by mounting a Volume to that folder . Data stored in the folder would get persisted to a Volume, which can be re-attached on every successful re-deployment of your app. This makes previously generated files accessible on every new deployment!

  • If you’re curious, you can also check out how to persist the “storage” folder in a Laravel app.

2. Print logs in the monitor/log

  • can listen and capture logs sent to your application’s stdout. Captured logs can then be viewed via the fly logs command, or viewed in your app’s monitoring console<app-name>/monitoring.

  • Aside from’s default service that allows yo to capture logs sent to stdout( which are temporarily available btw! ), you can also send captured logs to a longer persisted place through the Fly Log Shipper

Hopefully one of the above directions can gets your logs in a better place!

1 Like

Hi kathrynannetan.

Thanks for responding to my question.

Regarding 2. point.

I am able to write the the log using something like this.

$obj = print_r($someDataObject,true);
file_put_contents("php://stdout", $obj ."\n");

That works great. thx for that.

But… My app fires a request to a web service when triggered by a webhooks. Unfortunately, that doesn’t get picked up by the logs. I tried php://stderr. Same result.

Any idea why I cant log anything from within the callback of a webhook?

Thx again.

That works great. thx for that.

That’s great to read!

Any idea why I cant log anything from within the callback of a webhook?

Now, with regards to why logs aren’t received from your webhook callback, one factor causing this could revolve around where this “callback” is running from. Is it running from:

a) the same Fly App as your main app?
b) on a different Fly App?
c) or is it running outside of

Aside from where this callback is running from, can you further check if it is actually getting called? It might be a case where the callback is not actually getting reached as well!

Yes, I see the callback being logged and it is being called from Shopify (orders/create) But not from the Shopify admin. All code is within my Fly app.

2023-12-18T07:56:40Z app[4d89dee2c3d078] arn [info] - - [18/Dec/2023:07:56:40 +0000] "POST /web/nav/CreateNavOrder.php HTTP/1.1" 200 550 "-" "Shopify-Captain-Hook"

And I’m able to write a log up until an API call I do within that function.

To give a little more insight. When an order is created in Shopify we pick that up and send it to a web service as a curl call. The funny thing is that the same call is made in another file that updates the stock. That works fine. I just need to bugfix what’s going on with the request/response of that call.

Could the issue be that the log is deleted even before I get a chance to read it? Also, I’m only running 1 machine so I’m sure I’m fly ssh console into the right machine.

I believe logs stick around for ~2 days so in theory you should be able to see it!

I wonder if it’s worth shipping logs to an aggregator, either through a PHP integration with a logging app such as logtail, or via a Fly VM used to collect logs

Writing logs to a directory on a mounted volume might be a tad easier (so you can be sure they persist).

And I’m able to write a log up until an API call I do within that function.

that’s interesting, perhaps the curl request times out and the request fails? Altho it’s returning a 200 response to that web hook!

Does your curl request happen inline within that webhook HTTP request, or do you use a background worker to send them?

Hi Fideloper-fly

Thanks for replying to my question.

I did consider that the curl request might have timed out but since I did get 200 I didn’t spend additional time on that.

I’m not doing the curl call inline. I’m relying on a (composer) NTLM library to handle the request and response.

In the meantime, I have moved the caller outside the webhook callback and are now calling the web service when the app is called by refreshing the backend. I’ll move that into a cron call when I’m satisfied with everything.

So everything is working as it should as long as I’m not calling NTLM library in the webhook callback.

But I guess you could be on to something. Not being able to log anything within the callback is one thing. And I did try setting up a Monolog with the same result. Another thing is that I don’t know if it’s even possible to call the NTLM library async. I haven’t tried that in any other environment. I didn’t return any error or anything else.

You would properly don’t know NTLM but would it make sense to assume that that could be the issue?

Thx again.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.