Logfile ohne Overhead
-
wow, hier geht's ja ab.
Interessantes Thema... Danke für die zahlreichen Antworten, scheint doch ein nicht ganz einfaches Thema zu sein.Würden sich alle an die Konvention halten, gäbe es viel seltener Probleme.
Gibt's diese Konvention irgendwo im Internet zum Nachlesen? Ich mache das nämlich auch (mehr oder weniger) frei Schnauze (und ja, ich weiß, dass das nicht gerade toll ist).

Grundsätzlich sollte einmal öffnen vollkommen ausreichen. Bei einem Absturz sollte das Betriebssystem zusehen, dass die Resourcen wieder freigegeben werden. Letztendlich kann man das mit Exception aber in den meisten Fällen dank der Destruktoren sogar selber erledigen.
Ich meinte damit eher, ob die Schreibzugriffe nicht mal durch einen Absturz verloren gehen könnten und dann die Message nicht im Log steht...
Kann sowas passieren oder sind diese ungepuffert? (dachte sie wären gepuffert)
Oder müsste man jedes mal ein flush nach dem Schreibzugriff einfügen?
-
Es gibt ungepufferte Streams.
std:cerrgehört z.B. dazu. Ergibt ja auch wie du richtig feststellst bei Log-Streams durchaus Sinn.
-
Ok, das löst das Problem natürlich... Vielen Dank

-
</Exit> schrieb:
Würden sich alle an die Konvention halten, gäbe es viel seltener Probleme.
Gibt's diese Konvention irgendwo im Internet zum Nachlesen? Ich mache das nämlich auch (mehr oder weniger) frei Schnauze (und ja, ich weiß, dass das nicht gerade toll ist).

Tja, den ersten Teil (Makros groß schreiben) findet man ganz klar, z.B. hier http://www.possibility.com/Cpp/CppCodingStandard.html (war die erste Seite die ich gefunden habe, über die Qualität kann ich nichts sagen).
Der zweite Teil (alles andere nicht komplett groß schreiben) folgt aus der Tatsache, dass man Kollisionen vermeiden will.
Lars
-
CSpille schrieb:
Ich bevorzuge dann aber
#ifdef DEBUG inline void debug(const std::string & debugMessage){ std::cout << debugMessage << std::endl; } #else inline void debug(const std::string & /*debugMessage*/){} #endifIch bevorzuge lieber:
namespace hidden { inline void debug(string const& file, string const& line, string const& function, string const& message) { out << function <<"@"<<file<<":"<<line<<" -> "<<message<<endl; } } #ifdef DEBUG #define DBG_OUT(msg) ((void)::hidden::debug(__FILE__, BOOST_STRINGIZE(__LINE__), BOOST_PRETTY_FUNCTION, (msg))) #else #define DBG_OUT(msg) ((void)0) #endif
-
Aber die __LINE__ vor der Ausgabe erst zum string zu machen, tut dem volkardchen weh.
Der Cast nach void des Ergebnisses von hidden::debug bewirkt gar nichts, oder?
-
volkard schrieb:
Aber die __LINE__ vor der Ausgabe erst zum string zu machen, tut dem volkardchen weh.
Kommt darauf an was man machen will. Hier ist die Umwandlung nicht notwendig und generell wären char const* wohl auch besser als string const&. Ich hab aber gerne line als String weil die Umwandlung gratis ist und man sich leichter tut das ganze in nicht c++ Streams reinzupacken.
Aber klar, __LINE__ kann man auch getrost so lassen wie es ist, das würde mich auch kein bisschen stören.
Der Cast nach void des Ergebnisses von hidden::debug bewirkt gar nichts, oder?
Jetzt wo du es sagst, ja.
-
Shade Of Mine schrieb:
Ich bevorzuge lieber:
namespace hidden { inline void debug(string const& file, string const& line, string const& function, string const& message) { out << function <<"@"<<file<<":"<<line<<" -> "<<message<<endl; } } #ifdef DEBUG #define DBG_OUT(msg) ((void)::hidden::debug(__FILE__, BOOST_STRINGIZE(__LINE__), BOOST_PRETTY_FUNCTION, (msg))) #else #define DBG_OUT(msg) ((void)0) #endifZu welchem Boost - Teil gehört BOOST_STRINGIZE und BOOST_PRETTY_FUNCTION? Google findet dazu nur diesen Thread.
-
Hi,
vielleicht könnte mir noch mal jemand helfen... Ich bekomme einen "mutliple definition of _instance" Error:
Logfile.hpp
class Logfile{ public: //Singleton Design Pattern static Logfile* getLogfile(); static Logfile* getLogfile(string name, bool append = false, unsigned long size = 4096); void closeLogfile(); inline void writeToLog(string message, const unsigned int loglevel){...} private: //for Singleton Logfile(); Logfile(const Logfile&); Logfile& operator=(const Logfile&); //for functionality Logfile(string name, bool append = true, unsigned long size = 4096); ~Logfile(); static Logfile* _instance; //... }; Logfile* Logfile::_instance = NULL;Sonst wird _instance nirgendwo angesprochen... (außer natürlich in getLogfile)
Logfile.cpp
Logfile* Logfile::getLogfile(){ //Singleton return _instance == NULL ? _instance = new Logfile("Logfile.txt") : _instance; }
-
...
-
Danke, allerdings bleibt der Fehler...

-
include guards hast du?!
Logfile* Logfile::getLogfile(){ //Singleton return _instance == NULL ? _instance = new Logfile("Logfile.txt") : _instance; }hmm.. bäh! : D
Logfile* Logfile::getLogfile() { if(_instance == NULL) _instance = new Logfile("Logfile.txt"); return _instance; }wenn man es andersrum schreibt und 2x auf NULL prüft, hat man es so gar thread-safe:
Logfile* Logfile::getLogfile() { if(_instance != NULL) return _instance; if(_instance == NULL) _instance = new Logfile("Logfile.txt"); return _instance; }da gabs mal irgendwo hier nen schönen link (mit ner sehr ausführlichen beschreibung zu diesem problem), allerdings hab ich den nicht mehr - vll weiß ja jmd anders, was ich meine und hat ihn noch und postet ihn...
bb
-
...
-
jo, natürlich noch nen lock zwischen die beiden ifs... ^^
-
...
-
Ja, ok mit if's sieht es echt schöner aus... Include Guards hab ich natürlich auch
(allerdings nicht gepostet)Thread-safe ist schon mal nicht schlecht... Darüber hab ich mir schon gedanken gemacht. Thanks!
EDIT:
der Fehler hat sich jetzt geändert... Zwar immer noch multiple definition of _instance, aber jetzt im .cpp-File!
(außerdem hab ich noch "first defined here" im main-File)Schätzungsweise ist es dann diese Zeile:
//init Logfile* Logfile::_instance = NULL;Wo muss die genau hin? Ich hab sie einfach ganz oben (nach includes/using) direkt ins .cpp-File rein (ohne Funktion drum herum oder sowas)
EDIT2:
ja, wenn ich die Zeile auskommentiere compiliert und linkt er es richtig und ohne Fehler. (allerdings wird die Ausführung fraglich)
-
...
-
Nein, ich weiß, dass man sowas auf keinen Fall machen sollte

Das komische ist auch, dass ich 3 Arten von "Fehlern" habe und bei jedem mal clean/build springt der hin und her:
1. multiple definition of _instance
2. undefined reference to _instance (bei allen _instance im .cpp)
3. es funktioniert (hä!?) - ja!Strange...
-
</Exit> schrieb:
Das komische ist auch, dass ich 3 Arten von "Fehlern" habe und bei jedem mal clean/build springt der hin und her
Das kann nicht sein. Nach jedem clean/build muß die Reaktion gleich sein.
Riecht nach Compiler-Ist-Kaputt. Falls Du Microsoft verwendest, lösch (während die IDE nicht auf ist) die *.ncb.
-
Soviel Diskussion um ein so altes Thema der Programmierung?

Kann jeder machen wie er will. Präprozessor-Anweisungen an den Compiler sind schon mal gut, aber im Quelltext aufwendig. Auskommentieren der Logfile-Einträge kann ohne Overhead sehr nützlich sein und lässt sich später jederzeit reaktivieren. Ich mache das nur so und kille die Logdatei für die Releaseversion.