Cron job appendOutputTo not append anything in Laravel - laravel

I have a problem in my project. I cannot append output in my cron job.
Here is my code
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel {
protected $commands = [
'\App\Console\Commands\CronEmail'
];
protected function schedule(Schedule $schedule) {
$schedule->command('app:CronEmail')->everyMinute()->appendOutputTo(public_path("cron.log"))->emailOutputTo('my email address');
}
protected function commands() {
$this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
}
But this is not append output to my file, Also it does not send output to my email address

Related

Laravel scheduler not working when called from controller

I have created a console command that (for now) just outputs a log statement.
That command is scheduled every minute.
I have a controller endpoint (located at /scheduler/run) that performs an Artisan::call(); to the artisan schedule:run command.
Locally it works perfectly (laravel valet & nginx), on production (apache) however, nothing happens when hitting that endpoint...
I do get the reply from my controller, but the scheduler is never triggered.
My route:
Route::get('/scheduler/run', SchedulerController::class)->name('scheduler');
My controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Artisan;
class SchedulerController extends Controller
{
public function __invoke()
{
Artisan::call('schedule:run');
return response()->noContent();
}
}
My Kernel.php
<?php
namespace App\Console;
use App\Console\Commands\PingCommand;
use App\Console\Commands\RefreshTwikeyKey;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
PingCommand::class,
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command(PingCommand::class)->everyMinute();
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

Cron run schedule not running automatically on the server

I have this cron job code in Laravel-5.8 application:
App/Console/Commands:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Hr\HrDesignation;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Exception;
use Notification;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException;
class UpdateCreateDesignation extends Command
{
protected $signature = 'updatecreatedesignations';
protected $description = 'Update or Create Designation';
public function __construct()
{
parent::__construct();
}
public function handle()
{
$client = new Client();
$res = $client->request('GET','https://api.cloudjkk.net/jkkapp/profile/all-designations', [
'query' => ['key' => 'dddddd']
])->getBody();
$clientdatas = json_decode($res->getContents(), true);
foreach($clientdatas as $clientdata)
{
if ($clientdata['job_title']) {
$designation = HrDesignation::updateOrCreate([
'designation_name' => $clientdata['job_title']
],
[
'description' => $clientdata['job_description'],
'company_id' => 1,
]);
}
}
}
}
For the schedule, I have this code in the kernel which is supposed to run by 1:00a.m. every day
kernel.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
protected $commands = [
'App\Console\Commands\UpdateCreateDesignation',
];
protected function schedule(Schedule $schedule)
{
$schedule->command('updatecreatedesignations')
->dailyAt('01:00');
}
protected function commands()
{
require base_path('routes/console.php');
}
}
I observe that the cron job is not running on the server as scheduled by 01:00.
There is no error.
How do I resolve this?
Thanks
Laravel needs to run the php artisan schedule:run every minute. If the current time is 01:00, that task is executed.
So you need to:
Add a cronjob every minute * * * * *.
Go to the directory cd /path-to-your-project
Run the artisan command that will match the time php artisan schedule:run
You can test this if you add a job with ->everyMinute();
$schedule->command('increment-db-int')
->everyMinute();
You will need to make sure that you have enabled the scheduler in crontab
https://laravel.com/docs/7.x/scheduling#introduction
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Processing Laravel job with many HTTP requests inside, it fails trying by timeout

I have an API REST built using Laravel 5.8 framework.
I have to get the data for my app from a public REST API. For this, i have to do a lot of requests. I made a seeder what do this, and it takes 2 minutes for the entire migration data process approximately (take from the public Api and insert in my application database).
I cant run the seeder by a cronjob because it does not work (it looks like need an user to execute the command to work). So, i created a job class what i call from my kernel file, the queue configuration was seted as database (QUEUE_CONNECTION=database), like a scheduled task (to execute with Supervisor: https://laravel.com/docs/5.8/queues#supervisor-configuration).
Despite this, the job fails, because it takes a long time to execute, so my data is not updated.
What i can do process my jobs by batch successfully?
This is my kernel.php
<?php
namespace App\Console;
use App\Jobs\Seed\ApiPlayerStatisticJob;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->job(new ApiPlayerStatisticJob)->everyFiveMinutes();
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
My ApiPlayerStatisticJob.php
<?php
namespace App\Jobs\Seed;
use App\ApiExternal;
use App\ApiPlayer;
use App\ApiTeam;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class ApiPlayerStatisticJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$api_teams = ApiTeam::get();
foreach ($api_teams as $api_team) {
// echo 'TEAM: '.$api_team->id;
$api_external_players = ApiExternal::getTeamPlayerStatistics($api_team->id);
foreach ($api_external_players as $api_external_player) {
// echo PHP_EOL.'PLAYER: '.$api_external_player['id'];
$api_player = ApiPlayer::find($api_external_player['id']);
if ($api_player != null) {
$api_player->update($api_external_player);
// echo PHP_EOL.'> PLAYER UPDATED ';
} else {
// echo PHP_EOL.'X PLAYER DIDNT UPDATED ';
}
}
// echo PHP_EOL;
// echo PHP_EOL;
}
}
}
And my Seeder what i used for construct my job (by replication, excluding the print expressions):
<?php
use Illuminate\Database\Seeder;
use App\ApiExternal;
use App\ApiPlayer;
use App\ApiTeam;
class ApiPlayerStatisticsSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$api_teams = ApiTeam::get();
foreach ($api_teams as $api_team) {
echo 'TEAM: '.$api_team->id;
$api_external_players = ApiExternal::getTeamPlayerStatistics($api_team->id);
foreach ($api_external_players as $api_external_player) {
echo PHP_EOL.'PLAYER: '.$api_external_player['id'];
$api_player = ApiPlayer::find($api_external_player['id']);
if ($api_player != null) {
$api_player->update($api_external_player);
echo PHP_EOL.'> PLAYER UPDATED ';
} else {
echo PHP_EOL.'X PLAYER DIDNT UPDATED ';
}
}
echo PHP_EOL;
echo PHP_EOL;
}
}
}
Finally, the static function ApiExternal::getTeamPlayerStatistics(int id) do all requests necessaries to get th data (like 30 requests), so what i can do to process this job (or the seeder directly) in background without it fails?
Did you configure the config/queue.php file correctly?
Quote from the documentation in the Job expirations paragraph:
In your config/queue.php configuration file, each queue connection defines a retry_after option. This option specifies how many seconds the queue connection should wait before retrying a job that is being processed.

How to properly add external php files in Laravel 5

I have a small websockets chat written, the php part is just 2 files, server.php and Chat.php, they are both inside a bin folder and depend on ratchet and some other libraries which I downloaded to the laravel installation via composer.
server.php
require __DIR__.'/../vendor/autoload.php';
require 'Chat.php';
use Ratchet\Server\IoServer;
use Ratchet\http\HttpServer;
use Ratchet\WebSocket\WsServer;
$server = IoServer::factory(new HttpServer(new WsServer(new Chat)), 8080);
$server->run();
Chat.php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $conn, $msg)
{
foreach ($this->clients as $client)
{
if ($client !== $conn ) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e)
{
echo 'the following error occured: ' . $e->getMessage();
$conn->close();
}
}
Now, I have that bin folder inside the laravel root, and so I am able to start the server since the server.php is looking for dependencies in vendor one level up, but what I wanna do is use all the laravel goodies within these files, especially within Chat.php.
So now for example if I write use DB in Chat.php it gives an error (which I understand, it has no way of knowing laravel), so my question is how do I include this bin folder and its files so that I can use all the laravel goodies within them?
You do not need to manually load vendor/autoload.php because laravel does that for you.
First you have to create folder inside your YourLaravelRoot/app dir(Let's name that as Services). Then move chat.php into that, rename it to ChatService.php(Change class name also to ChatService) or any appropriate name(reccomanded to ends with xxxxService so it's easier to identify) and namespace it as namespace App\Services;(Assumming that your app name is App).Namespacing correctly is important otherwise you have to manually loads it throught composer.json .Then create a artisan command and move content of server.php into handle method inside command(Let's name it ServerCommand.php). Add use App\Services\ChatService as Chat;. Register the command in Kernal.php on app/console That's it. Now you should be able to access any laravel facade inside ChatService
Summary:
YourLaravelProject
-app
--Console
Kernal.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
Commands\ServerCommand::class,
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
}
---Commands
----ServerCommand.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use App\Services\ChatService as Chat;
class ServerCommand extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'server:run';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$server = IoServer::factory(new HttpServer(new WsServer(new Chat)), 8080);
$server->run();
}
}
--Services
---ChatService.php
<?php
namespace App\Services;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
/**
*
*/
class ChatService implements MessageComponentInterface {
{
protected $clients;
function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $conn, $msg)
{
foreach ($this->clients as $client)
{
if ($client !== $conn ) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e)
{
echo 'the following error occured: ' . $e->getMessage();
$conn->close();
}
}
Execute command php artisan server:run

Laravel cron not working automatically

I'm working on a project in Laravel through scotch box. I am trying to automate some things through cronjobs. The problem is that my cron does not run automatticly, but when I php artisan schedule:run it runs my task perfectly.
app/commands/sendmail.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Mail;
class sendmail extends Command {
protected $name = 'sendMail';
protected $description = 'A mail has been send ';
public function fire()
{
Mail::send([],[], function($message) {
//sendmail function that works...
});
}
}
app/console/Kernel.php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\DB;
use App\Battle;
use Carbon\Carbon;
use App\Console\Commands\Inspire;
use App\Commands\mails;
class Kernel extends ConsoleKernel
{
protected $commands = [
\App\Console\Commands\Inspire::class,
\App\Console\Commands\sendmail::class,
];
protected function schedule(Schedule $schedule)
{
$schedule->command('inspire')
->everyMinute();
$schedule->command('sendMail')
->everyMinute();
}
}
crontab -e
# m h dom mon dow command
* * * * * php var/www/artisan schedule:run
The problem ended up being the use of an relative path versus absolute path.
Using the relative path defined as var/www/artisan will set the path according to present working directory. That would mean App/Console/var/www/artisan where no artisan was located.
Instead using an absolute path such as /var/www/artisan will set the directory directly to /var/www/artisan, which would be the correct location of artisan.
* * * * * php -d register_argc_argv=On /var/www/artisan schedule:run

Resources