Creating a Laravel Logger - Part 6: Creating our web application
For this part of the series, you will need PHP 7.13+, Laravel 5.7+ and Composer installed on your machine.
In this sixth and final part of our the series, we will build a simple web application to receive realtime updates when logs are pushed from the main Laravel app created in the first part.
In the previous part of this series, we created the iOS application that would be responsible for log monitoring on Apple devices. It also had the ability to receive push notifications from the application when the log level was an error.
We will build a web application using Vue.js and Laravel. Here is a demo of what you will build:
Requirements
To follow along with this series you need the following things:
- Completed previous parts of the series.
- Laravel installed on your local machine. Installation guide.
- Knowledge of PHP and the Laravel framework.
- Composer installed on your local machine. Installation guide.
- The latest version of Android Studio installed on your machine (If you are building for Android).
- Knowledge of Kotlin and the Android Studio IDE.
- The latest version of Xcode installed on your machine (If you are building for iOS).
- Knowledge of the Swift programming language and the Xcode IDE.
- A Pusher application. Create one here.
- A Pusher Beams application. Create one here.
Creating the project
We will start by creating a new Laravel app. Run this command in any directory of your choice:
$ laravel new web_logging_client
The command above will create a new Laravel project.
Building our user interface
After creating and installing our Laravel application and its required dependencies, open the resources/views
and replace the codes in the welcome.blade.php
file with this:
<!-- File: ./resources/views/index.blade.php -->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Push Logger</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="style sheet" type="text/css">
<!-- Styles -->
<link rel="stylesheet" href="{{ asset('css/app.css')}}">
<style>
html,
body {
overflow-x: hidden; /* Prevent scroll on narrow devices */
}
.position-ref {
position: relative;
}
.top-right {
position: absolute;
right: 10px;
top: 18px;
}
.content {
text-align: center;
}
.title {
font-size: 84px;
}
.m-b-md {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="content">
<div class="title m-b-md">
Push Logger
</div>
<div id="logs" class="row justify-content-md-center">
<div class="col-lg-8">
<div class="alert alert-success" role="alert">
This is a primary alert—check it out!
</div>
<div class="alert alert-warning" role="alert">
This is a secondary alert—check it out!
</div>
<div class="alert alert-info" role="alert">
This is a success alert—check it out!
</div>
</div>
</div>
</div>
<script src="js/app.js"></script>
</body>
</html>
If you run your app using:
$ php artisan serve
You should see something like this:
This shows logs with dummy data inserted already. This gives us an idea of what our app will look like when logs are displayed on the page.
We will now use to add Vue.Js to the project. To do that, we need to create a Vue component. Add this script just before the closing body
tag in the welcome.blade.php
file:
<script>
var logs = [];
Vue.component('pusher-logger', {
data() {
return { logs }
},
methods: {
// Methods go here
},
template: ``
});
new Vue({
el: "#logs"
})
</script>
We put the script tags at the end of the body so that they are executed in order after the DOM is loaded. In this snippet, we have the logs
array declared to hold our log messages.
Now, we have a pusher-logger
Vue component created. This component can be used as an HTML tag like so:
<pusher-logger> </pusher-logger>
The pusher-logger
component has the data
attribute that hosts the data we want Vue to render. In our own case, we return just the logs.
The methods
object is another attribute of the Vue component. We use it to define the behaviors of a component. The template
property holds the HTML markup for our component, we will update this part soon enough.
Finally, we initialized a Vue root component on #logs
. Notice that in the welcome.blade.php
file, you will notice that there is a div
with a class name - logs
. This is the part that will show our logs to the user.
Next, update the template
object of the Vue component like so:
template: `
<div class="col-lg-8">
<div v-for="log in logs" class="alert" v-bind:class= "checkLevel(log.loglevel)"
role="alert">
@{{ log.message }}
</div>
<div v-show="logs.length == 0">
No Logs Dispatched
</div>
</div>
`
The template property now returns a rendered list of the logs and if the logs array is empty at logs.length == 0
we show No Logs Dispatched.
The {{ }}
braces are used both by Vue and Laravel Blade to render data. So whenever using Vue inside a blade file append an @ character to braces {{ }}
.
Next, add this method to the methods
object of the Vue component :
// [...]
methods: {
checkLevel(loglevel) {
switch(loglevel) {
case 'info':
return 'alert-info'
case 'warning':
return 'alert-warning'
case 'error':
return 'alert-danger'
default:
return 'alert-default'
}
}
}
// [...]
In this function, we check the log level to return different alert types. This will change the behavior of the component based on the log level.
Now, still inside the welcome.blade.php
view file, update the div
section with the ID logs
with this snippet below:
<div id="logs" class="row justify-content-md-center">
<pusher-logger> </pusher-logger>
</div>
Here, we replaced the former logs snippet with the pusher-logger
HTML
tag which is a representation of the pusher-logger
Vue component we created earlier.
Adding realtime functionality
Now let’s enable realtime log updates using Pusher Channels. Before the closing body
tag, just after the inclusion of the app.js
script, add this script:
<script src="https://js.pusher.com/4.3/pusher.min.js"></script>
<script>
let pusher = new Pusher('PUSHER_APP_KEY', {
cluster: 'PUSHER_APP_CLUSTER',
forceTLS: true
});
// subscribe to the channel the log is broadcasted on
let channel = pusher.subscribe('log-channel');
// Subscribe to pushlogger event
channel.bind('log-event', function (log) {
logs.push(log);
});
</script>
Replace
PUSHER_APP_KEY
andPUSHER_APP_CLUSTER
with their actual values.
In the code above, we are using the Pusher’s library to listen for log updates on the log-channel pusher channel and the log-event
event. Whenever any of the events are triggered, we get an update of the log message and level in realtime.
You can run your app by running this command:
$ php artisan serve
We also need to start a development server on the previous application so we can dispatch logs. Be sure to run it on another port:
$ php artisan serve --port=9000
Here is how our app should look like:
Conclusion
We have successfully built our final client app and come to the end of our six-part tutorial series. We have explored various technologies such as Laravel, Vue.js, Swift and Kotlin while using them to showcase Pusher’s realtime functions.
The source code to the code is available on GitHub.
29 March 2019
by Neo Ighodaro