2

I'm using OctoberCMS based on Laravel.

I have records in a database table vendor_log_.

Each day I need Laravel to save a list of the newly created records to a dated .log file.

In my Custom Component's Plugin.php file I created a registerSchedule function. I have it get() the records in the table by current date, then use file_put_contents to append them to a .log file.

However, no log file is being saved to my logs server path. I cannot tell if the schedule is not firing or what it could be, there are no errors.

public function registerSchedule($schedule)
{
    # Generate Daily Log File
    $schedule->call(function () {

        # Get Today's Date
        $date = date("Y-m-d");

        # Get Records by Today's Date
        # Match Record created_at date, exclude time
        $records = \Db::table('vendor_log_')
                    ->whereDay('created_at', date('d'))
                    ->whereMonth('created_at', date('m'))
                    ->whereYear('created_at', date('Y'))
                    ->get();

        # Write records to log file
        foreach ($records as $line) {
          file_put_contents("/var/www/mysite/logs/$date.log", $line . PHP_EOL, FILE_APPEND);
        }

    })->everyMinute();
}

Output of $line:

stdClass Object ( [user_id] => 1 [id] => 28 [username] => [name] => test [created_at] => 2017-03-22 02:39:13 )

Note: I have used ->everyMinute() in place of ->daily() to generate the logs quicker for testing.

Docs:
https://octobercms.com/docs/plugin/scheduling#defining-schedules
https://laravel.com/docs/5.4/scheduling#schedule-frequency-options

9
  • Can you dump a $line for us? Could be that an object / array to string conversion does not work properly. If you want to check wether it creates errors or not, can you try this script in a controller or anything? Commented Mar 22, 2017 at 10:43
  • 1
    Are you sure you set up the scheduler correctly: octobercms.com/docs/setup/installation#crontab-setup , i.e. put the correct line in your crontab. Is the path correct? If both is the case, verify with a simple traceLog('scheduler called') in your regsiterSchedule method that it is actually beeing called. Commented Mar 22, 2017 at 10:44
  • @DouwedeHaan I think I found a conflict, my site is in /public folder and Laravel does not have permission to write outside of it to /log. Commented Mar 22, 2017 at 10:48
  • @MattMcManis Is it an possibility to create a folder inside the public folder where you store your logs? You could protect it with an .htaccess file. Commented Mar 22, 2017 at 10:51
  • 1
    @MattMcManis You can't print an object to a string (not one of the stdClass type). So you have to create a way to convert the object to a string and append that to the log. Commented Mar 22, 2017 at 11:10

1 Answer 1

2

A summary of the problem and the comments:

The problem consisted of two parts;

  • The location where the log is saved isn't writable by the user
  • The object returned by the DB class can't be written as a string

The first problem was solved by writing the log files to the public folder of the hosting that is used.

To write the DB object to a string could be done by the following code

foreach($records as $record) {
    $array = (array) $record;

    $string = '';

    foreach($record as $key => $value) {
        $string .= $key .' '. $value . ',';
    }

    // strip the trailing comma of the end of the string
    $line = rtrim($string, ',');

    file_put_contents("/link/to/public/$date.log", $line . PHP_EOL, FILE_APPEND);
}
Sign up to request clarification or add additional context in comments.

7 Comments

This is working well, the scheduler is appending the array to the log file. But http_build_query turns the array into "id=28&username=&created_at=2017-03-22+02%3A39%3A13". Is there a way to get it to use the actual values from the array separated by spaces or commas? Such as "id 28, username matt, created_at 2017-03-22".
@MattMcManis Yes, I've updated the code. Check the code block!
@MattMcManis Did you also change the first line? I changed the name of the variables in the foreach loop
I had copied it wrong. It is all working perfect now. Do you know how it would be possible to use the /logs director outside of /public? Or does it have to do with www-data permissions? If not I'll have to use a dir in public and protect it.
You could leverage Laravel itself to do the logging Read more about logging here. If you set the logging in the config/app.php to daily, and instead of the file_put_contents() use Log::info() you can put everything in daily logs where Laravel stores them. If you can't get to the logs with OctoberCMS, you should store them in the public folder and deny access to the folder with .htaccess files
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.