Get remote laravel log file

By now you are deploying your web applications via some sort of magic like Codeship and have probably decided to turn FTP off on your servers. Either that or you are using Forge and the only way you can get at your production server is via SSH.

If you want to run migrations on your production server then you can SSH in or maybe have an Envoy command to do this. However, what happens if you need to review your production log files from your Laravel app but you cannot just FTP in and download them.

At first I thought about doing it via Envoy but I could not get my head around how to use the ‘scp’ command. I ended up setting an alias to do it from my local machine using

alias get-amazing-com-log=”scp ~/Projects/amazing_com/app/storage/logs/”

Then I thought, how about a quick Laravel Command to do something like

php artisan logs:get

To do this we are going to make use of the SSH Class in Laravel, specifically SFTP Downloads. For us to be able to use this class we need to set some remote configurations.

To get started we need to go to ‘/app/config/remote.php’ and add the settings for your remote server, in this example we will set them for our production server.

// app/config/remote/php
'connections' => array(
    'production' => array(
        'host' => $_ENV['SSH_HOST'],
        'username' => $_ENV['SSH_USERNAME'],
        'password' => $_ENV['SSH_PASSWORD'],
        'key' => '',
        'keyphrase' => '',
        'root' => '/home/web/',

You will notice that the only thing we actually set in this file is the ‘root’ as everything else is extremely sensitive so we are going to set those configuration items using “dot” files.

<? // .env.local.php return array( 'SSH_HOST' => '',
'SSH_USERNAME' => 'deployment',
'SSH_PASSWORD' => '53curep455w0rd',

Once we have the configuration setup then we are ready to setup our new Artisan Command.

// app/commands/GetLog.php

use IlluminateConsoleCommand;
use SymfonyComponentConsoleInputInputArgument;

class GetLog extends Command

    protected $name = 'logs:get';
    protected $description = 'Connect via SSH to the given remote environment and download log file.';

    public function __construct()

    public function fire()

        $this->info('Stand by...');

        try {

            $env = $this->argument('env');
            $app_log_path = '/app/storage/logs/laravel.log';
            $remote_log_path = Config::get('remote.connections.' . $env . '.root') . $app_log_path;
            $local_log_path = dirname(__FILE__) . '/../storage/logs/' . $env . '.log';

            SSH::into($env)->get($app_log_path, $local_log_path);

        } catch (InvalidArgumentException $e) {

            $this->error('Check you have settings for app/config/remote.php connections.' . $env);


        $this->info('Environment : ' . $env);
        $this->info('Connected to ' . $_ENV['SSH_HOST']);
        $this->info('Getting file from : ' . $remote_log_path);
        $this->info('File downloaded to : ' . $local_log_path);


    protected function getArguments()
        return array(
                'Environment to get the logs from set in app/config/remote.',

And remember to register this command so you have access to it when running Artisan on the CLI.


// app/start/artisan.php

Artisan::add(new GetLog);

And there you have it. Now you can run a simple Artisan command from your local machine or from within your Homestead VM and it will connect to production, pull down the log file and store it in ‘app/storage.logs/production.log’.

You’re welcome.

Limit packages to development in Laravel applications

Let’s say you like to use Laravel 4 Generators by Jeffery Way like we do at Clicksco. If you are not familiar with this package then you should head over to Laracasts and watch the free video. You will only be using the generators in development so you don’t really want to have this included on production. Let’s have a look at how we can do this.

First of all you need to make sure that you have included ‘way/generators’ in the ‘require-dev’ section of your composer.json file and not the ‘require’ section. You can do this manually or from terminal by running

php composer require --dev "way/generators:2.*"

Worth noting that if you run this then composer will automatically run a ‘composer update’ and this update will run including require-dev packages, this is the default action of a composer update. Your composer.json file will now include the package in the ‘require-dev’ section.

"require-dev": {
"way/generators": "2.*"

After requiring the package, which now sits in your vendor folder, you will need to instruct Laravel to use it. To do this we register a service provider. If you were to follow the installation instructions on GitHub then you will notice that you are asked to open ‘app/config/app.php’, and add a new item to the providers array (shown below).

'providers' => array(

This is where we are going to start doing things a little differently.

Instead of doing the above we are actually going to add the service provider to our development environment app config.

As I am sure you are aware, inside the ‘app/config’ folder you can create folders that match your environments. By default the ‘app/config/app.php file will be loaded by Laravel and this will be true for production. However, for development we want to tell Laravel to load ‘app/config/development/app.php’. To do this we need to alter ‘bootstrap/start.php’ and include something like:

$env = $app->detectEnvironment([
'development' => [
'production' => [

The above example has my local machine hostname for situations where I would be using MAMP and also the hostname of my Vagrant VM for when I am working in our default Vagrant setup we have at Clicksco. I then have the domain of the live application in the production array. There are a number of different ways of managing this but I have found this to work best for my needs.

Another way, and one that is much better

$env = $app->detectEnvironment(function () {
return isset($_SERVER['ENV']) ? $_SERVER['ENV'] : 'development';

We have told Laravel to check in the ‘app/config/development’ folder for settings to be used when in our development environment we now need to add our service provider to this file.

Normally we would just add the config settings for development in a new array inside the ‘app/config/development/app.php’ file but by default this will override the settings loaded from ‘app/config/app.php’. So we are going to make use of the ‘append_config’ helper method in our environment app configuration file, see below.


return array(

'debug' => true,

'providers' => append_config(


Notice that the debug = true is an example of an override and our providers = append_config is an example of us appending to what has already been loaded. Now we have access to Jeffery Ways Generators but only when we are in development, you can test this by running

php artisan

and you will now see something like

generate:controller Generate a controller
generate:migration Generate a new migration
generate:model Generate a model
generate:pivot Generate a pivot table
generate:publish-templates Copy generator templates for user modification
generate:resource Generate a new resource
generate:scaffold Scaffold a new resource (with boilerplate)
generate:seed Generate a database table seeder
generate:view Generate a view

To finish off we will want to make sure that we don’t include the ‘require-dev’ packages on production. This is simply done by running composer update adding the –no-dev option. Just add the ‘–no-dev’ option to your deployment script.

composer update --no-dev

Hope this helps someone.