How to handle logs and reports in your app using Laravel 5 – Part 1
Logging is a very important part of every application.
Introduction
When building an app, it’s always good to keep track of virtually every activity on the application. It gives you an overview of what your users are doing and what mistakes they make more often. From a security perspective, web application logs can be very useful in:
1. Detecting Attacks
2. Detect application misuse.
3. Detect errors
Laravel takes care of this so easily by taking advantage of the popular PHP Monolog library.
We’ll create a simple web application called ShoutPad and I’ll demonstrate how to handle logging and report in this application. These are the features of the application:
1. Users will be able to create an account.
2. Users will be able to log in after creating an account.
3. Users will be able to give a shoutout.
4. Users will be able to delete their accounts.
Code Time
1. Install a fresh copy of Laravel
2. Fire up your vagrant and setup a database
3. Create a migration file like so:
1 |
php artisan make:migration create_shout_table |
shout_table migration file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?php use IlluminateDatabaseSchemaBlueprint; use IlluminateDatabaseMigrationsMigration; class CreateShoutTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('shouts', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned(); $table->longText('text'); $table->timestamps(); $table->foreign('user_id') ->references('id') ->on('users') ->onDelete('cascade') ->onUpdate('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('shouts'); } } |
Now, run the migrations
4. Set up routes, authentication and frontend
Add this to the routes.php like so:
1 |
Route::get('/', 'WelcomeController@index'); |
Create a Welcome Controller like so:
WelcomeController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php namespace AppHttpControllers; use IlluminateHttpRequest; use AppHttpRequests; use AppHttpControllersController; class WelcomeController extends Controller { /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { return view('welcome'); } } |
Go to resources/views/welcome.blade.php and replace it with this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
@extends('layouts.app') @section('content') <p>It is the celebration of Christmas. Give a Shoutout to your loved ones, Santa would definitely be happy with you on this!</p> <div class="text-center big"> <p> <a href="/"><img src="shoutpad.jpg" alt="ShoutPad" style="max-width: 25rem"></a><br> </p> </div> <div class="text-center"> @if(Auth::check()) <a href="/shouts" class="btn btn-default btn-lg github-sign-up-button"> <i class="fa fa-step-forward"></i> Make a Shoutout </a> @else <a href="/auth/register" class="btn btn-default btn-lg github-sign-up-button"> <i class="fa fa-register"></i> Sign Up Right Here </a> <div> <a href="/auth/login">Have an account already?, Click here to Sign in</a> </div> @endif </div> @stop |
Create a layouts directory and app.blade.php in it
app.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<!DOCTYPE html> <html> <head> <title>ShoutPad</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/css/app.css"> <link href="//fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> </head> <body> <div class="container"> <div class="row"> @if ( Auth::check()) <a href="auth/logout" class="btn btn-default pull-right meta-button">Log out <i class="fa fa-sign-out"></i></a> @endif <h1 class="text-center page-title page-title"><a href="/">ShoutPad</a></h1> </div> <div class="row col-md-8 col-md-push-2"> @yield('content') </div>` <div class="row col-md-8 col-md-push-2 text-center footer"> ShoutPad source is on GitHub: <a href="https://github.com/goodheads/shout-pad">goodheads/shout-pad</a>.<br> By <a href="http://twitter.com/unicodeveloper/">Prosper Otemuyiwa</a>, for tutorial purpose <a href="https://goodheads.io/mattstauffer/leveraging-laravel-launching-side-projects-quickly-with-laravel">talk at Laracon 2015</a>.<br> </div> </div> </body> </html> |
Open the routes.php file and add this:
1 2 3 |
// Registration routes Route::get('auth/register', 'AuthAuthController@getRegister'); Route::post('auth/register', 'AuthAuthController@postRegister'); |
Create a partials folder in the views directory, add signup-form.blade.php, signin-form.blade.php, shoutout-form.blade.php, shoutouts.blade.php and errors.blade.php in it.
partials/signup-form.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@include ('partials.errors') <form method="POST" action="/auth/register"> {{ csrf_field() }} <div class="form-group"> <input type="email" name="email" class="form-control" placeholder="Email Address" autofocus="autofocus" /> </div> <div class="form-group"> <input type="password" name="password" class="form-control" placeholder="Password" /> </div> <div class="form-group"> <input type="text" name="name" placeholder="username" class="form-control" /> </div> <div class="text-right"> <input type="submit" name="submit" class="btn btn-primary" value="Sign up" /> </div> </form> |
partials/error.blade.php
1 2 3 4 5 6 7 |
@if (! $errors->isEmpty()) <ul class="errors"> @foreach ($errors->all() as $message) <li>{{ $message }}</li> @endforeach </ul> @endif |
partials/sign-in.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@include ('partials.errors') <form method="POST" action="/auth/login"> {{ csrf_field() }} <div class="form-group"> <input type="email" name="email" class="form-control" placeholder="Email Address" autofocus="autofocus" /> </div> <div class="form-group"> <input type="password" name="password" class="form-control" placeholder="Password" /> </div> <div class="text-right"> <input type="submit" name="submit" class="btn btn-primary" value="Sign in" /> </div> </form> |
partials/shoutout-form.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 |
@include ('partials.errors') <form method="POST" action="/shout"> {{ csrf_field() }} <div class="form-group"> <textarea name="shoutout" class="form-control" cols="5" rows="5"></textarea> </div> <div class="text-right"> <input type="submit" name="submit" class="btn btn-primary" value="Shout" /> </div> </form> |
partials/shoutouts.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@if(count($shouts) > 0) <div class="row"> @foreach ($shouts as $shout) <div> <span> {{ $shout->text }} </span> by <span style="font-style: italic; color: #09f;"> @if(auth()->user()->id === $shout->user->id) {{ 'you' }} @else {{ $shout->user->name }} @endif </span> </div> <hr/> @endforeach </div> @endif |
Create an auth folder in the views directory, add login.blade.php and register.blade.php in it.
auth/register.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-1"> <div class="panel panel-default panel-on-grey signup-box"> <div class="panel-heading"> <h2 class="panel-title">Sign up</h2> </div> <div class="panel-body"> @include ('partials.signup-form') </div> </div> </div> </div> @stop |
Add this property to AuthController.php. This is where a user is directed to when he/she registers and logs in.
1 |
protected $redirectTo = '/shouts'; |
5. We are going to need to store and retrieve shoutouts, let’s create a ShoutOutController like so:
1 |
php artisan make:controller ShoutoutController |
Now, that the controller has been created, let’s stub out some routes.
1 2 3 |
// Shoutout routes Route::get('shouts', 'ShoutoutController@index'); Route::post('shout', 'ShoutoutController@store'); |
Before we go further, Let’s creat the Shout Model like so:
1 |
php artisan make:model Shout |
It creates a Shout.php class in the app
directory.
Shout.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php namespace App; use AppUser; use IlluminateDatabaseEloquentModel; class Shout extends Model { /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['user_id', 'text']; public function user() { return $this->belongsTo(User::class); } } |
User.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?php namespace App; use AppShout; use IlluminateAuthAuthenticatable; use IlluminateDatabaseEloquentModel; use IlluminateAuthPasswordsCanResetPassword; use IlluminateFoundationAuthAccessAuthorizable; use IlluminateContractsAuthAuthenticatable as AuthenticatableContract; use IlluminateContractsAuthAccessAuthorizable as AuthorizableContract; use IlluminateContractsAuthCanResetPassword as CanResetPasswordContract; class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract { use Authenticatable, Authorizable, CanResetPassword; /** * The database table used by the model. * * @var string */ protected $table = 'users'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['name', 'email', 'password']; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = ['password', 'remember_token']; public function shouts() { return $this->hasMany(Shout::class); } } |
Now that we have established the relationships, let’s move ahead.
Create a shoutouts directory and index.blade.php in it.
index.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@extends('layouts.app') @section('content') <div class="container"> @include ('partials.shoutouts') <div class="row"> <div class="col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-1"> <div class="panel panel-default panel-on-grey signup-box"> <div class="panel-heading"> <h2 class="panel-title">Give a Shoutout</h2> </div> <div class="panel-body"> @include ('partials.shoutout-form') </div> </div> </div> </div> @stop |
Create a shoutout-form.blade.php in the partials directory
shoutout-form.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 |
@include ('partials.errors') <form method="POST" action="/shout"> {{ csrf_field() }} <div class="form-group"> <textarea name="shoutout" cols="5" rows="5" class="form-control"></textarea> </div> <div class="text-right"> <input type="submit" name="submit" class="btn btn-primary" value="Shout" /> </div> </form> |
Head over to the ShoutoutController.php. Make sure you have this:
ShoutoutController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
...... ...... public function __construct() { $this->middleware('auth'); } /** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { return view('shoutouts.index'); } /** * Store a newly created resource in storage. * * @param IlluminateHttpRequest $request * @return IlluminateHttpResponse */ public function store(Request $request) { $this->validate($request, [ 'shoutout' => 'required' ]); $request->user()->shouts()->create([ 'text' => $request->shoutout, ]); return redirect('shouts'); } |
Now, we can add shouts. Let’s retrieve all shouts for all users and display it.
In your ShoutoutController.php, the index method will change to this:
1 2 3 4 5 6 7 8 9 10 11 |
/** * Display a listing of the resource. * * @return IlluminateHttpResponse */ public function index() { $shoutouts = Shout::all(); return view('shoutouts.index', ['shouts' => $shoutouts]); } |
Let’s quickly Add the Logout route in routes.php like so:
1 2 |
.... Route::get('auth/logout', 'AuthAuthController@getLogout'); |
Let’s add the login routes too like so:
1 2 3 |
// Login Routes Route::get('auth/login', 'AuthAuthController@getLogin'); Route::post('auth/login', 'AuthAuthController@postLogin'); |
So, test the application and make sure it works properly.
Conclusion
This is the sample application for our logging tutorial.
The source code is on github. Check it out https://github.com/goodheads/shout-pad .
We just prepped for the logging here by going through the sample application together. In the next post, we’ll handle Logging
Please, if you have any questions or observations, let me know in the comments section.

- How to build your own Youtube – Part 10 - August 1, 2016
- How to build your own Youtube – Part 9 - July 25, 2016
- How to build your own Youtube – Part 8 - July 23, 2016
- How to build your own Youtube – Part 6 - July 6, 2016
- Introducing Laravel Password v1.0 - July 3, 2016
- How to build your own Youtube – Part 5 - June 28, 2016
- How to build your own Youtube – Part 4 - June 23, 2016
- How to build your own Youtube – Part 3 - June 15, 2016
- How to build your own Youtube – Part 2 - June 8, 2016
- How to build your own Youtube – Part 1 - June 1, 2016