Logging
-
Warum nicht gleich boost::log?
-
Die WS Streamweiche hat er schon in Post 4 angeboten bekommen (und abgelehnt)

-
padreigh schrieb:
Die WS Streamweiche hat er schon in Post 4 angeboten bekommen (und abgelehnt)

aber da (vrmtl) auch nur, weil er dachte, er müsse sie auf std::cout anwenden.
-
das mit std::cerr könnte klappen. Das probiere ich mal die Tage.
ich teste gerade log4cxx (bin bisher aber nicht begeistert)
mfg
-
Ich hab das jetzt mal versucht zu realisieren..aber es klappt noch nciht so ganz.
ich nutzte die aus dem anderen Forum bekannte Weiche als Klasse cWeiche!
class cLogStream { public: cLogStream(std::ofstream *fOStream); std::ostream& operator<<(const std::string &fString); protected: std::ofstream * m_stream; cWeiche m_Weiche; };cLogStream::cLogStream(std::ofstream *fOStream) : m_stream(fOStream), m_Weiche(std::cerr, *fOStream) { }; std::ostream& cLogStream::operator<<(const std::string &fString) { if (!m_stream) { std::cout << "Error: cLogStream --> m_stream==NULL\n" << std::flush; } return *m_stream << fString << std::flush; }jetzt nutze ich die Klasse im Main wie folgt
{ std::ofstream *aStream=nLog::getFileStream("holgers.log"); nLog::cLogStream mStream(aStream); std::cerr << "1\n" ; std::cerr << "2\n" ; std::cerr << "3\n" ; std::cerr << "4\n" ; mStream << "5\n"; mStream << "6\n"; mStream << "7\n"; mStream << "8\n"; mStream << "9\n"; std::cerr << "10\n" << std::flush ; std::cerr << "11\n" << std::flush; }Auf dem bildschirme rscheint nun, wie gewollt
1
2
3
4
10
11aber in der Datei erscheint nur
1
2
3
4
5
6
7
8
9In der Datei fehlen die Ausgaben 10 und 11
Hat jemand eine Idee?
-
wieder mal im testprogramm vergessen den pointer zu löschen.
nach löschen des Pointers geht es..
Ein herzliches Dankeschön an alle, die mir geholfen haben.
-
Gibt es irgendwelche begrenzungen mit der Weiche?
ich hab gearde nen Crash gehabt wo das core-File tausende zeilen hat die irgendwie so aussehen
#949 0xb74a3f3a in std::basic_streambuf<char, std::char_traits<char> >::sputc (this=0x82e167c, __c=42 '*')
at /usr/local/crosstool/crosstool-0.43/build/i686-unknown-linux-gnu/gcc-4.2.1-glibc-2.3.6/build-gcc/i686-unknown-linux-gnu/libstdc++-v3/include/streambuf:430
#950 0xb75ca6de in nLog::cWeiche::overflow (this=0x82bbcb4, c=42) at /users/holger/workspace_rsn/mil/awu/sm/smoswa/smoswa_utils/log_stream.h:95
^C#951 0xb74a3f3a in std::basic_streambuf<char, std::char_traits<char> >::sputc (this=QuitHa<t jemand eine Idee was da schief geht?
-
HeroHolger schrieb:
Gibt es irgendwelche begrenzungen mit der Weiche?
ich hab gearde nen Crash gehabt wo das core-File tausende zeilen hat die irgendwie so aussehen
#949 0xb74a3f3a in std::basic_streambuf<char, std::char_traits<char> >::sputc (this=0x82e167c, __c=42 '*')
at /usr/local/crosstool/crosstool-0.43/build/i686-unknown-linux-gnu/gcc-4.2.1-glibc-2.3.6/build-gcc/i686-unknown-linux-gnu/libstdc++-v3/include/streambuf:430
#950 0xb75ca6de in nLog::cWeiche::overflow (this=0x82bbcb4, c=42) at /users/holger/workspace_rsn/mil/awu/sm/smoswa/smoswa_utils/log_stream.h:95
^C#951 0xb74a3f3a in std::basic_streambuf<char, std::char_traits<char> >::sputc (this=QuitHa<t jemand eine Idee was da schief geht?
ich vermute mal, dass Du den Scope verlassen hast, in dem sich das ofstream-Objekt befindet, auf das Du logging-Ausgabe machen willst. Die beiden ostream-Objekte (z.B.: cout, ofstream) sollten sich im selben Scope wie das Weiche-Objekt oder einem übergeordneten Scope (cout ist global) befinden.
Andere Möglichkeit: Du greifst aus mehreren Threads ungeschützt und gleichzeitig auf das Logging-File zu.
-
k dann kommen wir zur Frage aller Fragen.
1.) ist diese Weiche Thread-sicher?
2.) was passiert wenn in einem anderen Thread oder außerhalb meines Bereiches/Scopes jemand std::cerr nutzt? geht es dann schief? cerr soll doch nur bei mir in der Datei landen.
-
Es erscheint, dass die Weiche definitiv nicht zum komplexen loggen geeignet ist.
denn nun wird pauschal, überall im Programm cerr in die Datei geschrieben, obwohl ich es garnicht will.
Also das bringt es nicht.
ich bin jetzt am implementieren von log4cxx
das scheint gut zu gehen.
Thread kann zu gemacht werden
-
Ist echt schwer, der weiche noch nen dtor zu verpassen...
template< typename C, typename T = std::char_traits<C> > class duplexer : public std::basic_streambuf<C, T> { public: typedef std::basic_streambuf<C, T> base_type; typedef typename base_type::traits_type traits_type; duplexer(std::basic_ostream<char_type, traits_type>& source, std::basic_ostream<char_type, traits_type>& duplicate) : streambuf_one(source.rdbuf()), streambuf_two(duplicate.rdbuf()), output(source) { source.rdbuf(this); } ~duplexer() { output.rdbuf(streambuf_one); } protected: virtual int_type overflow(int_type c = traits_type::eof()) { if(!streambuf_one || !streambuf_two) return traits_type::eof(); int_type first = streambuf_one->sputc( static_cast<char_type>(c) ); int_type second = streambuf_two->sputc( static_cast<char_type>(c) ); if(traits_type::eq_int_type(first, traits_type::eof()) || traits_type::eq_int_type(second, traits_type::eof())) return traits_type::eof(); return traits_type::not_eof(c); } private: duplexer(const duplexer&); duplexer& operator= (const duplexer&); base_type* streambuf_one; base_type* streambuf_two; std::basic_ostream<char_type, traits_type>& output; };das hab ich vor einiger zeit mal aus der weiche gemacht gehabt.
habs zwar nicht oft verwendet gehabt, aber es sollte schon alles fehlerfrei gehen
zu verwenden:
int main() { std::ofstream file("asd.txt"); { duplexer<char> foo(std::clog, file); std::clog << "ich steh in file und konsole" << std::endl; file << "ich stehe nur im file" << std::endl; } std::clog << "ich stehe nur auf der konsole" << std::endl; file << "ich stehe nur im file" << std::endl; { duplexer<char> foo(std::clog, file); std::clog << "ich steh in file und konsole" << std::endl; file << "ich stehe nur im file" << std::endl; } }bb
edit: ich seh gerade, dass der gcc das vrmtl nicht compilieren wird, da typedefs nicht mitgeerbt werden - da der msvc das aber "kann", fehlt hier halt das
typedef base_type::int_type int_type;
-
@unskilled,
Das will er ja anscheinend auch nicht.@HeroHolger,
Wo bitte schön, war denn nun wieder das Problem?int main() { std::ofstream logfile("thefile.txt"); Weiche weiche(std::cerr, logfile); // so, ab jetzt alles was in std::cerr geht, kommt auf der Konsole und geht ins File. }Das ist doch, was du wolltest? Es soll global sein, du willst
std::coutweiterhin bneutzen können, ohne dass es ins File geht, es soll aber ein weiterer Stream existieren, welcher alles auf die Konsole und in das File schreibt.Das ganze ist nicht threadsicher, weil der aktuelle C++ Standards nicht mal weiss, was Threads sind.
Grüssli