C# fragen zu logger

Rooky420

Cadet 4th Year
Registriert
Nov. 2015
Beiträge
98
Hallo zusammen,

ich will mir als kleines freizeitprojekt einen logger schreiben den ich am besten überall einbauen kann.
Hierzu habe ich noch fragen:
1) Wie macht man es am besten bzgl. Logstreams d.h. wenn der logger beispielsweise in eine datenbank oder in eine textdatei loggen kann. Lässt man den stream zur datenbank/datei immer offen oder öffnet man den stream jedes mal neu beim schreiben? Oder macht man es mit einer zwischenlösung in der man beispielsweise ein eine zeit definiert z.B. 5 sekunden nachdem der stream geschlossen wird wenn nichts geschrieben wurde? ich finde alle 3 möglichkeiten irgendwie schlecht hat jemand eine gute lösung für das?
2) Ich habe gesehen dass moderne logger die option anbieten die logdatei verschlüsselt zu speichern. Wie bzw. wann verschlüsselt man das am besten? soll ich jede zeile die ich hinzufüge verschlüsseln oder die ganze datei lesen, die zeile hinzufügen, die ganze datei verschlüsseln und dann wieder abspeichern? Hier weiß ich auch nicht wirklich wie man es am "professionellsten" löst.

Grüße,
Rooky420
 
Rooky420 schrieb:
ich finde alle 3 möglichkeiten irgendwie schlecht
na wie sieht denn deine pro-/contra matrix aus?

meine meinung zu 1.: es ist denke ich zu erwarten, dass ein programm waehrend seiner laufzeit ein handle auf die logdatei bzw. eine datenbankverbindung aufrecht erhaelt.

sinnvollerweise kannst du dir auch ueberlegen, wie die grenzfaelle fuer den einsatz in sachen durchsatz aussehen.
nennen wir deine drei varianten mal bedarf, permanent, timeout. dann:

hoher durchsatz: bedarf => produziert sehr viel overhead. permanent => kein overhead. timeout => verhaelt sich wie permanent
geringer durchsatz: bedarf => gibt zugriff auf datei auf. ist das ein gewinn? permanent => behaelt dateizugriff. timeout => wie bedarf

im falle regelmaessiger fataler abstuerze wuerde die bedarfsvariante z.B. mehr sinn ergeben, da dann nicht etwaig gepufferte schreibvorgaenge verloren gehen (falls das in C# so funktioniert wie in java - keine ahnung, sorry).

wenn du lustig drauf bist, implementier einfach alle drei; je nach situation und logdurchsatz ergeben sie irgendwo alle sinn.

zu 2.: das kommt wohl auf die cipher und die art und weise, wie du spaeter auslesen willst an. manche ciphers kannst du als stream schreiben, bei anderen kriegst du vielleicht probleme, hunderte von kilobytes an logdaten staendig zu schreiben und zu verschluesseln.
 
Zu Frage 2: Krypto selber basteln endet garantiert katastrophal. Daran sind schon viel Klügere Leute, als der durchschnittliche CB-User gescheitert. Lass es!
 
Er will doch gar keine Verschlüsselung basteln?!

Lässt man den stream zur datenbank/datei immer offen oder öffnet man den stream jedes mal neu beim schreiben?
​Wieso solltest du ihn nicht offen lassen? Du hättest sonst bei jedem Loggen den Overhead des Verbindungsaufbaus und -abbaus.
​Also sofern möglich, würde ich die Verbindung schon offen lassen.

​Anders sieht es natürlich aus, wenn der Konnektor/File Writer buffern würde und man keine Möglichkeit hat den Buffer rauszuschreiben ohne die Verbindung zu schließen.
​In diesem Fall würde ich es zumindest erwägen die Verbindung zu schließen um nicht ggf. Logeinträge zu verlieren (wohl die wichtigsten).

​Nach 5 Sekunden disconnecten ist mMn i.d.R. sinnlos, da ein offener FileWriter oder ne Datenbankverbindung dir wohl kaum Performanceeinbußen bringen wird. Unnötiger Aufwand.
 
The Ripper schrieb:
​Wieso solltest du ihn nicht offen lassen? Du hättest sonst bei jedem Loggen den Overhead des Verbindungsaufbaus und -abbaus.
​Also sofern möglich, würde ich die Verbindung schon offen lassen.
Bei .Net ist es gängige Praxis, die Verbindung nur zu öffnen, wenn sie auch tatsächlich benötigt wird. Die Verbindung wird im Hintergrund von .Net verwaltet, d.h. obwohl du sie schließt, kann .Net sie immer noch für die nächste Verbindung offen halten.
 
Auszug aus Improving ADO.NET Performance:
Too many open connections. Connections are an expensive and scarce resource, which should be shared between callers by using connection pooling. Opening a connection for each caller limits scalability. To ensure the efficient use of connection pooling, avoid keeping connections open and avoid varying connection strings.
Failure to release resources. Failing to release resources can prevent them from being reused efficiently. If you fail to close connections before the connections fall out of scope, they are not reclaimed until garbage collection occurs for the connection. Failing to release resources can cause serious resource pressure and lead to shortages and timeouts.
und
Acquire connections late and release them early. Opening connections before they are needed reduces the number of connections that are available and increases resource pressure. Close connections quickly to ensure that they can be reused as soon as possible. Do not hold on to connections. Holding on to connections reduces the connections that are available to other code and increases resource pressure. The general pattern is to open and close connections on a per-method basis.
 
Ja okay, falls man ein Framework benutzt, dass intern einen Pool von Connections verwaltet (wie ADO.NET: https://msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.110).aspx), dann halte ich das für sinnvoll - sogar für empfehlenswert.

Aber ich würde das nicht empfehlen, wenn man wirklich explizit eine Verbindung herstellt und wieder schließt, oder wenn man sich eine Verbindung reserviert, die vielleicht, vielleich auch nicht geschlossen wird - wie ich hier vermutet habe:
Die Verbindung wird im Hintergrund von .Net verwaltet, d.h. obwohl du sie schließt, kann .Net sie immer noch für die nächste Verbindung offen halten.

​Fazit: Im Prinzip sind sollte man also trotzdem immer eine Verbindung zur DB offen halten (sei es explizit, oder implizit durch das verwendete Framework), statt die Verbindung bei jedem Logeintrag (welche Wahrscheinlich nicht allzu selten gemacht wird) eine neue Verbindung herzustellen und wieder zu schließen.
 
Zurück
Oben