Imported Upstream version 17.28.8
[platform/upstream/libzypp.git] / zypp-core / base / LogControl.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/base/LogControl.h
10  *
11 */
12 #ifndef ZYPP_BASE_LOGCONTROL_H
13 #define ZYPP_BASE_LOGCONTROL_H
14
15 #include <iosfwd>
16 #include <ostream> //for std::endl
17
18 #include <zypp-core/base/Logger.h>
19 #include <zypp-core/base/PtrTypes.h>
20 #include <zypp-core/Pathname.h>
21
22 ///////////////////////////////////////////////////////////////////
23 namespace zypp
24 { /////////////////////////////////////////////////////////////////
25
26   ///////////////////////////////////////////////////////////////////
27   namespace log
28   { /////////////////////////////////////////////////////////////////
29
30     /** If you want to log the (formated) loglines by yourself,
31      *  derive from this, and overload \c writeOut.
32      * Expect \a formated_r to be a formated log line without trailing \c NL.
33      * Ready to be written to the log.
34      */
35     struct LineWriter
36     {
37       virtual void writeOut( const std::string & /*formated_r*/ )
38       {}
39       virtual ~LineWriter()
40       {}
41     };
42
43     /** Base class for ostream based \ref LineWriter */
44     struct StreamLineWriter : public LineWriter
45     {
46       StreamLineWriter( std::ostream & str_r ) : _str( &str_r ) {}
47
48       virtual void writeOut( const std::string & formated_r )
49       { (*_str) << formated_r << std::endl; }
50
51       protected:
52         StreamLineWriter() : _str( 0 ) {}
53         std::ostream *_str;
54     };
55
56     /** \ref LineWriter to stdout. */
57     struct StdoutLineWriter : public StreamLineWriter
58     {
59       StdoutLineWriter();
60     };
61
62     /** \ref LineWriter to stderr. */
63     struct StderrLineWriter : public StreamLineWriter
64     {
65       StderrLineWriter();
66     };
67
68     /** \ref LineWriter to file.
69      * If \c mode_r is not \c 0, \c file_r persissions are changed
70      * accordingly. \c "-" logs to \c cerr.
71     */
72     struct FileLineWriter : public StreamLineWriter
73     {
74       FileLineWriter( const Pathname & file_r, mode_t mode_r = 0 );
75       protected:
76         shared_ptr<void> _outs;
77     };
78
79     /////////////////////////////////////////////////////////////////
80   } // namespace log
81   ///////////////////////////////////////////////////////////////////
82
83
84   ///////////////////////////////////////////////////////////////////
85   namespace base
86   { /////////////////////////////////////////////////////////////////
87
88     ///////////////////////////////////////////////////////////////////
89     //
90     //  CLASS NAME : LogControl
91     //
92     /** Maintain logfile related options.
93      * \note A Singleton using a Singleton implementation class,
94      * that's why there is no _pimpl like in other classes.
95     */
96     class LogControl
97     {
98       friend std::ostream & operator<<( std::ostream & str, const LogControl & obj );
99
100     public:
101       /** Singleton access. */
102       static LogControl instance()
103       { return LogControl(); }
104
105
106       /** \see \ref log::LineWriter */
107       typedef log::LineWriter LineWriter;
108
109       /** If you want to format loglines by yourself,
110        *  derive from this, and overload \c format.
111        * Return a formated logline without trailing \c NL.
112        * Ready to be written to the log.
113       */
114       struct LineFormater
115       {
116         virtual std::string format( const std::string & /*group_r*/,
117                                     logger::LogLevel    /*level_r*/,
118                                     const char *        /*file_r*/,
119                                     const char *        /*func_r*/,
120                                     int                 /*line_r*/,
121                                     const std::string & /*message_r*/ );
122         virtual ~LineFormater() {}
123       };
124
125     public:
126       /** Assign a LineFormater.
127        * If you want to format loglines by yourself. NULL installs the
128        * default formater.
129       */
130       void setLineFormater( const shared_ptr<LineFormater> & formater_r );
131
132     public:
133       /** Set path for the logfile.
134        * Permission for logfiles is set to 0640 unless an explicit mode_t
135        * value is given. An empty pathname turns off logging. <tt>"-"</tt>
136        * logs to std::err.
137        * \throw if \a logfile_r is not usable.
138       */
139       void logfile( const Pathname & logfile_r );
140       void logfile( const Pathname & logfile_r, mode_t mode_r );
141
142       /** Turn off logging. */
143       void logNothing();
144
145       /** Log to std::err. */
146       void logToStdErr();
147
148       /** will cause the log thread to exit and flush all sockets */
149       void emergencyShutdown();
150
151       /**
152        *  This will completely disable logging,
153        *  its supposed to be called in the child process after fork()
154        *  was called to shut down all logging completely
155        */
156       static void notifyFork();
157
158     public:
159       /** Get the current LineWriter */
160       shared_ptr<LineWriter> getLineWriter() const;
161
162       /** Assign a LineWriter.
163        * If you want to log the (formated) loglines by yourself.
164        * NULL turns off logging (same as logNothing)
165        * \see \ref log::LineWriter
166        */
167       void setLineWriter( const shared_ptr<LineWriter> & writer_r );
168
169     public:
170       /** Turn on excessive logging for the lifetime of this object.*/
171       struct TmpExcessive
172       {
173         TmpExcessive();
174         ~TmpExcessive();
175       };
176
177       /** Exchange LineWriter for the lifetime of this object.
178        * \see \ref log::LineWriter
179       */
180       struct TmpLineWriter
181       {
182         TmpLineWriter( const shared_ptr<LineWriter> & writer_r = shared_ptr<LineWriter>() )
183           : _writer( LogControl::instance().getLineWriter() )
184         { LogControl::instance().setLineWriter( writer_r ); }
185
186         /** Convenience ctor taking over ownership of an allocated LineWriter.
187          *\code
188          * TmpLineWriter mylw( new log::StderrLineWriter );
189          * \endcode
190         */
191         template<class TLineWriter>
192         TmpLineWriter( TLineWriter * _allocated_r )
193           : _writer( LogControl::instance().getLineWriter() )
194         { LogControl::instance().setLineWriter( shared_ptr<LineWriter>( _allocated_r ) ); }
195
196         ~TmpLineWriter()
197         { LogControl::instance().setLineWriter( _writer ); }
198
199       private:
200         shared_ptr<LineWriter> _writer;
201       };
202
203     private:
204       /** Default ctor: Singleton */
205       LogControl()
206       {}
207     };
208     ///////////////////////////////////////////////////////////////////
209
210     /** \relates LogControl Stream output */
211     std::ostream & operator<<( std::ostream & str, const LogControl & obj );
212
213     /////////////////////////////////////////////////////////////////
214   } // namespace base
215   ///////////////////////////////////////////////////////////////////
216   /////////////////////////////////////////////////////////////////
217 } // namespace zypp
218 ///////////////////////////////////////////////////////////////////
219 #endif // ZYPP_BASE_LOGCONTROL_H