Bij het ontwikkelen van een moderne toepassing moet logging bovenaan de prioriteitenlijst staan.

Logging biedt een manier om je app zowel in ontwikkeling als in productie te visualiseren, wat transparantie en zichtbaarheid mogelijk maakt. Met goed gestructureerde logging kunnen moderne toepassingen gemakkelijker onderhouden worden, omdat we pro-actief points of failure en bottlenecks in de prestaties van onze app kunnen opsporen.

Het Laravel framework wordt geleverd met een robuust loggingsysteem dat alle hindernissen die komen kijken bij het configureren van een goed gestructureerd loggingsysteem oplost. Dit nieuwe loggingsysteem dat in Laravel 6.5 geïntroduceerd wordt is krachtig, en we zullen het in dit artikel verkennen.

Dit artikel zal de basisprincipes van Laravel logging verkennen en uitleggen waarom je Laravel logging in je volgende project zou moeten gebruiken. We zullen gestructureerd loggen en gecentraliseerd loggen uitgebreid bespreken. Bovendien zullen we leren hoe je Laravel logging kunt implementeren door een Todo toepassing te bouwen.

Je zult meer uit dit artikel halen als je het volgende al onder de knie hebt:

Wat is Laravel logging?

Laravel logging gaat over hoe Laravel logging, oftewel automatische probleemmelding, afhandelt met behulp van een viraal PHP logging systeem dat Monolog heet. Maar vanwege Laravel’s filosofie om populaire bestaande bibliotheken te gebruiken om verschillende frameworkfuncties uit te voeren, gebruikt Laravel Monolog voor al de loggingbehoeften.

Monolog is een zeer flexibele en populaire PHP loggingbibliotheek die we kunnen configureren om je logs naar bestanden, sockets, databases, en andere webdiensten te sturen. Monolog biedt een vertrouwde interface voor het schrijven van logs, van standaard tekstbestanden tot geavanceerde externe logbeheerdiensten. Laravel stelt Monolog typisch in om een standaard logging configuratiebestand te gebruiken.

Voor meer informatie over Monolog en zijn mogelijkheden kun je de officiële documentatie raadplegen, want dat valt buiten het bereik van dit artikel.

Voor we duiken in het configureren en implementeren van Laravel logging met Monolog, verkennen we eerst meer redenen om Laravel logging te gebruiken en de verschillende soorten.

Waarom Laravel logging gebruiken?

Waarom is logging nodig?

Het Twelve-Factor App manifest behandelt logging als een van de belangrijkste aandachtspunten van een moderne toepassing, want logging is de sleutel tot prestaties en monitoring.

Logs helpen bij het gedetailleerd begrijpen van fouten die in de productie optreden en waar ze vandaan komen. Met de juiste logstructuren kan bovendien de specifieke gebruiker getoond worden, de actie die de fout veroorzaakte, en de mogelijke oplossing voor snellere bug fix en onderhoud.

Gestructureerde logging is een redder in nood in productie-applicaties door te helpen bij het opsporen van defecten en het oplossen van problemen in de productie. Bovendien kun je al je logberichten in real-time volgen en verzamelen met gespecialiseerde logging tools voor live analyse en rapportage.

Om deze redenen moet je van gestructureerde logging een topprioriteit maken in je volgende moderne applicatieproject.

Laten we eens kijken naar het overzicht van de verschillende loggingstijlen die beschikbaar zijn.

Grondbeginselen van Laravel logging

Het leren van de basisprincipes van logging helpt je te begrijpen hoe Laravel met logging omgaat en hoe je je gestructureerde loggingpraktijken kunt verbeteren.

Laten we twee essentiële concepten in logging onderzoeken om beter te begrijpen hoe we onze loggingprocedures kunnen implementeren.

Gestructureerd loggen in Laravel

In softwareontwikkeling is gestructureerd loggen het implementeren van een vooraf bepaald en consistent berichtformat voor toepassingslogs. Met dit formaat kunnen de berichten behandeld worden als gegevens die veel beter gevolgd, gemanipuleerd en gevisualiseerd kunnen worden dan het gewone tekstformat.

Je moet een gestructureerde loggingaanpak implementeren in je moderne applicatieontwikkeling omdat logbestanden essentieel zijn voor ontwikkelaars als er in productie iets verkeerds gebeurt met je applicatie.

Omdat Laravel Monolog gebruikt, kunnen ontwikkelaars snel gestructureerd loggen implementeren door de logger te configureren om specifieke soorten informatie te ontvangen, de logbestanden in verschillende formaten op te slaan, en de logs naar verschillende externe logbeheerdiensten te sturen voor visualisatie.

Laravel gecentraliseerd loggen

Een gecentraliseerd logsysteem is een systeem waarbij logs vanuit meerdere bronnen naar Centralized Log Management (CLM) oplossingen worden gestuurd voor eenvoudige consolidatie en visualisatie. CLM is echter een gespecialiseerde loggeroplossing die logberichten uit verschillende bronnen verzamelt en de gegevens consolideert voor gemakkelijke verwerking en visualisatie.

Behalve het verzamelen van gegevens wordt van CLM ook verwacht dat het de analyse van loggegevens ondersteunt en een duidelijke presentatie van de gegevens na analyse.

Gestructureerd loggen vs. basic loggen

Laten we eens kijken naar het verschil tussen gestructureerd loggen en basic (ongestructureerd) loggen en waarom je gestructureerd loggen in je Laravel project zou moeten gebruiken.

Basic loggen

Bij basic loggen worden de logbestanden in een onbewerkt format opgeslagen met beperkte gegevens om individuele logs op te vragen en te identificeren.

Bij gebruik van Basic logging zullen ontwikkelaars geen externe analysetools gebruiken om logs te lezen, bekijken en analyseren, tenzij ze een eigen tool ontwikkelen of het houden bij een tool die hun logformat ondersteunt.

Er zijn drie belangrijke redenen om het gebruik van basic logging te vermijden:

  1. Gecentraliseerde logbeheersystemen kunnen niet met de gegevens werken zonder extra ondersteuning.
  2. Een aangepaste oplossing is nodig om de gegevens van een basic loggingsoplossing te lezen en te ontleden.
  3. Het kan voor beheerders een uitdaging zijn om bacic logginggegevens te lezen omdat ze ruw en ongestructureerd zijn.

Gestructureerd loggen

Gestructureerd loggen bespaart ontwikkelaars tijd door gebruik te maken van externe open-source loganalysetools die standaard log-structuur ondersteunen om logs te lezen, te bekijken en te analyseren.

Logs zijn nuttig als ze de juiste gegevens bevatten die hieronder vermeld staan, en dat is wat gestructureerd loggen probeert. We kunnen de gegevens in gestructureerde logging gebruiken om dashboards, grafieken, diagrammen en andere nuttige visualisaties te maken om de gezondheid van de toepassing te bepalen.

Dit zijn basisvoorbeelden van de informatie die we in gestructureerde logberichten kunnen opnemen. Bovendien kun je de gegevens helemaal aanpassen aan je eigen behoeften.

Hier zijn enkele voorbeelden van de gegevens die je met gestructureerde logging kunt verzamelen:

  1. De poort die gebruikt werd om de functie uit te voeren
  2. De datum en tijd waarop de gebeurtenis plaatsvond
  3. De gebruikersnaam of ID van de klant
  4. Een beschrijving van de gebeurtenis (logbericht)
  5. Het protocol dat gebruikt werd om de functie uit te voeren
  6. De plaats van de getriggerde gebeurtenis (geef API of draaiende app aan)
  7. De unieke gebeurtenis-ID
  8. Het soort actie dat geactiveerd wordt (logniveau)

Logs moeten voldoende gegevens bevatten om de oplossing of de reden voor de loggebeurtenis gemakkelijk te kunnen visualiseren. Merk ook op dat je niet alle soorten informatie, zoals wachtwoorden of gevoelige gegevens, in logs moet opslaan.

Nu we een glimp opgevangen hebben van wat Laravel loggen inhoudt, gaan we verder met het implementeren van Laravel loggen door een toepassing te bouwen met loggen als belangrijke component.

Hoe Laravel logging implementeren met Todo App

Nu gaan we toepassen wat we tot nu toe geleerd hebben door een nieuw Laravel project te maken en Laravel logging te implementeren.

Als je Laravel nog niet eerder gebruikt hebt, kun je doorlezen wat Laravel is of een blik werpen op onze lijst van uitstekende Laravel handleidingen om aan de slag te gaan.

Laravel opzetten

Eerst gaan we een verse Laravel instantie aanmaken met het onderstaande commando. Je kunt de officiële documentatie raadplegen voor meer.

Open je console en navigeer naar de plaats waar je je PHP projecten opslaat voordat je de onderstaande commando’s uitvoert. Zorg ervoor dat Composer correct geïnstalleerd en geconfigureerd is.

composer create-project laravel/laravel laravel-logging-app
cd laravel-logging-app // Change directory to current Laravel installation
php artisan serve // Start Laravel development server

De database configureren en seeden

Vervolgens richten we onze database in, maken een nieuw Todo model, en seeden 200 nepgegevens om te testen.

Open je databaseprogramma en maak een nieuwe database aan. We doen hetzelfde met de naam laravel_logging_app_db en vullen dan ons .env bestand met de database-informatie:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_logging_app_db
DB_USERNAME=//DB USERNAME HERE
DB_PASSWORD=//DB PASSWORD HERE

Vervolgens voeren we het volgende commando uit om tegelijk de migratie en het Todo model te maken:

php artisan make:model Todo -mc

Open de nieuw gemaakte migratie, die je kan vinden in database/migrations/xxx-create-todos-xxx.php en plak er de volgende codes in:

<?php
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateTodosTable extends Migration
{
  /**
  * Run the migrations.
  *
  * @return void
  */
  public function up()
  {
    Schema::create('todos', function (Blueprint $table) {
      $table->id();
      $table->string('title');
      $table->text('description')->nullable();
      $table->boolean('is_completed')->default(false);
      $table->timestamps();
    });
  }
  /**
  * Reverse the migrations.
  *
  * @return void
  */
  public function down()
  {
    Schema::dropIfExists('todos');
  }
}

Je kunt je todo’s seeden met Faker gegevens door te leren je databases in Laravel te seeden met Faker.

Overzicht van Monolog

Met Laravel Monolog kun je gestructureerde logs streamen en versturen naar verschillende kanalen, zoals e-mails, Slack, bestanden, sockets, inboxen, databases, en verschillende webdiensten. In Laravel kun je het loggen configureren vanuit een enkel configuratiebestand dat staat in config/logging.php.

Het configuratiebestand wordt geleverd met voorgedefinieerde log drivers om uit te kiezen, en de standaard driver is een stack die het single kanaal gebruikt om te loggen naar een laravel.log bestand dat in de map storage/logs staat. We zullen gestructureerd loggen demonstreren door een paar van de Laravel log drivers te gebruiken.

Laravel biedt een handvol methoden om met Logs te interageren, zoals binnenkort algemeen gedemonstreerd wordt in het TodosController.php controller bestand.

Logberichten schrijven in de controller

Open het pas gemaakte TodosController.php controller bestand dat je vindt app/Http/Controllers map en plak er de volgende codes in:


<?php
namespace AppHttpControllers;
use AppModelsTodo;
use IlluminateHttpRequest;
use AppHttpControllersController;
use IlluminateSupportFacadesAuth;
use IlluminateSupportFacadesLog;
class TodosController extends Controller
{
  public function index(Request $request)
  {
    $todos = Todo::all();
    Log::warning('User is accessing all the Todos', ['user' => Auth::user()->id]);
    return view('dashboard')->with(['todos' => $todos]);
  }
  public function byUserId(Request $request)
  {
    $todos = Todo::where('user_id', Auth::user()->id)->get();
    Log::info('User is accessing all his todos', ['user' => Auth::user()->id]);
    return view('dashboard')->with(['todos' => $todos]);
  }
  public function show(Request $request, $id)
  {
    $todo = Todo::find($id);
    Log::info('User is accessing a single todo', ['user' => Auth::user()->id, 'todo' => $todo->id]);
    return view('show')->with(['todo' => $todo]);
  }
  public function update(Request $request, $id)
  {
    # Validations before updating
    $todo = Todo::where('user_id', Auth::user()->id)->where('id', $id)->first();
    Log::warning('Todo found for updating by user', ['user' => Auth::user()->id, 'todo' => $todo]);
    if ($todo) {
      $todo->title = $request->title;
      $todo->desc = $request->desc;
      $todo->status = $request->status == 'on' ? 1 : 0;
      if ($todo->save()) {
        Log::info('Todo updated by user successfully', ['user' => Auth::user()->id, 'todo' => $todo->id]);
        return view('show', ['todo' => $todo]);
      }
      Log::warning('Todo could not be updated caused by invalid todo data', ['user' => Auth::user()->id, 'todo' => $todo->id, 'data' => $request->except('password')]);
      return; // 422
    }
    Log::error('Todo not found by user', ['user' => Auth::user()->id, 'todo' => $id]);
    return; // 401
  }
  public function store(Request $request)
  {
    Log::warning('User is trying to create a single todo', ['user' => Auth::user()->id, 'data' => $request->except('password')]);
    # Validations before updating
    $todo = new Todo;
    $todo->title = $request->title;
    $todo->desc = $request->desc;
    $todo->user_id = Auth::user()->id;
    if ($todo->save()) {
      Log::info('User create a single todo successfully', ['user' => Auth::user()->id, 'todo' => $todo->id]);
      return view('show', ['todo' => $todo]);
    }
    Log::warning('Todo could not be created caused by invalid todo data', ['user' => Auth::user()->id, 'data' => $request->except('password')]);
    return; // 422
  }
  public function delete(Request $request, $id)
  {
    Log::warning('User is trying to delete a single todo', ['user' => Auth::user()->id, 'todo' => $id]);
    $todo = Todo::where('user_id', Auth::user()->id)->where('id', $id)->first();
    if ($todo) {
      Log::info('User deleted a single todo successfully', ['user' => Auth::user()->id, 'todo' => $id]);
      $todo->delete();
      return view('index');
    }
    Log::error('Todo not found by user for deleting', ['user' => Auth::user()->id, 'todo' => $id]);
    return; // 404
  }
}

Binnen elk van de methoden in de TodoController, voegden we de gevel Log toe met een bepaald logniveau om het soort fout te bepalen dat we willen zenden. Hieronder zie je een voorbeeld van het gebruik van de

Log façade in de store methode.

public function store(Request $request)
{
  Log::warning('User is trying to create a single todo', ['user' => Auth::user()->id, 'data' => $request->except('password')]);
  # Validations before updating
  $todo = new Todo;
  $todo->title = $request->title;
  $todo->desc = $request->desc;
  $todo->user_id = Auth::user()->id;
  if ($todo->save()) {
    Log::info('User create a single todo successfully', ['user' => Auth::user()->id, 'todo' => $todo->id]);
    return view('show', ['todo' => $todo]);
  }
  Log::warning('Todo could not be created caused by invalid todo data', ['user' => Auth::user()->id, 'data' => $request->except('password')]);
  return; // 422
}

Logmeldingen opmaken

Stel dat je je niet op je gemak voelt met de standaard LineFormatter die Laravel gebruikt, die prima werk levert met leesbare en behulpzame berichten.

In dat geval kun je gemakkelijk een aangepast formatter object spinnen dat bij je gebruik past en het door de hele toepassing gebruiken.

De officiële Monolog documentatie geeft een complete lijst van beschikbare formatters en je kunt er gemakkelijk een custom mee maken.

In Laravel kun je eenvoudig instellen dat een van de stuurprogramma’s je aangepaste formatter gebruikt door het toe te voegen aan de lijst zoals hieronder binnen het configuratiebestand dat staat in config/logging.php:

'daily' => [
  'driver' => 'daily',
  'path' => storage_path('logs/laravel.log'),
  'level' => env('LOG_LEVEL', 'debug'),
  'days' => 14,
  'formatter' => MonologFormatterHtmlFormatter::class,
  'formatter_with' => [
    'dateFormat' => 'Y-m-d',
  ]
],

Het voorbeeld hierboven voegt een aangepaste MonologFormatterHtmlFormatter toe aan de daily driver die de formatter en formatter_with sleutel gebruikt in de daily kanaal configuratie om het formaat van de datums te veranderen.

Logs naar verschillende kanalen zenden

Met de hulp van Monolog kan Laravel logs naar verschillende kanalen sturen en naar meerdere kanalen tegelijk.

Laten we demonstreren hoe we logs naar ons Slack kanaal kunnen sturen volgens deze eenvoudige stappen. Verander het standaard logkanaal in Slack en voeg Slack Webhook URL toe in je .env bestand .

LOG_CHANNEL=slack
LOG_SLACK_WEBBHOOK_URL= Slack_webhook_url_here

Test vervolgens je configuratie door een bericht in je toepassing te loggen met de Log façade zoals hieronder:

Log::debug("The API instance is on fire caused by:", ['user' => 1])

Je kunt je Slack kanaal openen om te controleren of de fout is afgedrukt in het gewenste kanaal dat je bij het genereren van de Webhook URL hebt opgegeven.

Samenvatting

Loggen is net zo belangrijk als elke ander onderdeel van je applicatie, zo niet nog belangrijker. Daarom wordt het door het Twelve-Factors App manifest voorgesteld als een van de meest kritische aandachtspunten van elke moderne toepassing.

Met effectieve logging kun je fouten en gebreken die in je productieklare applicatie optreden gemakkelijk aflezen, bekijken en visualiseren. Daartoe is het belangrijk dat je vanaf het begin van het project gestructureerde logging in je toepassing implementeert.

In dit artikel hebben we Laravel logging verkend en waarom je het in je volgende project zou moeten gebruiken. We bespraken zowel gestructureerd loggen als gecentraliseerd loggen in detail. Bovendien leerden we hoe je Laravel logging kunt implementeren door een Todo toepassing te bouwen.

Hoe ben jij van plan logging in je volgende app te implementeren? Laat het ons weten in de commentaar sectie.

Solomon Eseme

I am a Software Engineer and Content Creator who is geared toward building high-performing and innovative products following best practices and industry standards. I also love writing about it at Masteringbackend.com. Follow me on Twitter, LinkedIn, and About Me