openfaas / templates

OpenFaaS Classic templates
https://www.openfaas.com
MIT License
276 stars 228 forks source link

Support request for PHP logging #303

Closed kylerossypretorius closed 1 year ago

kylerossypretorius commented 1 year ago

Expected Behaviour

Getting the display output from the display methods in the response from the container when the script is run. Such examples such as var_dump/echo/print all fail the script.

Current Behaviour

As console.log works in node perfectly fine, to be able to make use of var_dump/echo/print for PHP7/8 in the same manner.

List All Possible Solutions and Workarounds

No workaround has been found yet, any suggestions welcome.

Steps to Reproduce (for bugs)

Template we make use of for php7/8 used below

{
    /**
     * @param string $data
     */
    public function handle($data): string
    {
        $data = json_decode($data);
        try {
            return json_encode(["result" => $this->runScript($data)]);
        } catch (\Exception $e) {
            $result = [
                "result" => REPLACE_DEFAULT_FAIL_VALUE,
                "error" => $e->getMessage()
            ];

            return json_encode($result);
        }
    }

    public function runScript($data)
    {
        REPLACE_TEXT
    }
}

REPLACE_TEXT would be the code inserted by the user, which would include, i.e $data = 1 + 5; var_dump($data); return $data;

Context

Users who make use of creating their own scripts need a means to see certain output to debug their code and check additional responses without it breaking the PHP script.

alexellis commented 1 year ago

Hi thanks for the issue. Could you format the code in a code block please? That usually means surrounding it all in three backticks the start and finish of each section.

alexellis commented 1 year ago

@welteki please can you set up a quick function with the above handler and try out the PHP built-in that @kylerossypretorius mentioned?

It's not on this thread, but Kyle sent it via email asking for:

var_dump
echo
print

I have a suspicion that changing the env-vars here would help.

As a rule, does var_dump print to stdout or stderr @kylerossypretorius ?

Alex

welteki commented 1 year ago

Hi @kylerossypretorius

The PHP 7/8 templates both use the classic-watchdog. By default the watchdog combines stdout and stderr in the function response.

Since var_dump,echo and print all write to stdout their output will be included in the function response.

This is a demo function I created based on your template:

<?php

namespace App;

/**
 * Class Handler
 * @package App
 */
class Handler
{
    /**
     * @param string $data
     * @return string
     */
    public function handle(string $data): string
    {
        $data = json_decode($data);
        try {
            return json_encode(["result" => $this->runScript($data)]);
        } catch (\Exception $e) {
            $result = [
                "result" => REPLACE_DEFAULT_FAIL_VALUE,
                "error" => $e->getMessage()
            ];

            return json_encode($result);
        }
    }

    public function runScript($data)
    {
        fwrite(STDERR, "hello, world!\n");

        var_dump($data);

        return "ok";
    }
}

Invoking the function returns this response:

$ curl -i "http://127.0.0.1:8080/function/php-log" \
    -H "Content-Type: application/json" \
    -d '{"foo":"bar"}'

HTTP/1.1 200 OK
Content-Length: 86
Content-Type: application/json
Date: Thu, 30 Mar 2023 13:55:35 GMT
X-Call-Id: 26b14bf7-d044-44b2-b96c-fd0e23fedd45
X-Duration-Seconds: 0.008887
X-Start-Time: 1680184535636450378

hello, world!
object(stdClass)#2 (1) {
  ["foo"]=>
  string(3) "bar"
}
{"result":"ok"}%    

The watchdog has an env variable combine_output. When set to false stderr is written to the container logs and only stdout is included in the response.

If you want to log things in your function I would suggest setting combine_output to false and writing anything you want to log to stderr.

You could create some additional functions for this, like:

function print_log($text) {
    fwrite(STDERR, $text . PHP_EOL);
}

When setting combine_output to false for the demo function the hello, world! message is no longer included in the response but can be seen in the logs of the function:

$ faas-cli logs php-log

2023-03-30T13:23:19Z 2023/03/30 13:23:19 Version: 0.2.1 SHA: cd8dc9f4e98049150d8079a74a18cd5a2e311aeb
2023-03-30T13:23:19Z 2023/03/30 13:23:19 Timeouts: read: 5s write: 5s hard: 0s health: 5s.
2023-03-30T13:23:19Z 2023/03/30 13:23:19 Listening on port: 8080
2023-03-30T13:23:19Z 2023/03/30 13:23:19 Writing lock-file to: /tmp/.lock
2023-03-30T13:23:19Z 2023/03/30 13:23:19 Metrics listening on port: 8081
2023-03-30T13:23:24Z 2023/03/30 13:23:24 Forking fprocess.
2023-03-30T13:23:24Z 2023/03/30 13:23:24 stderr: hello, world!

combine_output can be set either as an environment variable in the function yaml or you could consider setting it in the Dockerfile of your custom template.

Does this answer the question?

How are your customers invoking the functions and how is the response shown to them?

1) Do you just give back the HTTP response to customers? 2) Do you let the customer see the logs from the function?

Why do you think you are not seeing any response right now or why do you think invocations are failing?

Han

alexellis commented 1 year ago

@kylerossypretorius thoughts?

alexellis commented 1 year ago

We didn't hear back from you on this, so we'll get this closed.

Feel free to reach out again if you need further support from our team.