Sentry
Überblick
OSentry ist ein REST-API-Konnektor von Omnis Studio zu Sentry. Der Konnektor sendet Fehler, Messages, Logs und Laufzeitkontext aus Omnis-Anwendungen an Sentry, damit Probleme in produktiven Systemen sichtbar, gruppierbar und analysierbar werden.
Diese Dokumentation beschreibt die Installation, die Nutzung in bestehenden Omnis-Anwendungen, die Definition eigener standardisierter Exception-Typen, die interne Struktur und die Demo-Library.
Inhalt
- 01 Installation
- 02 Quickstart
- 03 Events erfassen
- 04 Eigene Exceptions standardisieren
- 05 Tags Extras und User
- 06 Stacktrace und Kontext
- 07 Interne Architektur
- 08 Demo Library
- 09 API Reference
- 10 Troubleshooting
Kernidee
OSentry besteht aus zwei produktiv relevanten Klassen:
OSentryHL: High-Level-Adapter für die Anwendung. Diese Klasse sollte von normalem Applikationscode aufgerufen werden.OSentry: Low-Level-Adapter für DSN-Parsing, JSON-Erzeugung, Stacktrace-Aufbereitung und HTTP-Kommunikation mit Sentry.
Die Anwendung arbeitet im Normalfall mit OSentryHL. Dadurch bleiben Sentry-spezifische Details zentral gekapselt und neue standardisierte Exception-Typen können als eigene Methoden in OSentryHL definiert werden.
Hauptfeatures
- Direkte Anbindung von Omnis Studio an Sentry über REST API und DSN
- Erfassen von Exceptions, Messages, Logs und SQL-Fehlern
- Unterstützung der Sentry-Level
fatal,error,warning,infounddebug - Automatische Omnis-Kontextinformationen
- Omnis-Stacktrace mit Klassen, Methoden, Zeilen und Variablen
- Tags für Filterung und Gruppierung
- Extras für zusätzliche Diagnoseinformationen
- Optionaler User-Kontext
- Proxy-Unterstützung
- Aktivieren und Deaktivieren der Sentry-Übertragung
- Lokales Speichern von Reports bei Übertragungsfehlern
Weiterführende Links
Screenshots
Installation
Diese Seite beschreibt, wie OSentry in eine bestehende Omnis-Anwendung integriert wird.
Voraussetzungen
- Omnis Studio Anwendung
- Sentry Account oder self-hosted Sentry Installation
- Ein Sentry-Projekt mit SDK-Typ
Other - Die DSN des Sentry-Projekts
- Netzwerkzugriff auf Sentry
Die exportierte Demo-Library wurde mit Omnis 11.1 erstellt.
Sentry-Projekt erstellen
- In Sentry ein neues Projekt erstellen.
- Als SDK
Otherauswählen. - Die DSN des Projekts kopieren.
Die DSN wird beim Initialisieren verwendet. OSentry zerlegt sie intern in Public Key, Host und Project ID.
Klassen kopieren
Kopiere die folgenden Klassen in deine bestehende Omnis-Library:
OSentryOSentryHL
Die Demo-spezifischen Klassen sind für die produktive Integration nicht erforderlich. Damit sind die übrigen Klassen der Demo-Library gemeint, zum Beispiel FSY_Demo, ODummy, ODatabaseHandler und OSLSession. Diese Klassen dienen nur dazu, die Demo-Library mit Fenster, SQLite-Testdaten und Beispielaufrufen auszuführen.
Task Variable anlegen
Lege in deiner Startup Task eine Task Variable an:
| Name | Typ |
|---|---|
tSentry |
OSentryHL
|
tSentry sollte als global erreichbarer Singleton der Anwendung verwendet werden. In Omnis ist dafür eine Task Variable sinnvoll, weil sie von Fenstern, Objektklassen und zentralen Error-Handlern aus konsistent erreichbar ist. Dadurch gibt es genau eine aktive Sentry-Konfiguration mit einer DSN, einem Status, optionalen Proxy-Daten und gemeinsamen Wrapper-Methoden in OSentryHL.Im Demo-Projekt ist diese Variable in Startup_Task definiert.
Initialisierung im Startup Task
Initialisiere tSentry beim Start deiner Anwendung mit der DSN deines Sentry-Projekts:
Do tSentry.$init('<DSN>')
Die Demo-Library ruft im Startup Task ebenfalls die Initialisierung auf. Quelle: Startup_Task.$construct.
#Init Sentry on lbs startup Do tSentry.$init()
In einer produktiven Anwendung sollte die DSN explizit oder aus einer Konfiguration übergeben werden:
Do tSentry.$init('https://PUBLIC_KEY@sentry.io/PROJECT_ID')
Testcall
Nach der Initialisierung kann ein erstes Testevent gesendet werden:
Do tSentry.$captureMessage('Hello World!')
Wenn alles korrekt eingerichtet ist, erscheint das Event im Sentry-Projekt.
Proxy konfigurieren
Falls die Anwendung in einem geschützten Netzwerk läuft, kann ein Proxy gesetzt werden. Die Methode befindet sich im Low-Level-Objekt OSentry.
Do tSentry.iOSentry.$setProxy('proxy.example.local','8080')
Die interne Implementierung setzt den Proxy vor dem HTTP-Request:
#Configure proxy; needed when sending data out of secured networks If not(isclear(iProxyHost))¬(isclear(iProxyPort)) HTTPSetProxyServer (iProxyHost,iProxyPort) End If
Sentry aktivieren oder deaktivieren
OSentry kann zentral ein- oder ausgeschaltet werden.
Do tSentry.$setStatus(1) ## aktiv Do tSentry.$setStatus(0) ## inaktiv
Im Low-Level-Objekt OSentry wird vor dem Senden geprüft:
#Check if Sentry is enabled If iStatus=0|isclear(iStatus) Quit method 0 End If
Quickstart
Diese Seite zeigt die minimale Integration in eine bestehende Omnis-Anwendung.
Klassen übernehmen
Kopiere OSentry und OSentryHL in deine Library.
Task Variable erstellen
In der Startup Task:
| Name | Typ |
|---|---|
tSentry |
OSentryHL
|
Sentry initialisieren
Do tSentry.$init('https://PUBLIC_KEY@sentry.io/PROJECT_ID')
OSentryHL.$init delegiert an das Low-Level-Objekt OSentry:
#Init of the main sentry object Do iOSentry.$init(pDSN) Quit method
Message senden
Do tSentry.$captureMessage('Hello Euromnis! This is a test message...')
Die Demo-Library verwendet genau diesen Aufruf im Button Trigger a message. Quelle: FSY_Demo.message.$event.
On evClick ## Event Parameters - pRow( Itemreference )
Do tSentry.$captureMessage('Hello Euromnis! This is a test message...')
Do $cinst.$showmessage('Sentry Event successfully triggered!','Info')
Quit method
Exception senden
Do tSentry.$captureException('A generic Exception occured',1234,'Generic Exception','error')
In Sentry prüfen
In Sentry sollte anschließend ein neues Event sichtbar sein. Je nach Event-Typ enthält es:
- Message
- Level
- Tags
- Extras
- User-Kontext
- Stacktrace
- Omnis-Kontextinformationen
Events erfassen
OSentryHL ist die empfohlene Einstiegsschicht für Applikationscode. Die Klasse bietet sprechende Methoden für typische Event-Arten und ruft intern OSentry.$captureException auf.
Message
Eine einfache Information wird mit $captureMessage gesendet:
Do tSentry.$captureMessage('Hello World!')
Implementierung in OSentryHL:
# Captures an Info Message Do iOSentry.$captureException(pMessage,3,,'info',kFalse,,kFalse) Returns code Quit method
Verhalten:
- Level:
info - Kein Stacktrace
- Kein User Interface
- Geeignet für einfache Statusmeldungen oder technische Hinweise
Log
Ein Log-Event wird mit $captureLog gesendet:
Do tSentry.$captureLog('Uh oh this is a Log because something went wrong')
Implementierung in OSentryHL:
# Captures a Log Sentry Report Do iOSentry.$captureException(pErrorText,1,'Log','warning',1,0,1) Returns code Quit method
Verhalten:
- Level:
warning - Stacktrace aktiv
- Exception Interface in diesem Wrapper deaktiviert
- User Interface aktiv
Generische Exception
Eine generische Exception wird mit $captureException gesendet:
Do tSentry.$captureException('A generic Exception occured',1234,'Generic Exception','error')
Implementierung in OSentryHL:
# Method to capture a generic Exception
#Add any custom tags / extras
Do $cinst.$addTag('Custom Test Tag','Euromnis')
Do iOSentry.$captureException(pErrorText,pErrorCode,pExcType,pLevel) Returns code
Quit method
Parameter:
| Parameter | Bedeutung |
|---|---|
pErrorText |
Text, der in Sentry als Message sichtbar ist |
pErrorCode |
Fehlercode oder fachlicher Code |
pExcType |
Exception-Typ für Benennung und Gruppierung |
pLevel |
Sentry-Level |
Gültige Levels:
fatalerrorwarninginfodebug
SQL Exception
SQL-Fehler können mit $captureSQLException gemeldet werden.
Do tSentry.$captureSQLException('SQL statement failed',stat)
Implementierung in OSentryHL:
# Method to capture an SQL Exception
Do $cinst.$addTag('Database',tOSLSession.$hostname)
Do $cinst.$addExtra('SQL-Text',pStat.$sqltext)
Do $cinst.$addExtra('SQL-Error',pStat.$nativeerrortext)
Do iOSentry.$captureException(pErrorText,1,'SQL-Exception','error')
Quit method
Verhalten:
- Fügt die Datenbank als Tag hinzu
- Fügt SQL-Text als Extra hinzu
- Fügt native Datenbankfehlermeldung als Extra hinzu
- Sendet das Event als
SQL-Exceptionmit Levelerror
Deprecated Call
Veraltete Codepfade können gezielt gemeldet werden:
Do tSentry.$captureDeprecatedCall()
Implementierung in OSentryHL:
# Report a deprecated call of a piece of code to sentry
Do iOSentry.$captureException('Deprecated Call',3,'Deprecated Call','warning',1,1,1) Returns code
Quit method
Dieser Wrapper eignet sich, um zu erkennen, ob alter Code in produktiven Systemen noch ausgeführt wird.
Frei konfigurierbares Event
Für Sonderfälle gibt es $captureAnything:
Do tSentry.$captureAnything('Text',1001,'Custom Type','error',kTrue,kTrue,kTrue)
Implementierung in OSentryHL:
# Capture a generic Sentry Report (max configurability) Do iOSentry.$captureException(pErrorText,pErrorCode,pExcType,pLevel,pStacktraveInterface,pExceptionInterface,pUserInterface) Returns code Quit method
Diese Methode bietet maximale Flexibilität. Für wiederkehrende Exception-Typen sollte aber eine eigene Methode in OSentryHL angelegt werden. Siehe 04 Eigene Exceptions standardisieren.
Eigene Exceptions standardisieren
Wenn ein Exception-Typ mehrfach in der Anwendung vorkommt, sollte er nicht überall manuell mit $captureException aufgebaut werden. Besser ist eine eigene Methode in OSentryHL.
Dadurch entsteht eine zentrale, wiederverwendbare Definition für:
- Exception-Typ
- Sentry-Level
- Fehlercode
- Tags
- Extras
- Stacktrace/User/Exception Interface
Die automatisch gesetzten Tags und Extras aus OSentry.$generateJson müssen in solchen Wrappern nicht erneut ergänzt werden. Eigene Exception-Methoden setzen nur zusätzliche Werte, die für diesen standardisierten Exception-Typ relevant sind.
Warum über OSentryHL?
OSentryHL ist die Abstraktionsschicht für Applikationscode. Sie kapselt die Details von OSentry und sorgt dafür, dass Aufrufe in der Anwendung kurz und konsistent bleiben.
Bestehende Beispiele aus OSentryHL:
# Report a deprecated call of a piece of code to sentry
Do iOSentry.$captureException('Deprecated Call',3,'Deprecated Call','warning',1,1,1) Returns code
Quit method
# Method to capture an SQL Exception
Do $cinst.$addTag('Database',tOSLSession.$hostname)
Do $cinst.$addExtra('SQL-Text',pStat.$sqltext)
Do $cinst.$addExtra('SQL-Error',pStat.$nativeerrortext)
Do iOSentry.$captureException(pErrorText,1,'SQL-Exception','error')
Quit method
Empfohlenes Muster
Für jeden standardisierten Exception-Typ wird eine eigene Methode in OSentryHL erstellt.
Beispiel:
# Captures a validation exception
Do $cinst.$addTag('Module',pModule)
Do $cinst.$addExtra('Field',pField)
Do $cinst.$addExtra('Invalid Value',pValue)
Do iOSentry.$captureException(pErrorText,2001,'Validation-Exception','warning',1,1,1) Returns code
Quit method code
Mögliche Parameter der neuen Methode:
| Parameter | Beispiel | Zweck |
|---|---|---|
pErrorText |
'Invalid customer number' |
Sentry Message |
pModule |
'Customer' |
Filterbarer Tag |
pField |
'cu_number' |
Diagnoseinformation |
pValue |
'ABC' |
Diagnoseinformation |
Der Applikationscode bleibt dadurch einfach:
Do tSentry.$captureValidationException('Invalid customer number','Customer','cu_number',cu_number)
Beispiel: Business Rule Exception
Neue Methode in OSentryHL:
# Captures a business rule violation
Do $cinst.$addTag('Module',pModule)
Do $cinst.$addTag('Business Rule',pRuleName)
Do $cinst.$addExtra('Details',pDetails)
Do iOSentry.$captureException(pErrorText,3001,'Business-Rule-Violation','warning',1,1,1) Returns code
Quit method code
Aufruf in der Anwendung:
Do tSentry.$captureBusinessRuleViolation('Invoice cannot be posted','Invoice','PostingAllowed','Invoice is missing customer')
Beispiel: Integration Exception
Neue Methode in OSentryHL:
# Captures an integration exception
Do $cinst.$addTag('Integration',pSystem)
Do $cinst.$addTag('Endpoint',pEndpoint)
Do $cinst.$addExtra('Payload',pPayload)
Do $cinst.$addExtra('Response',pResponse)
Do iOSentry.$captureException(pErrorText,4001,'Integration-Exception','error',1,1,1) Returns code
Quit method code
Aufruf in der Anwendung:
Do tSentry.$captureIntegrationException('External API request failed','ERP','/api/customer',jsonPayload,responseText)
Namenskonventionen
Empfehlung für neue Methoden:
- Methodenname beginnt mit
$capture - Der fachliche Typ steht im Methodennamen
- Der Sentry Exception Type ist stabil und ändert sich nicht laufend
- Tags sind kurz und filterbar
- Extras dürfen länger sein und Diagnoseinformationen enthalten
Beispiele:
$captureValidationException$captureBusinessRuleViolation$captureIntegrationException$capturePermissionViolation$captureConfigurationError
Error Codes
Verwende feste Fehlercodes für standardisierte Exception-Typen. Dadurch können Events in Sentry besser gefiltert und wiedererkannt werden.
Beispiel:
| Code | Exception Type |
|---|---|
2001 |
Validation-Exception
|
3001 |
Business-Rule-Violation
|
4001 |
Integration-Exception
|
5001 |
Configuration-Error
|
Wann nicht standardisieren?
Nicht jeder Einzelfall braucht eine eigene Methode. Für einmalige technische Tests oder sehr spezielle Fälle reicht:
Do tSentry.$captureException('A generic Exception occured',1234,'Generic Exception','error')
Sobald ein Exception-Typ aber mehrfach vorkommt oder fachlich relevant ist, sollte er als eigene Methode in OSentryHL definiert werden.
Tags, Extras und User-Kontext
Tags, Extras und User-Kontext reichern Sentry-Events mit zusätzlichen Informationen an. Diese Informationen helfen beim Filtern, Gruppieren und Analysieren.
Tags
Tags sind kurze, filterbare Werte.
Beispiele:
- Datenbank
- Kunde
- Modul
- Umgebung
- Error Code
- Omnis-Version
Methode in OSentryHL:
# Add a Tag to the next Sentry Report Do iOSentry.$addTag(pName,pValue) Quit method
Methode in OSentry:
#Adds a tag to the next request processed Do iTagList.$add(pName,pValue) Quit method
Beispiel:
Do tSentry.$addTag('Module','Invoice')
Do tSentry.$addTag('Customer','10001')
Do tSentry.$captureException('Invoice posting failed',3001,'Business-Rule-Violation','warning')
Extras
Extras sind Detailinformationen, die nicht primär zum Filtern gedacht sind.
Beispiele:
- SQL-Text
- Native Datenbankfehlermeldung
- Payload
- Response Body
- interne IDs
- zusätzliche Debug-Informationen
Methode in OSentryHL:
# Add an Extra to the next Sentry Report Do iOSentry.$addExtra(pName,pValue) Quit method
Methode in OSentry:
#Adds extra information to the next request being processed Do iExtraList.$add(pName,pValue) Quit method
Beispiel aus der SQL Exception:
Do $cinst.$addExtra('SQL-Text',pStat.$sqltext)
Do $cinst.$addExtra('SQL-Error',pStat.$nativeerrortext)
Automatische Tags
Die folgenden Tags werden bei jedem Event automatisch von OSentry.$generateJson ergänzt. Sie müssen bei eigenen Exceptions nicht erneut gesetzt werden. Eigene Wrapper-Methoden in OSentryHL sollten nur zusätzliche, fachlich oder technisch relevante Tags hinzufügen.
OSentry.$generateJson fügt mehrere Tags automatisch hinzu:
# Add static tags
Do iTagList.$add('Omnisversion',sys(1))
Calculate systemversionRow as systemversion()
Do iTagList.$add('Plattform',con(sys(8),pick(systemversionRow.server,'',' SRV')))
Do iTagList.$add('OS Version',con(systemversionRow.major,'.',systemversionRow.minor,'.',systemversionRow.build))
Do iTagList.$add('error_code',pErrorCode)
Automatisch gesendete Tags:
| Tag | Herkunft | Zweck |
|---|---|---|
Omnisversion |
sys(1) |
Zeigt, mit welcher Omnis-Version das Event erzeugt wurde |
Plattform |
sys(8) und Server-Flag aus systemversion() |
Unterscheidet Plattform und Server Runtime |
OS Version |
systemversionRow.major/minor/build |
Zeigt die Betriebssystemversion |
error_code |
Parameter pErrorCode |
Verbindet das Event mit dem übergebenen Fehlercode |
Beispiel für eine eigene Exception: Der Wrapper muss nicht erneut Omnisversion oder OS Version setzen. Er ergänzt nur das, was für diesen Exception-Typ zusätzlich hilfreich ist.
Do $cinst.$addTag('Module',pModule)
Do $cinst.$addTag('Business Rule',pRuleName)
Do iOSentry.$captureException(pErrorText,3001,'Business-Rule-Violation','warning',1,1,1) Returns code
Automatische Extras
Auch die folgenden Extras werden bei jedem Event automatisch ergänzt. Bei eigenen Exceptions müssen nur zusätzliche Extras gesetzt werden, zum Beispiel ein SQL-Statement, ein Payload oder fachliche Zusatzdaten.
OSentry.$generateJson fügt offene Fenster, offene Reports und die aktuelle Printfile hinzu:
# Static extra 1: All open windows
Do $root.$iwindows.$makelist($ref.$name) Returns nameList
For i from 1 to nameList.$linecount step 1
Calculate windows as con(windows,', ',nameList.[i].1)
End For
Calculate windows as right(windows,len(windows)-2)
Do iExtraList.$add('Open Windows',windows)
# Static extra 2: All open reports
Do $root.$ireports.$makelist($ref.$name) Returns nameList
For i from 1 to nameList.$linecount step 1
Calculate reports as con(reports,', ',nameList.[i].1)
End For
Calculate reports as right(reports,len(reports)-2)
Do iExtraList.$add('Open Reports',reports)
Do iExtraList.$add('Current Printfile',$root.$prefs.$printfile)
Automatisch gesendete Extras:
| Extra | Herkunft | Zweck |
|---|---|---|
Open Windows |
$root.$iwindows.$makelist($ref.$name) |
Zeigt, welche Fenster im Moment des Events offen waren |
Open Reports |
$root.$ireports.$makelist($ref.$name) |
Zeigt, welche Reports im Moment des Events offen waren |
Current Printfile |
$root.$prefs.$printfile |
Zeigt die aktuell gesetzte Printfile |
Beispiel für zusätzliche Extras in einem eigenen Wrapper:
Do $cinst.$addExtra('Payload',pPayload)
Do $cinst.$addExtra('Response',pResponse)
Do iOSentry.$captureException(pErrorText,4001,'Integration-Exception','error',1,1,1) Returns code
User-Kontext
Der User-Kontext ordnet ein Event einem betroffenen Benutzer zu. In Sentry erscheint dadurch ein eigener User-Bereich, und Events können nach Benutzer gefiltert oder gruppiert werden. Das ist besonders hilfreich, wenn ein Fehler nur bei einzelnen Kunden, Arbeitsplätzen oder Benutzerkonten auftritt.
OSentry unterstützt drei User-Felder:
| Feld | Bedeutung |
|---|---|
id |
stabile interne Benutzer-ID oder Kundennummer |
username |
lesbarer Benutzername |
email |
E-Mail-Adresse, falls sie übertragen werden darf |
Der User-Kontext wird nur in das Event geschrieben, wenn das User Interface beim Capture-Aufruf aktiviert ist. Die Standardmethode OSentry.$captureException hat pUserInterface standardmäßig auf kTrue. Einzelne High-Level-Methoden können das bewusst deaktivieren, zum Beispiel $captureMessage.
OSentry kann User-Daten an das Event anhängen:
#Sets userinformation for the next request being processed Calculate iUserID as pID Calculate iUserName as pName Calculate iUserEmail as pEmail Quit method
Das User Interface wird so generiert:
# Create user data row
Do UserdataRow.$define(id,email,username)
Calculate UserdataRow.id as iUserID
Calculate UserdataRow.email as iUserEmail
Calculate UserdataRow.username as iUserName
Do JSON.$addmember('','user','')
Do JSON.$setobject('user',UserdataRow)
Calculate jsonString as OJSON.$formatjson(JSON.$getjson())
Quit method jsonString
Die aktuelle Demo-Methode in OSentryHL verwendet feste Testdaten. Quelle: OSentryHL.$setUser.
# Set the User which should be linked to the Sentry Issue Do iOSentry.$setUserData(23,'Euromnis Test User','euromnis@test.com') Quit method
Für produktive Nutzung sollte diese Methode angepasst und parametrisiert werden:
Do iOSentry.$setUserData(pUserID,pUserName,pUserEmail) Quit method
Empfohlen ist, den User nach Login oder beim Wechsel des aktiven Benutzers zentral zu setzen. Bei anonymen oder sensiblen Installationen kann statt Name und E-Mail auch nur eine interne ID oder ein pseudonymisierter Wert verwendet werden.
Datenschutz
Besonders kritisch sind:
- personenbezogene Daten
- Kundendaten
- SQL-Statements mit Werten
- Zugangsdaten
- Tokens
- interne Pfade
Tags und Extras sollten so gestaltet werden, dass sie für die Fehleranalyse hilfreich sind, aber keine unnötigen sensiblen Daten übertragen.
Stacktrace und Kontext
OSentry erzeugt einen Omnis-spezifischen Stacktrace und übergibt ihn an Sentry. Dadurch sieht man in Sentry nicht nur eine Fehlermeldung, sondern auch Klassen, Methoden, Zeilen und Variablenkontext. Ergänzende Informationen zu Tags, Extras und User-Kontext stehen auf der separaten Kontext-Seite.
Stack lesen
OSentry.$generateStacktraceInterface verwendet sys(192), um den aktuellen Omnis-Stack zu lesen:
# Clean up the Stacklist (remove OSentry classes from the stack)
Do sys(192) Returns sys192List
For sys192List.$line from 1 to sys192List.$linecount step 1
Set reference class to sys192List.classitem
If pos('OSentry',class.$name)>0|pos('OSentryHL',class.$name)>0
Do sys192List.[sys192List.$line].$selected.$assign(kTrue)
End If
End For
Do sys192List.$remove(kListDeleteSelected)
Interne Frames von OSentry und OSentryHL werden entfernt, damit in Sentry die fachlich relevanten Stellen sichtbar bleiben.
SQL-Error Frames entfernen
Bestimmte interne SQL-Fehlerframes werden ebenfalls entfernt:
# Remove some other classes which we do not want to display If sys192List.1.method='$sqlerror' Do sys192List.$remove(1) Else If sys192List.1.method='$statementerror' Do sys192List.$remove(1) End If
Frames erzeugen
Für jeden Stack-Eintrag werden Funktion, Zeilennummer und Kontextzeile erzeugt:
#Loop through every item on the omnis stack For sys192List.$line from 1 to sys192List.$linecount step 1 Set reference class to sys192List.classitem Calculate className as class.$name # Create the content row Do contentRow.$define(vars,function,pre_context,context_line,lineno,filename,post_context) Calculate contentRow.lineno as sys192List.line Calculate contentRow.filename as testFileName Calculate contentRow.context_line as sys192List.linetext If isclear(sys192List.object) Calculate contentRow.function as con(className,'.',sys192List.method) ## If it's a class method Else Calculate contentRow.function as con(className,'.',sys192List.object,'.',sys192List.method) ## If it's a method of an object of a class (e.g. Headedlist) End If Do contentList.$add(contentRow) End For
Variablen aufnehmen
Pro Stackframe werden Instance Variablen und Parameter gesammelt:
# Get all iVars
Do varList.$define(name,value)
Set reference class to sys192List.inst
Do $cinst.$getVars('ivars',class) Returns varList
# Get all params
Calculate paramList as sys192List.params
For paramList.$line from 1 to paramList.$linecount step 1
If not(paramList.value='(Not empty)')
Do varList.$add(paramList.name,paramList.value)
Else
Do varList.$add(paramList.name,'(Not empty)')
End If
End For
Pre- und Post-Context
OSentry fügt Methodenzeilen vor und nach der aktuellen Zeile hinzu:
# Pre Context (all method lines before the error occured) Set reference method to sys192List.methoditem Do precontextList.$define(line) For i from 1 to sys192List.line-1 step 1 Do precontextList.$add(method.$methodlines.[i].$text) End For # Post Context (all method lines after the error occured Do postcontextList.$define(line) For i from sys192List.line+1 to method.$methodlines.$count step 1 Do postcontextList.$add(method.$methodlines.[i].$text) End For
Variablentypen
OSentry.$getVars unterstützt Basisvariablen, Rows und Lists.
Basisvariablen:
If varType='char'|varType='boolean'|varType='integer'|varType='number'|varType='date' Calculate varContent as pItemRef.$[pVarType].[varName] Do varList.$add(varName,varContent)
Rows:
Else If varType='row' Calculate varRow as pItemRef.$[pVarType].[varName] If varRow.$colcount=0 Do varList.$add(varName,'(Empty)') Else For Z2 from 1 to varRow.$colcount step 1 Calculate varContent as con(varContent,varRow.$cols.[Z2].$name,': ',varRow.[Z2],', ') End For Do varList.$add(varName,varContent)
Lists:
Else If varType='list'
Calculate varListType as pItemRef.$[pVarType].[varName]
Calculate varContent as con('Colcount: ',varListType.$colcount,', ','Linecount: ',varListType.$linecount,', ','Current Line: ',varListType.$line)
If varListType.$linecount=0&varListType.$line=0&varListType.$colcount=0
Do varList.$add(varName,'(Empty)')
Calculate varContent as ''
Else
For Z3 from 1 to varListType.$colcount step 1
Calculate colName as varListType.$cols.[Z3].$name
Calculate varContent as con(varContent,' ',colName,': ',varListType.[colName])
End For
Do varList.$add(varName,varContent)
Calculate varContent as ''
End If
End If
Hinweise
Stacktrace und Variablenkontext sind sehr hilfreich, können aber sensible Daten enthalten. Vor produktiver Nutzung sollte geprüft werden, ob bestimmte Variablen anonymisiert oder ausgeschlossen werden müssen.
Interne Architektur
Diese Seite beschreibt die produktiv relevanten Klassen OSentryHL und OSentry.
Klassenübersicht
| Klasse | Rolle |
|---|---|
OSentryHL |
High-Level-Adapter für Applikationscode |
OSentry |
Low-Level-Adapter für JSON, Stacktrace und HTTP |
Startup_Task |
Demo-Startup und Beispiel für Initialisierung |
FSY_Demo |
Demo-Fenster |
ODummy |
Demo-Code für Stacktrace-Beispiel |
ODatabaseHandler |
Demo-DB Initialisierung |
OSLSession |
SQLite Session für Demo |
Empfohlener Aufrufweg
Applikationscode sollte OSentryHL verwenden:
Do tSentry.$captureException('A generic Exception occured',1234,'Generic Exception','error')
OSentryHL delegiert anschließend an OSentry:
Do iOSentry.$captureException(pErrorText,pErrorCode,pExcType,pLevel) Returns code
Ablauf eines Events
- Applikationscode ruft Methode in
OSentryHLauf. OSentryHLfügt bei Bedarf Tags und Extras hinzu.OSentryHLruftiOSentry.$captureException(...)auf.OSentryprüft, ob Sentry aktiv ist.OSentryerzeugt JSON.- Stacktrace, Exception Interface und User Interface werden optional ergänzt.
- HTTP Header und Sentry Auth Header werden erstellt.
- JSON wird per HTTPS an Sentry gesendet.
- Bei Erfolg werden Tags und Extras geleert.
- Bei Fehler wird der JSON Report lokal gespeichert.
DSN Parsing
OSentry.$init zerlegt die DSN:
# Parse the DSN into Public Key, Host and Project ID
If len(pDSN)>5
Calculate iDSN as pDSN
Calculate part1 as strtok('iDSN','@')
Calculate iProtocol as strtok('part1','/')
Calculate iProtocol as left(iProtocol,len(iProtocol)-1)
Do strtok('part1','/')
Calculate iPubKey as strtok('part1',':')
Calculate iHost as strtok('iDSN','/')
Calculate iProID as iDSN
#Save the values for the next startup
Calculate $cclass.$ivardefs.iPubKey.$objinitval as con('"',iPubKey,'"')
Calculate $cclass.$ivardefs.iHost.$objinitval as con('"',iHost,'"')
Calculate $cclass.$ivardefs.iProID.$objinitval as con('"',iProID,'"')
End If
Quit method
JSON-Erzeugung
OSentry.$generateJson ist die zentrale Methode für den Payload. Sie setzt unter anderem:
event_idloggerplatformculprittimestampsdkmessageleveltagsextra- optional
user - optional
exception - optional
stacktrace
Auszug:
# Add all required fields (those are required from the API)
Do JSON.$addmember('','event_id',$cinst.$generateUUID()) ## auto generated UUID 4
Do JSON.$addmember('','logger',logger)
Do JSON.$addmember('','platform',platform)
Do JSON.$addmember('','culprit',culprit)
#Do JSON.$addmember('','release',release)
Do JSON.$addmember('','timestamp',timestamp)
Do JSON.$addmember('','sdk','')
Do JSON.$addmember('','message',pErrorText)
Do JSON.$addmember('','level',pLevel)
Do JSON.$addmember('','tags','')
HTTP-Kommunikation
OSentry.$captureException sendet den erzeugten JSON-Payload an Sentry:
#Generate HTTP Auth header
Begin text block
Text:Sentry sentry_version=7,
Text:sentry_timestamp=[$cinst.$getUnixTimestamp()],
Text:sentry_key=[iPubKey],
Text:sentry_client=omnis/1.0
End text block
Get text block auth
#Generate header list
Calculate Host as 'sentry.io'
Calculate Url as con('/api/',iProID,'/store/')
Do HdrList.$define(wert,name)
Do HdrList.$add('User-Agent','omnis/1.0')
Do HdrList.$add('Content-Type','application/json')
Do HdrList.$add('Content-Length',binlength(json))
Do HdrList.$add('X-Sentry-Auth',auth)
Anschließend wird der Request über HTTPPost, HTTPSend und HTTPRead ausgeführt.
Fehlerbehandlung beim Senden
Wenn der Socket nicht geöffnet werden kann:
HTTPPost (Host,Url,,HdrList,443,kTrue,kTrue) Returns Socket
If Socket<0
#Error when opening connection -> save json as a file
Do $cinst.$writeJSON(iJSON,con('Error ',Socket,' when performing HTTPPost'))
Do $cinst.$clearList()
HTTPClose (Socket)
Quit method -1
End If
Wenn das Senden fehlschlägt:
HTTPSend (Socket,json) Returns byteCount
If byteCount<0
# Error while sending data -> save json as a file
Do $cinst.$writeJSON(iJSON,con('Erorr ',byteCount,' when performing HTTPSend'))
Do $cinst.$clearList()
HTTPClose (Socket)
Quit method -2
End If
Wenn die Antwort nicht erfolgreich ist:
HTTPRead (Socket,Buffer) Returns byteCount
If byteCount<0|not(pos('200 OK',Buffer))
# JSON may be corrupted or contains errors -> save json and the buffer as a file
Do $cinst.$writeJSON(iJSON,Buffer)
Do $cinst.$clearList()
HTTPClose (Socket)
Quit method -3
End If
Lokales Speichern
Bei Fehlern wird der JSON Report lokal im Omnis-Installationsordner gespeichert:
#Writes the json and the http buffer to a file in the omnis installation folder
Calculate path as sys(115)
Calculate filename as con('Sentryreport_',$cinst.$getUnixTimestamp(),'.json')
Do fOP.$createfile(con(path,filename)) Returns err
Do fOP.$writecharacter(kUniTypeUTF8,pJSON) Returns err
If not(isclear(pBuffer))
Do fOP.$writecharacter(kUniTypeUTF8,con(kCr,pBuffer),kTrue) Returns err
End If
Do fOP.$closefile()
Quit method
Cleanup
Nach erfolgreichem Senden werden Tags und Extras gelöscht:
#Clears all extras and tags => to be used after a sentry request has successfully been sent Do iTagList.$clear() Do iExtraList.$clear() Quit method
Demo Library
Die Demo-Library zeigt, wie OSentry initialisiert wird und wie verschiedene Event-Typen aus einer Omnis-Oberfläche heraus an Sentry gesendet werden.
Bestandteile
| Klasse | Zweck |
|---|---|
Startup_Task |
Initialisiert Sentry, SQLite und öffnet das Demo-Fenster |
FSY_Demo |
Demo-Fenster |
ODummy |
Erzeugt Demo-Stack für Exception |
ODatabaseHandler |
Erstellt SQLite-Demo-Datenbank |
OSLSession |
SQLite Session |
OSentry |
Low-Level-Sentry-Adapter |
OSentryHL |
High-Level-Sentry-Adapter |
Startup
Startup_Task.$construct initialisiert Sentry, baut eine SQLite Session auf und öffnet das Demo-Fenster. Quelle: Startup_Task.$construct.
#Init Sentry on lbs startup
Do tSentry.$init()
#SQLite Session init
Do $objects.OSLSession.$newref() Returns tOSLSession
#Calculate tOSLSession.$opencreate as kTrue
Calculate workingDir as tODatabaseHandler.$getWorkingDir()
Do con(workingDir,'Sentry_Test.db') Returns dbLocation
Do tOSLSession.$logon(dbLocation,'','','slsession') Returns #F
#Open Test Window
Do $windows.FSY_Demo.$openonce('*')
Quit method
Demo-Fenster
FSY_Demo enthält folgende Bereiche:
- DSN Configuration
- DB Status
- Actions
Wichtige Felder:
| Feld | Datenanbindung |
|---|---|
| DSN | iDSN
|
| Host | tSentry.iOSentry.iHost
|
| Public Key | tSentry.iOSentry.iPubKey
|
| Project ID | tSentry.iOSentry.iProID
|
| DB Status | iCurrentDBStatus
|
Demo-Fenster der OSentry Library
DSN setzen
Die DSN wird im Feld iDSN erfasst. Der Button Set DSN ruft anschließend tSentry.$init(iDSN) auf. Nach dem Setzen werden Public Key, Host und Project ID aus der DSN gelesen und in den darunterliegenden Feldern angezeigt.
DSN-Konfiguration im Demo-Fenster
Der Button Set DSN initialisiert Sentry mit der eingegebenen DSN. Quelle: FSY_Demo.setDSN.$event.
On evClick ## Event Parameters - pRow( Itemreference )
Do tSentry.$init(iDSN)
Calculate $cclass.$ivardefs.iDSN.$objinitval as con(kSq,iDSN,kSq)
Do $cinst.$showmessage('DSN set and Sentry initialized!','Info')
Do $cinst.$redraw()
Quit method
DB Status anzeigen
FSY_Demo.$displayDBState zeigt, ob die SQLite Session verbunden ist. Quelle: FSY_Demo.$displayDBState.
Do tOSLSession.$state Returns dbState If dbState='kSessionStateLoggedOff' Calculate iCurrentDBStatus as 'Logged Off' Else If dbState='kSessionStateLoggedOn' Calculate iCurrentDBStatus as 'Logged On' Else Calculate iCurrentDBStatus as 'Unkown DB State' End If Do $cinst.$redraw() Quit method
Demo-Datenbank erstellen
Der Button Create Database ruft ODatabaseHandler.$DBFirstInit auf. Quelle: FSY_Demo.createDB.$event.
On evClick ## Event Parameters - pRow( Itemreference )
#Setup the DB
Do tODatabaseHandler.$DBFirstInit() Returns err
If err=0
Do $cinst.$showmessage('DB successfully created!','Info')
Else
Do $cinst.$showmessage('Error while creating the DB. Make sure that the DB does not already exist.','Info')
End If
Do $cinst.$displayDBState()
Quit method
Die Datenbank wird im Arbeitsverzeichnis der Library angelegt. Quelle: ODatabaseHandler.$getWorkingDir.
Quit method con(FileOps.$parentdir($clib.$pathname),pathsep())
Die Demo-DB enthält unter anderem:
dpersondreleasedvcs
Message auslösen
Button Trigger a message. Quelle: FSY_Demo.message.$event.
On evClick ## Event Parameters - pRow( Itemreference )
Do tSentry.$captureMessage('Hello Euromnis! This is a test message...')
Do $cinst.$showmessage('Sentry Event successfully triggered!','Info')
Quit method
Log auslösen
Button Trigger a log. Quelle: FSY_Demo.log.$event.
On evClick ## Event Parameters - pRow( Itemreference )
Do tSentry.$captureLog('Uh oh this is a Log because something went wrong')
Do $cinst.$showmessage('Sentry Event successfully triggered!','Info')
Quit method
Exception auslösen
Button Trigger an exception bereitet eine Row und eine List vor und ruft anschließend ODummy.$dummyMethod auf. Quelle: FSY_Demo.exception.$event.
On evClick ## Event Parameters - pRow( Itemreference )
Do iDummyRow.$define(id,name)
Calculate iDummyRow.id as 22
Calculate iDummyRow.name as 'Tom'
Do iDummyList.$define(id,weekday)
Do iDummyList.$add(1,'Monday')
Do iDummyList.$add(2,'Tuesday')
Do iDummyList.$add(3,'Wednesday')
Do iDummyList.$add(4,'Thursday')
Do iDummyList.$add(5,'Friday')
Do iDummyList.$add(6,'Saturday')
Do iDummyList.$add(7,'Sunday')
Calculate iDummyList.$line as 5
Do iODummy.$dummyMethod('Important Value')
Do $cinst.$showmessage('Sentry Event successfully triggered!','Info')
Quit method
ODummy.$dummyMethod sendet die Exception. Quelle: ODummy.$dummyMethod.
#In here is some logic
#This logic would produce an error
#We send all this information to Sentry
Do tSentry.$captureException('A generic Exception occured',1234,'Generic Exception','error')
Quit method 0
Deprecated Call auslösen
Button Trigger a deprecated call. Quelle: FSY_Demo.deprecatedCall.$event.
On evClick ## Event Parameters - pRow( Itemreference )
Do tSentry.$captureDeprecatedCall()
Do $cinst.$showmessage('Sentry Event successfully triggered!','Info')
Quit method
SQL Exception Button
Der Button Trigger an SQLException ist im Export vorhanden, enthält aber noch keinen fertigen Demo-Code. Quelle: FSY_Demo.sqlException.$event.
On evClick ## Event Parameters - pRow( Itemreference ) #Code need's to be written
Für die Dokumentation der SQL-Erfassung siehe 03 Events erfassen.
API Reference
Diese Seite dokumentiert die produktiv relevanten Methoden von OSentryHL und OSentry.
OSentryHL
OSentryHL ist die empfohlene Klasse für Applikationscode.
$init(pDSN)
Initialisiert das interne OSentry-Objekt.
#Init of the main sentry object Do iOSentry.$init(pDSN) Quit method
$captureMessage(pMessage)
Sendet eine einfache Info-Message.
# Captures an Info Message Do iOSentry.$captureException(pMessage,3,,'info',kFalse,,kFalse) Returns code Quit method
$captureException(pErrorText,pErrorCode,pExcType,pLevel)
Sendet eine generische Exception.
# Method to capture a generic Exception
#Add any custom tags / extras
Do $cinst.$addTag('Custom Test Tag','Euromnis')
Do iOSentry.$captureException(pErrorText,pErrorCode,pExcType,pLevel) Returns code
Quit method
$captureAnything(pErrorText,pErrorCode,pExcType,pLevel,pStacktraveInterface,pExceptionInterface,pUserInterface)
Sendet ein frei konfigurierbares Event.
# Capture a generic Sentry Report (max configurability) Do iOSentry.$captureException(pErrorText,pErrorCode,pExcType,pLevel,pStacktraveInterface,pExceptionInterface,pUserInterface) Returns code Quit method
Hinweis: Der Parameter ist im Export als pStacktraveInterface geschrieben.
$captureLog(pErrorText)
Sendet ein Log-Event.
# Captures a Log Sentry Report Do iOSentry.$captureException(pErrorText,1,'Log','warning',1,0,1) Returns code Quit method
$captureDeprecatedCall()
Meldet die Ausführung eines veralteten Codepfads.
# Report a deprecated call of a piece of code to sentry
Do iOSentry.$captureException('Deprecated Call',3,'Deprecated Call','warning',1,1,1) Returns code
Quit method
$captureSQLException(pErrorText,pStat)
Meldet einen SQL-Fehler mit SQL-Text und nativer Datenbankfehlermeldung.
# Method to capture an SQL Exception
Do $cinst.$addTag('Database',tOSLSession.$hostname)
Do $cinst.$addExtra('SQL-Text',pStat.$sqltext)
Do $cinst.$addExtra('SQL-Error',pStat.$nativeerrortext)
Do iOSentry.$captureException(pErrorText,1,'SQL-Exception','error')
Quit method
$addTag(pName,pValue)
Fügt einen Tag für das nächste Event hinzu.
# Add a Tag to the next Sentry Report Do iOSentry.$addTag(pName,pValue) Quit method
$addExtra(pName,pValue)
Fügt ein Extra für das nächste Event hinzu.
# Add an Extra to the next Sentry Report Do iOSentry.$addExtra(pName,pValue) Quit method
$setStatus(pStatus)
Aktiviert oder deaktiviert Sentry.
#Toggels Sentry on or off Do iOSentry.$setStatus(pStatus) Quit method
$setUser()
Setzt im Export feste Demo-Userdaten.
# Set the User which should be linked to the Sentry Issue Do iOSentry.$setUserData(23,'Euromnis Test User','euromnis@test.com') Quit method
Für produktive Nutzung sollte diese Methode parametrisiert werden.
OSentry
OSentry ist die Low-Level-Klasse für Payload-Erzeugung und Versand.
$init(pDSN)
Parst die DSN in Protokoll, Public Key, Host und Project ID.
$captureException(pErrorText,pErrorCode,pExcType,pLevel,pStacktraceInterface,pUserInterface,pExceptionInterface)
Erzeugt JSON, sendet es an Sentry und behandelt Fehlerfälle.
Parameter:
| Parameter | Default | Bedeutung |
|---|---|---|
pErrorText |
Message | |
pErrorCode |
Fehlercode | |
pExcType |
Exception-Typ | |
pLevel |
fatal, error, warning, info, debug
| |
pStacktraceInterface |
kTrue |
Stacktrace senden |
pUserInterface |
kTrue |
User-Kontext senden |
pExceptionInterface |
kTrue |
Exception Interface senden |
$generateJson(...)
Erzeugt den Sentry JSON Payload als Binary.
$generateStacktraceInterface(pCulprit)
Erzeugt den Omnis-Stacktrace inklusive Variablen und Kontextzeilen.
$generateExceptionInterface(pType,pValue)
Erzeugt das Sentry Exception Interface.
# Generate Row to store in the JSON Do exceptionRow.$define(type,value,stacktrace) Calculate exceptionRow.type as pType Calculate exceptionRow.value as pValue Calculate exceptionRow.stacktrace as 'sentry.interfaces.stacktrace' ## Tells the exception interface that a stacktrace is passed aswell
$generateUserInterface()
Erzeugt den User-Kontext.
$addTag(pName,pValue)
Fügt einen Tag zur internen Tag-Liste hinzu.
$addExtra(pName,pValue)
Fügt ein Extra zur internen Extra-Liste hinzu.
$clearList()
Leert Tags und Extras nach einem Request.
$setUserData(pID,pName,pEmail)
Setzt Userdaten für den nächsten Request.
$setProxy(pProxyHost,pProxyPort)
Setzt Proxy-Informationen.
$setStatus(pStatus)
Setzt den Sentry-Status.
#Toggels Sentry Reports on or off Calculate iStatus as pStatus Quit method
$writeJSON(pJSON,pBuffer)
Schreibt fehlgeschlagene Reports lokal in eine Datei.
$getUnixTimestamp()
Gibt den aktuellen UNIX Timestamp zurück.
$generateUUID()
Erzeugt eine UUID für die Sentry Event ID.
#Genereates a UUID for the issue id Quit method OW3.$makeuuid(kFalse)
Troubleshooting
Es erscheinen keine Events in Sentry
Prüfe zuerst, ob Sentry aktiv ist:
Do tSentry.$setStatus(1)
OSentry.$captureException beendet sich sofort, wenn der Status 0 oder leer ist:
#Check if Sentry is enabled If iStatus=0|isclear(iStatus) Quit method 0 End If
Die DSN ist falsch
Prüfe, ob die DSN korrekt aus Sentry kopiert wurde. OSentry.$init erwartet eine DSN, aus der Public Key, Host und Project ID gelesen werden können.
Nach dem Setzen der DSN sollten in der Demo-Library folgende Felder gefüllt sein:
- Host
- Public Key
- Project ID
Netzwerk oder Proxy blockiert den Request
Wenn die Anwendung keinen direkten Zugriff auf Sentry hat, setze einen Proxy:
Do tSentry.iOSentry.$setProxy('proxy.example.local','8080')
Intern wird der Proxy vor dem HTTP Request gesetzt:
If not(isclear(iProxyHost))¬(isclear(iProxyPort)) HTTPSetProxyServer (iProxyHost,iProxyPort) End If
Report wird lokal gespeichert
Wenn HTTPPost, HTTPSend oder HTTPRead fehlschlägt, speichert OSentry den Report lokal:
Calculate path as sys(115)
Calculate filename as con('Sentryreport_',$cinst.$getUnixTimestamp(),'.json')
Do fOP.$createfile(con(path,filename)) Returns err
Suche im Omnis-Installationsordner nach Dateien mit dem Namen:
Sentryreport_<timestamp>.json
Sentry antwortet nicht mit 200 OK
Wenn die HTTP-Antwort kein 200 OK enthält, wird der JSON Report ebenfalls lokal gespeichert:
HTTPRead (Socket,Buffer) Returns byteCount
If byteCount<0|not(pos('200 OK',Buffer))
# JSON may be corrupted or contains errors -> save json and the buffer as a file
Do $cinst.$writeJSON(iJSON,Buffer)
Do $cinst.$clearList()
HTTPClose (Socket)
Quit method -3
End If
Mögliche Ursachen:
- falsche Project ID
- falscher Public Key
- ungültige DSN
- JSON Payload wird von Sentry abgelehnt
- Netzwerk-Gateway verändert den Request
Tags oder Extras erscheinen beim falschen Event
Tags und Extras werden für den nächsten Request gesammelt. Nach erfolgreichem Request werden sie gelöscht:
Do iTagList.$clear() Do iExtraList.$clear()
Wenn ein Request fehlschlägt, wird ebenfalls aufgeräumt:
Do $cinst.$clearList()
Prüfe trotzdem, ob in eigenen Wrapper-Methoden Tags und Extras direkt vor dem passenden Capture-Aufruf gesetzt werden.
User-Kontext zeigt Demo-Daten
OSentryHL.$setUser verwendet im Export feste Testdaten:
Do iOSentry.$setUserData(23,'Euromnis Test User','euromnis@test.com')
Für produktive Nutzung sollte die Methode parametrisiert werden:
Do iOSentry.$setUserData(pUserID,pUserName,pUserEmail)
SQL Exception Demo-Button funktioniert nicht
Der Button Trigger an SQLException ist im Export noch nicht implementiert:
On evClick ## Event Parameters - pRow( Itemreference ) #Code need's to be written
Die produktive Methode für SQL-Fehler ist aber vorhanden. Siehe auch Events erfassen.
Do tSentry.$captureSQLException('SQL statement failed',stat)
Zu viele Events
Sentry kann sehr schnell viele Events sammeln. Verwende für produktive Systeme:
- klare Wrapper-Methoden in
OSentryHL - sinnvolle Levels
- gezielte Tags
- keine Events in sehr häufigen Schleifen
- keine rein informativen Debug-Events ohne Nutzen
Sensible Daten
Stacktrace, Parameter, Instance Variablen, SQL-Text und Extras können sensible Daten enthalten. Prüfe vor produktiver Nutzung:
- Welche Variablen werden übertragen?
- Enthalten SQL-Statements personenbezogene Daten?
- Werden Tokens oder Passwörter in Extras geschrieben?
- Sollen bestimmte Werte maskiert werden?