Fortuna Entwickler Blog

Hier wird Ihnen geholfen

SonarCloud - Master Solution - Analyse

Für die Master Solution braucht es einen anderen Ablauf. Damit es manuell funktioniert müssen folgende Schritte erfolgen.

Vorbereitung

Bevor die eigentliche Analyse gestartet werden kann, müssen verschiedene Schritte vollzogen werden.

1. Herunterladen des Sonarscanners. 

Damit die Zeilen von Code analysiert werden können, brauchen wir den Client von SonarCloud dazu.

Dort sollte die net4.6 Version genommen werden, aufgrund des Mixes von C++ und C# in der Solution. 

Die .zip Datei nach dem Entpacken an einen geeigneten Platz legen (z.B. unter C:\\SonarCloud). Im späteren Schritt, werden wir den Pfad noch brauchen.

2. Herunterladen des Buildwrappers

Damit die Logdateien während der Analyse gefüllt werden, wird der Buildwrapper von SonarCloud benötigt.

Die .zip Datei nach dem Entpacken an einen geeigneten Platz legen (z.B. unter C:\\SonarCloud). Im späteren Schritt, werden wir den Pfad noch brauchen.

3. Setzen der Umgebungsvariablen

Damit verschiedene Einstellungen direkt gefunden werden müssen folgende Befehle in einer Powershell Konsole ausgeführt werden:

[Environment]::SetEnvironmentVariable("SONAR_SCANNER_OPTS", "-Dhttps.proxyHost=10.98.98.222 -Dhttps.proxyPort=8080",[System.EnvironmentVariableTarget]::Machine)
Kontrolliert werden kann dies mit dem Befehl:

[Environment]::GetEnvironmentVariable("SONAR_SCANNER_OPTS", [System.EnvironmentVariableTarget]::Machine)

Setzen der Path Variable mit allen vorherigen Pfaden (anpassen der Pfade beachten):

[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\SonarCloud\build-wrapper-win-x86" + ";C:\SonarCloud\sonar-scanner-msbuild-5.3.1.36242-net46",[System.EnvironmentVariableTarget]::Machine)

Kontrolliert werden kann dies mit diesem Befehl:

[Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::Machine)

3. Herunterladen des aktuellen Java JDKs

Für den Scanner wird Java mindestens in der Version 11 benötigt.


Analyse - Routine

Token können innerhalb der SonarCloud Oberfläche als Administrator erzeugt werden:



Zum Starten der Analyse muss zuerst auf der Kommandozeile in das Verzeichnis navigiert werden in der die Master Solution liegt. Folgend werden die Befehle ausgeführt:

SonarScanner.MSBuild.exe begin /k:"Master_MyLife" /o:"mylife-leben" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="bfe291ef26f056234f4782e8660fbefe541fc12f" /d:sonar.cfamily.build-wrapper-output="build_wrapper_output_directory"


build-wrapper-win-x86-64.exe --out-dir build_wrapper_output_directory MSBuild.exe Master.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64
SonarScanner.MSBuild.exe end /d:sonar.login="bfe291ef26f056234f4782e8660fbefe541fc12f" 

Sonarcloud

Sonarcloud ist eine Software zur statischen Codeanalyse. Statische Codeanalyse bedeutet, dass der Code nach gewissen Regeln basierend auf der jeweiligen Programmiersprache überprüft wird. Sonarcloud setzt diesen Prozess um, indem eine Auflistung aller Resultate der Analyse präsentiert wird und zusätzlich Verbesserungsvorschläge aufgezeigt werden. 

Damit wir im Unternehmen die Software vollumfänglich nutzen können wird in diesem Artikel beschrieben, wie die Software zu benutzen ist.


Einrichten von Azure DevOps

Sonarcloud wird bei uns über die Azure DevOps Pipeline genutzt. Diese ist so konfiguriert, dass sie am Sonntagabend einen automatischen Durchlauf auslöst. Für die Einrichtung würde ich auf den folgenden Artikel verweisen. Da dieser alles vollumfänglich und vernünftig erklärt. Wichtig für uns sind folgende Stichpunkte:

  • Als Buildtool sollte MSBuild genutzt werden, da derzeit noch .NET Framework Anwendungen betrieben werden. Sollten diese irgendwann wegfallen, könnte über eine Analyse über dotnet nachgedacht werden
  • Bei der Einrichtung der Pipeline darf nicht vergessen werden, dass verschiedene Packages aus anderen Quellen, wie z.B. Telerik kommen. Dazu muss unter dem Punkt NuGet restore die Abhängigkeit eingetragen werden
  • Sollten verschiedene Dateitypen oder Ordner nicht mit in die Analyse einbezogen werden, dann kann dies über die Additional Properties konfiguriert werden. Um alle möglichen Parameter zu sehen, sollte die Sonarcloud Dokumentation angeschaut werden. 

Einrichten Account/Login
Über die Sonarcloud Seite kann ein Account "eingerichtet" werden. Da die Software über die Azure DevOps Funktionen genutzt wird, brauch kein gesonderter Account registriert werden. Es können die Credentials von dem normalen Azure DevOps Account genutzt werden. 
Zum Einloggen auf die Webseite gehen und oben rechts über Login und With Azure DevOps anmelden. Wenn es die erste Anmeldung ist, dann danach dem jeweiligen Administrator bescheid geben, damit er/sie zur Organisation eingeladen werden kann und die jeweiligen Issues zugeordnet werden können.


Ablauf
Im Folgenden wird der Prozess beschrieben wie myLife Sonarcloud einsetzt. 
Jedes Mitglied wird eine gewisse Anzahl an Issues innerhalb von Sonarcloud bekommen. Diese werden ausgewählt und zugewiesen anhand von den Kompetenzen und Wissensstand innerhalb der jeweiligen Projekte. Die Issues werden wöchentlich oder je nach Arbeitspensum zugewiesen. Zusätzliche Issues dürfen natürlich immer bearbeitet werden. Das Ziel ist es anfangs alle kritischen Vorkommnisse zu eliminieren. Danach werden die nächsten Probleme angegangen.

Sonarcloud ist nicht in der Lage Tickets innerhalb von Azure DevOps zu kreieren. Deshalb wird vom jeweiligen Administrator wöchentlich ein übergeordnetes Ticket in Azure DevOps angelegt, wodrin die jeweiligen Sonarcloud Tickets gesammelt werden. Dies kann dann zum einchecken von den Änderungen genutzt werden.


UI
Sobald der User sich anmeldet, wird ihm ein Dashboard angezeigt.

Dieses Dashboard stellt den Unterschied zwischen der vorherigen Version (weiß) und der aktuell hochgeladenen Version (gelb) da. Die Kategorien sollten selbsterklärend sein. Wenn dies nicht der Fall ist, dann können über die grauen Fragezeichen die Erklärungen angezeigt werden.

Für die Bearbeitung der Tickets sind vor allem die Punkte Issues und Security Hotspots wichtig. Diese beinhalten alle Tickets zu dem jeweiligen Bereich und gleichzeitig die Möglichkeit seine eigenen Issues anzuzeigen.




Bearbeitung von Tickets

Wenn ein Issue ausgewählt worden ist, gibt es die unten im Bild zu sehende Ansicht. Es gibt bei jedem Issue die Möglichkeit sich durchzulesen, wieso das ganze ein Fehler ist und wie dieser behoben werden könnte. 
Der Administrator wird im vorhinein eine Auswahl an Issues zuweisen, die seiner Meinung nach einen Fehler darstellen. Es ist sehr wichtig zu beachten, dass alle Fehler analysiert werden und zu 100% als behebungswürdig eingestuft werden müssen. Sollte dies nicht der Fall sein, dann bitte ein Kommentar dem Issue zuweisen und dem Administrator wieder zuweisen. Dies gilt auch bei Unklarheiten. Die Fehler sollen nur dann behoben sein, wenn der Entwickler sich zu 100% sicher ist. Sonst soll mit dem Team Rücksprache gehalten werden.
Wenn ein Fehler behoben worden ist, wird das Issue geschlossen.

Design Projekt .NET Core Web API

Um in der Zukunft einen einheitlichen Aufbau aller Projekte zu haben, wird hier ein Beispielaufbau einer Anwendung erklärt. Alle Angaben beziehen sich auf .NET Core Web APIs.

Aufbau Struktur

In jedem Projekt sollte es folgende Struktur geben:
  • Controllers => Beinhaltet jegliche Logik zu den Endpoints
  • Services => Beinhaltet jegliche Logik zur Verarbeitung der Daten (Anfragen an Datenbank, Manipulation von Daten, Anfrage an andere APIs usw.)
  • Mappings (wenn gebraucht) => Automapper Konfiguration Dateien
  • Resources (wenn gebraucht) => alle Projektspezifischen Ressourcen wie AppSettings Konfigurations Model 
  • Interfaces (wenn gebraucht) => Selbsterklärend
  • Extensions (wenn gebraucht) => Selbsterklärend
  • Models (wenn gebraucht)  => Selbsterklärend

Folgende Nuget-Pakete sollten in allen Anwendungen installiert sein:

Damit alle Pakete korrekt funktionieren müssen folgende Dinge in das Programm eingebaut werden.

Microsoft.AspNetCore.Mvc.NewtonsoftJson
Folgendes muss unter in der Startup.cs Datei in der Methode ConfigureServices reingeschrieben werden. Dies setzt die neue JSON Libary fest.


Swashbuckle.AspNetCore

Um Swagger nutzen zu können muss an zwei verschiedenen Stellen in der Startup.cs Datei Code eingefügt werden.

Zuerst in der ConfigureServices Methode nach der AddControllers Funktion muss Swagger hinzugefügt werden.

Danach muss Swagger noch aktiviert werden, dazu muss in der Configure Methode folgendes geschrieben werden.

Hier sind vor allem die Zeilen 35-39 wichtig. Der Aufbau der restlichen Zeilen kann aber übernommen werden. Hier gilt zu beachten, dass, dass der Name der API jeweils angepasst wird.

NLog NLog.Web.AspNetCore

http://webentw4/Blog/post/2020/05/12/nlog-in-in-asp-net-core-einbinden


ContentTypes

Die ContentTypes werden zentral in der Startup.cs eingestellt. Die meiste Zeit wird nur application/json benötigt. Sollten weitere benötigt werden, muss geschaut werden, ob diese zentral eingestellt werden oder nur für eine bestimmte Funktion. Zu beachten ist, wenn die ContentTypes überschrieben werden müssen an der Funktion dann alle angegeben werden.

Aufbau des Controllers

Ein Controller dient als Sammelstelle aller Endpoints. Hier ist nochmal zu erwähnen, jegliche Logik sollte in die Services geschrieben werden und nur der Zugriff auf die Services bzw. auf die Endpoints sollte im Controller beschrieben werden.

Im ersten Schritt sollte ein BaseController implementiert werden. Dieser beinhaltet alle allgemein gültigen Funktionen zur Verarbeitung von HTTP Requests bzw. Responses.


Der BaseController sollte zwingend die HandleError Methode besitzen, damit alle Fehler geloggt werden. Außerdem ist wichtig, dass der Controller mit dem Attribute ApiController ausgestattet wird, damit beim Kompilieren erkannt wird, dass alle zu erbenden Klassen bzw. Controller Teil der API sind.

Wird dann ein Blick auf die "richtigen" Controller geworfen, müssen ein paar Dinge erledigt werden. Zuerst muss die Route bestimmt werden. Diese wird mit api/[controller] angegeben. Daraus resultiert in dem Fall immer der Pfad api/vertrag/xxx. Dies hat den Vorteil, dass wir nicht in jeder Funktion gewisse Teile des Pfads doppelt schreiben müssen. 
Darüber hinaus muss der Logger und die benötigten Services per Dependency injection eingebunden werden.


Aufbau eines Endpoints

Alle Endpoints sollten folgenden Aufbau besitzen:

  • Http Request Methode mit Pfad => Funktionsname bzw. Abwandlung angeben und jeweilige Parameter mit Datentypen
  • Consume/Produces Types => Content-Types => In der Regel brauchen wir nur application/json (allgemein) => Diese werden vorher zentral in der Startup.cs eingestellt und nur genauer angegeben, wenn zusätzliche fehlen
  • ProducesResponseType => Rein zu Dokumentationszwecken gedacht, aber sinnvoll zum testen => Alle Rückgabetypen mit Statuscodes eintragen
  • Rückgabetyp => Sollte eigentlich immer IActionResult sein, da wir unterschiedliche Rückgabetypen haben wie unter ProducesResponseType zu sehen ist, außer bei asynchronen Aufrufen, dann sollte es Task<IActionResult> sein
  • Funktionsname => Titel der Funktion, wenn asynchron an den Namen immer ein Async anhängen
  • Try-Catch-HandleError => Für unerwartete Fehler wie z.B. in der Datenbank 

Umlautproblem bei Visual Studio beheben

Teilweise kommt es vor, wenn ein neuer Rechner aufgesetzt worden ist, dass Visual Studio Umlaute als Fragezeichen darstellt. (Eigentlich soll es keine Umlaute im Code geben!!!)
Damit dieses Problem nicht auftritt muss bei Windows 10 eine Einstellung vorgenommen werden.

Der Weg zur Option ist folgender:
Systemsteuerung => Zeit und Region => Region => Verwaltung => Gebietsschema ändern

Dort gibt es die Option "Beta: Unicode UTF-8 für die Unterstützung weltweiter Sprachen verwenden". Diese Option deaktivieren, Rechner neu starten und voilà das Problem sollte behoben sein.

NPM Config - MSBuild Pfad & Version bearbeiten

Vor kurzem hat Microsoft .net Version 5 auf den Markt gebracht. Dadurch haben sich in der Verwaltung von Angular Anwendung in Bezug auf asp.net Core Anwendungen ein paar Einstellungen geändert. Beim ausführen der Paketinstallation in einer Angular Anwendung über npm mit "npm install" führte vermehrt zu dem Problem, dass die MSBuild.exe nicht gefunden werden konnte.
Um dieses Problem zu beheben muss npm mitgeteilt werden, wo die .exe liegt und welche Version es nutzen soll.

Um den Pfad einzustellen muss folgender Befehl ausgeführt werden (ggf. Pfad anpassen):

  • npm config set msbuild_path "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe"
Um die Version einzustellen muss folgender Befehl ausgeführt werden (ggf. Versionsnummer anpassen):

  • npm config set msvs_version 2017
Stand 01.12.2020 muss Version 2017 noch angegeben werden, da NPM 2019 als Keyword nicht registrieren kann.

Ggf. kommt dieses Problem auch durch das builden von dem Package node-gyp in Verbindung mit einer Node.js Version 12+.

Weitere Informationen:
  • https://github.com/nodejs/node-gyp/issues/1753

Was ist der Unterschied zwischen InProcess und OutOfProcess Hosting in asp.net Core?

Um eine asp.net Core Anwendung hosten zu können, gibt es zwei Möglichkeiten. Zum einen InProcess und zum anderen OutOfProcess. Im Folgenden wird der Unterschied erklärt:

  • InProcess: Das Hosting wird über den IIS-Server bereitgestellt.image-7.png (840×221)
  • OutOfProcess: Das Hosting wird über den Kestrel Web Server bereitgestellt.image-9.png (771×174)

Was ist der Unterschied zwischen den beiden Web-Servern? Der IIS ist ein seit über 15 Jahren aktiver Webserver, der gleichzeitig die größtmöglichste Abwärtskompatibiltät gewährt. Dies fällt zu Lasten der Performance. Um diesem Prozess entgegen zu wirken, wurde der Kestrel Web Server erstellt. Der Fokus liegt hier auf neueren Technologien, wie z.B. Async Unterstüztung.

Weitere Informationen:

UseStaticFiles() vs UseSpaStaticFiles() vs UseSpa()

Wenn eine asp.net-Core Anwendung mit einem Frontend wie z.B. Angular geschrieben wird, müssen meist statische Dateien bereitgestellt werden. Im Folgenden wird eine Erklärung dafür gegeben:

  • UseStaticFiles: Der Befehl gibt an, dass statische Dateien wie js, css, html usw. bereitgestellt werden. Typischerweise aus dem wwwrooot-Ordner, wobei dieser geändert werden kann. Die Dateien werden so wie sie erstellt worden sind dem Clienten zur Verfügung gestellt.
  • UseSpaStaticFiles: Der Befehl registriert eine Middleware, die dafür sorgt, dass Dateien aus dem Ordner bereitgestellt werden. Der Pfad wird dafür in de Funktion ConfigureServices => AddSpaStaticFiles konfiguriert.
  • UseSpa: Der Befehl registriert eine Middleware, welche alle Parameter enthält, um die Anwendung starten zu können. Z.B. aus welchem Ordner die Anwendung gestartet wird, in welcher Modus (Dev,Prod) und auch mit welchem Befehl die Anwendung gestartet wird (z.B. npm start).

Weitere Informationen:

Einbinden der Newtonsoft.Json Libary in einer .NET Core Anwendung

Seit .NET Core 3.0 hat Microsoft eine eigene Libary (System.Text.Json) freigegeben, um Operationen im JSON-Format durchzuführen. Darunter fällt auch das serialisieren und deserialisieren von Requests & Respones an eine API.

Leider hat die Libary noch ein paar Schwierigkeiten (Stand 09.10.2020) komplexere Datentypen, wie Dictionaries zu verarbeiten. Teilweise treten System.NotSupportExceptions auf, da die Libary, die Datentypen nicht unterstützt.

Damit das Problem umgangen werden kann, gibt es weiterhin die alt bekannte Newtonsoft.Json-Libary, die genutzt werden kann und auch mit komplexeren Datentypen umgehen kann.

Folgende Schritte müssen durchgeführt werden, um die Libary einzubinden:

  1. Newtonsoft.Json als Nuget Paket hinzufügen
  2. Als nächstes abhängig davon was für ein Projekt vorliegt, muss in der Startup.cs-Datei folgende Zeile geändert/hinzugefügt werden:

Sobald der Befehl abgeändert worden ist, wird das Paket automatisch genutzt in der Vearbeitung aller JSON-Operationen.

Umstellung einer Assembly von .NET Framework auf.NET Standard

Zunächst wählt man ein projekt aus, dass man auf .NET Standard umstellen möchte und wechselt im Datei Explorer zu diesem Projekt:


Jetzt legt man sich eine Sicherheitskopie irgendwo von diesem Ordner an, in dem man sich befindet und wechselt anschließend wieder ins Visual Studio.

Dort entfernt man das Projekt aus der Solution:


Jetzt kann man das Projekt auch auf Datei-Ebene löschen:



Als nächstes wird das Projekt neu in der Solution angelegt. Auch hier muss die selbe Stelle genommen werden, wo das alte Projekt lag:



Als Typ nimmt man die Class Library für .NET Standard. Natürlich mit der Sprache C#:



Der Name muss der selbe sein, den das Projekt auch schon früher hatte und der Ort muss der selbe sein, wo das alte Projekt vorher auch schon lag:



Jetzt ist das Projekt in der Solution. Die enthaltene Klasse "Class1.cs" kann man direkt einfach löschen:



Nun muss man den Code wieder in das Projekt packen. Dazu klickt man mit rechts auf das projekt und sagt "Add existing Item":



Im darauf folgenden Dialog wählt man aus seiner Sicherheitskopie sämtliche Code-Dateien aus (*.cs). Sollte das Projekt früher eine Ordnerstrukur gehabt haben, so muss man darauf achten, dass diese 1:1 nachgebildet wird. Sie muss auch wieder so vorhanden sein wie früher. Bitte jetzt nicht umstrukturieren!!!!:



Man sieht jetzt, dass die Dateien wieder im Projekt sind und die CS Dateien sind auch nicht ausgecheckt, sondern eingecheckt, weil sie den selben Namen haben wie vorher und die selbe Struktur und den selben Inhalt:



Nun kompiliert man zum ersten Mal das neue Projekt. Es wird dann möglichweise zu Fehlern kommen, da das alte Projekt Referenzen auf andere Fortuna Projekte hatte oder NuGet Packages eingebunden waren. Die muss man dann natürlich wieder hinzufügen. Man kann allerdings nur Fortuna Projekte referenzieren, die bereits auf .NET Standard umgestellt sind. Daher ist es hier sehr wichtig, dass man auf die Reihenfolge achtet, wenn man Fortuna Projekte auf .NET Standard umstellt!!!! Dies prüft man am besten am Anfang!!!!

Wenn sich das Projekt selbst kompilieren lässt, muss man prüfen, ob sich auch noch die Solution kompilieren lässt. Also macht man ein Build auf die Solution. Man wird dann wieder einige Fehler bekommen, denn durch das Entfernen des Projektes am Anfang aus der Solution, wurden bei vielen anderen Projektten auch die Referenz entfernt. Man erkennt dies in der Solution auch gut daran, dass diese Projekte in der Solution jetzt ausgecheckt sind (roter Haken).

Bei all diesen Projekten muss man nun die Referenzb auf dieses Projekt wieder reinnehmen.

Lässt sich die Solution anschließend wieder komplett durchkompilieren, geht es an die Feinheiten. Dazu klickt an doppelt auf das neue Projekt drauf, so dass man die Config des Projektes als XML sieht:


In der zweitenPropertyGroup fügt man nun noch folgende Zeile ein:

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

Sieht dann so aus:



Jetzt kann man alles einechecken in der Solution, also auch die Solution selber und die Projekte bei denen die Referenzen neu gesetzt werden mussten. Am besten hat man sich für die Umstellung des Projektes ein eigenes Workite angelegt.

Die Umstellung auf .NET Standard ist damit abgeschlossen.


NLog in in ASP.NET Core einbinden

Um NLog in einer ASP.NET Core Webanwendung oder Sevice zu verwenden, müssen zunächst die entsprechenden NuGet Packages installiert werden in der Anwendung. Dies sind die folgenden Packages

  • NLog
  • NLog.Web.AspNetCore
Hierbei bitte darauf achten, dass die Versionen verwendet werden, die auch bereits bei anderen Fortuna Anwendungen verwendet werden, damit es einheitlich bleibt.

Als nächstes wird eine lokale Umgebungsvariable "IS_LOCAL" in der ASP.NET Core Anwendung angelegt. Der Wert wird auf "true" gesetzt:



Anschließend wird die "Program.cs" Datei angepasst. Diese sieht ursprünglich ungefähr so aus:


Die "main"-Methode (Kann von Fortuna.Web.Abschluss kopiert werden) muss so angepasst werden:



Und die "CreateWebHostBuilder"-Methode so:



Als nächstes müssen die CONFIG-Dateien für NLog hinzugefügt werden. Hier bietet es sich an, diese von einer anderen Fortuna Anwendung wie Fortuna.Web.Abschluss zu kopieren, damit das Logging in den Anwendungen einheitlich passiert. Es müssen dann lediglich die Pfade in den CONFIG Dateien angepasst werden. Ich habe die Dateien auch mal als Anhang an diesen Post gehangen:

nlog.config (1,5KB)nlog.Development.config (1,9KB)nlog.Production.config (1,9KB)nlog.Test.config (1,9KB)

Nun benötigt man noch auf den Servern Ordner, wo die Logs hingeschrieben werden sollen (aktuell machen wir mit NLog File Logging).

Man findet den allgemeinen Log-order wie folgt:
  • \\webentw4\Logs
  • \\webtest4\Logs
  • \\web4\Logs
Jede Anwendung bekommt dort drin einen eigenen Unterordner (z.B. Dashboard). Außerdem befindet sich in den Logs-Ordnern ein "_Archive"-Ordner, wo auch jede Anwendung einen eigenen Unterordner drin besitzt.

Um nun die neuen Ordner anzulegen muss man sich per RDP auf die einzelnen Server connecten und die Unterordner in Logs und _Archive anlegen, da nur der Admin Schreibrechte hat und die IT-User lediglich Leserechte. Das Anlegen der Unterordner sollte so gemacht werden, wie die bereits vorhanden Ordner, damit diese Struktur beibehalten wird. Die Pfade zu den Ordnern müssen dann in den NLog CONFIG-Files eingetragen werden.

Nun ist alles fertig konfiguriert und der Logger kann im Controller der ASP.NET Core Anwendung verwendet werden. Da durch die Anpassung der main-Methode die Dependency Injection aktiviert wurde, kann der Logger ganz einfach im Konstruktor des Controllers verwendet werden:


Man benötigt einfach eine globale Variable vom Typ ILogger im Controller und man nimmt den ILogger auch im Kopf des Konstruktors vom Controller mit auf. Falls es noch keinen Konstruktor gibt im Controller, leget man einfach einen an. Im Konstruktor selbst weist man nur der globalen Variable die lokale Konstruktor-Variable zu. Nun kann man den Logger überall im Controller verwenden. Dies macht man für jeden Controller der Anwendung:


Das Ergebnis des File Logging sieht dann wie folgt aus: