Log.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 
32 #ifndef DRAIN_LOG_H_
33 #define DRAIN_LOG_H_
34 
35 #include <cstddef> // nullptr
36 #include <stdlib.h>
37 #include <sstream>
38 #include <string>
39 #include <iostream>
40 #include <fstream>
41 #include <stdexcept>
42 
43 //#include <ctime>
44 #include <sys/time.h>
45 #include <string.h> // strrchr()
46 
47 #include <syslog.h>
48 #include <map>
49 
50 #include "StringBuilder.h"
51 // #include "TextStyle.h"
52 #include "TextStyleVT100.h"
53 /*
54 #define LOG_EMERG 0 // system is unusable //
55 #define LOG_ALERT 1 // action must be taken immediately // RACK examples
56 #define LOG_CRIT 2 // critical conditions //
57 #define LOG_ERR 3 // error conditions // // File read/write failed
58 #define LOG_WARNING 4 // warning conditions // // HDF5 empty or contains no relevant data
59 #define LOG_NOTICE 5 // normal but significant condition // No volumes used for a composite
60 #define LOG_INFO 6 // informational // // Read/Write File, start/end of operator
61 #define LOG_DEBUG 7 // debug-level messages // Store variable
62  10 // Write control files (function input, output)
63  11 // Write intermediate results in files
64  15 // Debug 1D loops
65  20 // Debug 2D loops
66 
67 Compare with Python: https://docs.python.org/3/library/logging.html#logging-levels
68  */
69 
70 
71 /*
72 #ifdef __GNUC__
73  inline std::string className(const std::string & prettyFunction)
74  {
75  const size_t colons = prettyFunction.find("::");
76  if (colons == std::string::npos){
77  return "::";
78  }
79  else {
80  const size_t begin = prettyFunction.substr(0, colons).rfind(" ") + 1;
81  const size_t end = colons - begin;
82  return prettyFunction.substr(begin,end);
83  }
84 }
85 #define CLASSNAME className(__PRETTY_FUNCTION__)
86 #else
87 #define CLASSNAME __FILE__
88 #endif
89 */
90 
91 namespace drain {
92 
93 // using namespace std;
94 
95 struct Notification {
96 
97  /*
98  Notification(const std::string & key="", int vt100color=35){
99  set(key, vt100color);
100  };
101  */
102 
103  template <typename ... T>
104  Notification(const std::string & key, const T &... args){
105 
106  this->key = key;
107 
108  TextStyleVT100 vt100;
109  std::stringstream sstr;
110  //vt100.write(sstr, args..., key);
111  vt100.append(sstr, args...);
112  vt100color = sstr.str();
113  };
114 
115 
116  //void set(const std::string & key, int vt100color);
117 
118 
119  std::string key;
120  std::string vt100color;
121 
122 };
123 
124 // extern unsigned int Debug; // getting obsolete
125 
127 class Logger;
128 
130 
147 class Log {
148 
149 public:
150 
152  typedef unsigned short level_t;
153 
154  //typedef std::vector<Notification> notif_dict_t;
155  typedef std::map<int,std::string> status_dict_t;
156 
157  const
158  static status_dict_t statusDict;
159 
160  // experimental
161  int id = 0;
162 
164 
167  inline
168  Log(std::ostream & ostr=std::cerr, int verbosityLevel=LOG_WARNING) : ostrPtr(&ostr), verbosityLevel(verbosityLevel) // VT100(true),
169  {
170  resetTime();
171  //std::cerr << "start monitor, level=" << verbosityLevel << std::endl;
172  };
173 
174  inline
175  Log(const Log &m) : ostrPtr(m.ostrPtr), verbosityLevel(m.verbosityLevel) { // VT100(m.VT100),
176  resetTime();
177  };
178 
179  inline
180  ~Log(){
181  close(); // Note: external ofstream will not be closed.
182  /*
183  if (ostrPtr != nullptr){ // it never is...
184  ostrPtr->close();
185  }
186  */
187  }
188 
189 
190  inline
191  void setOstr(std::ostream & ostr){
192  /*
193  if (ostrPtr != nullptr){ // it never is...
194  ostrPtr->close();
195  }
196  */
197  close();
198  ostrPtr = &ostr;
199  }
200 
201  inline
202  void setOstr(const std::string & filename){
203  /*
204  if (ostrPtr != nullptr){ // it never is...
205  ostrPtr->close();
206  }
207  */
208  close();
209  ofstr.open(filename, std::ios::out);
210  ostrPtr = &ofstr;
211  }
212 
214  void close(){
215  if (ofstr.is_open()){
216  ostrPtr = nullptr; // or what, std::cerr ?
217  ofstr.close();
218  }
219  }
220 
221  //
222  inline
223  void setVerbosity(level_t level){
224  verbosityLevel = level;
225  };
226 
227  void setVerbosity(const std::string & level);
228 
229  inline
230  int getVerbosity() const {
231  return verbosityLevel;
232  };
233 
234  void flush(level_t level, const std::string & prefix, const std::stringstream & sstr);
235 
236  //void flush(level_t level, const Notification & notif, const std::string & prefix, const std::ostream & sstr);
237  void flush(level_t level, const Notification & notif, const std::string & prefix, const std::stringstream & sstr);
238 
239 
240  inline
241  long getRelativeMilliseconds(){
242  return getMilliseconds() - millisecondsStart;
243  }
244 
245  static inline
246  long getMilliseconds(){
247  timeval time;
248  gettimeofday(&time, NULL);
249  return (time.tv_sec * 1000) + (time.tv_usec / 1000);
250  }
251 
252  inline
253  void resetTime(){
254  millisecondsStart = getMilliseconds();
255  };
256 
257  static
258  bool USE_VT100; // = true;
259 
260  // static
261  // const notif_dict_t & getDict();
262 
263 protected:
264 
265  std::ostream *ostrPtr;
266 
267  std::ofstream ofstr;
268 
269  level_t verbosityLevel;
270 
271  long millisecondsStart;
272 
273  //drain::Dictionary<int, Notification> dict;
274 
275 };
276 
277 //extern Log monitor;
278 
279 Log & getLog();
280 
281 namespace image {
282 
283 Log & getImgLog();
284 
285 } // namespace image
286 
287 
288 class DrainException : public std::runtime_error {
289 
290 public:
291 
292 
293 
294  // Either this or previous is unneeded?
295  template<typename T,typename ... TT>
296  DrainException(const T &elem, const TT &... rest) : std::runtime_error(drain::StringBuilder<>(elem, rest...)){
297  }
298 
299 
300 };
301 
303 #define DRAIN_LOG_VAR(name) '#', #name, '=', name
304 
306 
309 //class Logger : public std::stringstream {
310 class Logger : public StreamBuilder<0> {
311 
312  std::stringstream & message;
313 
314 public:
315 
316 
317 
318  typedef Log::level_t level_t;
319 
321 
325  template <typename ... TT>
326  Logger(const char *filename, const TT & ...args);
327  //Logger(const char *filename, const std::string & name = "");
328 
330 
334  template <typename ... TT>
335  Logger(Log &log, const char *filename, const TT & ...args); //const char *className = NULL);
336  //Logger(Log &log, const char *filename, const std::string & name = ""); //const char *className = NULL);
337 
338  ~Logger();
339 
341 
345  inline
346  bool isLevel(level_t l){
347  return (monitor.getVerbosity() >= l);
348  };
349 
351 
355  inline
356  bool isDebug(level_t l=0){
357  return isLevel(LOG_DEBUG+l);
358  //return (monitor.getVerbosity() >= (LOG_DEBUG+l));
359  };
360 
361 
362 
364  template <int L, typename ... TT>
365  inline
366  Logger & start(const TT &... args){
367  static const Notification notif(__FUNCTION__, TextStyle::DIM); //, TextStyle::BOLD
368  initMessage<L>(notif);
369  flush(args...);
370  return *this;
371  };
372 
373 
375  template<typename ... TT>
376  inline
377  Logger & quit(const TT &... args){
378  static const Notification notif(__FUNCTION__, TextStyle::PURPLE, TextStyle::REVERSE, TextStyle::BOLD);
379  initMessage<LOG_EMERG>(notif);
380  flush(args...);
381  return *this;
382  };
383 
385  template<typename ... TT>
386  inline
387  Logger & alert(const TT &... args){
388  static const Notification notif(__FUNCTION__, TextStyle::PURPLE, TextStyle::BOLD);
389  initMessage<LOG_ALERT>(notif);
390  flush(args...);
391  return *this;
392  };
393 
395  template<typename ... TT>
396  inline
397  Logger & critical(const TT &... args){
398  static const Notification notif(__FUNCTION__, TextStyle::RED, TextStyle::REVERSE);
399  initMessage<LOG_CRIT>(notif);
400  flush(args...);
401  return *this;
402  };
403 
405  /*
406  inline
407  Logger & error(){
408  return initMessage<LOG_ERR>();
409  };
410  */
411 
412  template<typename ... TT>
413  inline
414  Logger & error(const TT &... args){
415  static const Notification notif(__FUNCTION__, TextStyle::RED, TextStyle::BOLD);
416  // error();
417  initMessage<LOG_ERR>(notif);
418  flush(args...);
419  return *this;
420  };
421 
422 
423  // LOG_WARNING
424 
426  template<typename ... TT>
427  inline
428  Logger & warn(const TT &... args){
429  // warn();
430  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::BOLD);
431  initMessage<LOG_WARNING>(notif);
432  flush(args...);
433  return *this;
434  };
435 
437  template<int L=LOG_WARNING,typename ... TT>
438  inline
439  Logger & discouraged(const TT &... args){
440  //static const Notification notif(__FUNCTION__, 35);
441  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM);
442  initMessage<L>(notif);
443  flush(args...);
444  return *this;
445  };
446 
447 
449  template<int L=LOG_WARNING,typename ... TT>
450  inline
451  Logger & fail(const TT &... args){
452  //static const Notification notif(__FUNCTION__, 33);
453  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM);
454  initMessage<L>(notif);
455  flush(args...);
456  return *this;
457  };
458 
460  // Valid alternative should be displayed.
461  template<int L=LOG_WARNING,typename ... TT>
462  inline
463  Logger & obsolete(const TT &... args){
464  //static const Notification notif(__FUNCTION__, 35);
465  static const Notification notif(__FUNCTION__, TextStyle::PURPLE, TextStyle::DIM, TextStyle::UNDERLINE);
466  initMessage<L>(notif);
467  flush(args...);
468  return *this;
469  };
470 
472  template<int L=LOG_WARNING,typename ... TT>
473  inline
474  Logger & attention(const TT &... args){
475  static const Notification notif(__FUNCTION__, TextStyle::CYAN, TextStyle::REVERSE, TextStyle::DIM); // 46);
476  initMessage<L>(notif);
477  flush(args...);
478  return *this;
479  };
480 
481 
482  // LOG_NOTICE
483 
485  template<typename ... TT>
486  inline
487  Logger & note(const TT &... args){
488  static const Notification notif(__FUNCTION__, TextStyle::BOLD);
489  initMessage<LOG_NOTICE>(notif);
490  //initMessage<LOG_NOTICE>();
491  flush(args...);
492  return *this;
493  };
494 
496  template<int L=LOG_NOTICE,typename ... TT>
497  inline
498  Logger & suspicious(const TT &... args){
499  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM);
500  initMessage<L>(notif);
501  flush(args...);
502  return *this;
503  };
504 
505 
507  template<int L=LOG_NOTICE,typename ... TT>
508  inline
509  Logger & unimplemented(const TT &... args){
510  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::OVERLINE); // , 35);
511  initMessage<L>(notif);
512  flush(args...);
513  return *this;
514  };
515 
517  template<int L=LOG_NOTICE,typename ... TT>
518  inline
519  Logger & deprecating(const TT &... args){
520  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM, TextStyle::UNDERLINE); //33);
521  initMessage<L>(notif);
522  flush(args...);
523  return *this;
524  };
525 
527  template<int L=LOG_NOTICE,typename ... TT>
528  inline
529  Logger & special(const TT &... args){
530  static const Notification notif(__FUNCTION__, TextStyle::CYAN); //36);
531  initMessage<L>(notif);
532  flush(args...);
533  return *this;
534  };
535 
536 
537  template<int L=LOG_NOTICE,typename ... TT>
538  inline
539  Logger & experimental(const TT &... args){
540  static const Notification notif(__FUNCTION__, TextStyle::CYAN, TextStyle::REVERSE); // 94);
541  initMessage<L>(notif);
542  flush(args...);
543  return *this;
544  };
545 
546  template<int L=LOG_NOTICE,typename ... TT>
547  inline
548  Logger & advice(const TT &... args){
549  static const Notification notif(__FUNCTION__, TextStyle::UNDERLINE);// 40);
550  initMessage<L>(notif);
551  flush(args...);
552  return *this;
553  };
554 
555 
556  // LOG_INFO
557 
558  template<typename ... TT>
559  inline
560  Logger & info(const TT &... args){
561  static const Notification notif(__FUNCTION__, TextStyle::WHITE); //32);
562  initMessage<LOG_INFO>(notif);
563  // initMessage<LOG_INFO>();
564  flush(args...);
565  return *this;
566  };
567 
568  template<int L=LOG_INFO,typename ... TT>
569  inline
570  Logger & ok(const TT &... args){
571  static const Notification notif(__FUNCTION__, TextStyle::GREEN); //32);
572  initMessage<L>(notif);
573  flush(args...);
574  return *this;
575  };
576 
578  template<int L=LOG_INFO,typename ... TT>
579  inline
580  Logger & accept(const TT &... args){
581  //static const Notification notif(__FUNCTION__, 42);
582  static const Notification notif(__FUNCTION__, TextStyle::GREEN, TextStyle::REVERSE, TextStyle::DIM);
583  initMessage<L>(notif);
584  flush(args...);
585  return *this;
586  };
587 
589 
592  template<int L=LOG_INFO,typename ... TT>
593  inline
594  Logger & pending(const TT &... args){
595  //static const Notification notif(__FUNCTION__, 42);
596  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::REVERSE, TextStyle::DIM);
597  initMessage<L>(notif);
598  flush(args...);
599  return *this;
600  };
601 
603 
606  template<int L=LOG_INFO,typename ... TT>
607  inline
608  Logger & reject(const TT &... args){
609  // static const Notification notif(__FUNCTION__, 41);
610  static const Notification notif(__FUNCTION__, TextStyle::RED, TextStyle::REVERSE, TextStyle::DIM);
611  initMessage<L>(notif);
612  flush(args...);
613  return *this;
614  };
615 
616 
618  template<int L=LOG_INFO,typename ... TT>
619  inline
620  Logger & success(const TT &... args){
621  // static const Notification notif(__FUNCTION__, 92);
622  static const Notification notif(__FUNCTION__, TextStyle::GREEN, TextStyle::DIM);
623  initMessage<L>(notif);
624  flush(args...);
625  return *this;
626  };
627 
628 
630  template<int L=LOG_INFO,typename ... TT>
631  inline
632  Logger & hint(const TT &... args){
633  static const Notification notif(__FUNCTION__, TextStyle::CYAN, TextStyle::DIM, TextStyle::UNDERLINE);
634  initMessage<L>(notif);
635  flush(args...);
636  return *this;
637  };
638 
639 
640  template<int L=LOG_INFO,typename ... TT>
641  inline
642  Logger & revised(const TT &... args){
643  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM);
644  initMessage<L>(notif);
645  flush(args...);
646  return *this;
647  };
648 
650  /*
651  template<typename ... TT>
652  inline
653  Logger & timing(const TT &... args){
654  static const Notification notif(__FUNCTION__, 7);
655  if (TIMING){ // ok here (also?)
656  initMessage<LOG_WARNING>(notif); // can be low, say WARNING level, because restricted with TIMING
657  flush(args...);
658  //std::cerr << args...;
659  };
660  return *this;
661  };
662  */
663 
664 
666 
676  template<typename ... TT>
677  inline
678  Logger & debug(const TT &... args){
679  static const Notification notif(__FUNCTION__, TextStyle::DIM);
680  initMessage<LOG_DEBUG>(notif);
681  flush(args...);
682  return *this;
683  };
684 
686  template<typename ... TT>
687  inline
688  Logger & debug2(const TT &... args){
689  static const Notification notif(__FUNCTION__, TextStyle::DIM, TextStyle::ITALIC);
690  initMessage<LOG_DEBUG+1>(notif);
691  flush(args...);
692  return *this;
693  };
694 
695  template<typename ... TT>
696  inline
697  Logger & debug3(const TT &... args){
698  static const Notification notif(__FUNCTION__, TextStyle::CYAN, TextStyle::DIM, TextStyle::ITALIC);
699  initMessage<LOG_DEBUG+2>(notif);
700  flush(args...);
701  return *this;
702  };
703 
704 
705  /*
706  inline
707  Logger & debug(level_t level){
708  static const Notification notif("DEBUG*", 49);
709  return initMessage<LOG_DEBUG+1>(notif); // obsolete
710  //return *this;
711  };
712  */
713 
714  inline
715  Logger & log(level_t level){
716  initMessage(level); // avoid
717  return *this;
718  };
719 
720  // Experimental! For mout.log(level)(args); !
721  template<typename ... TT>
722  inline
723  Logger & operator()(const TT &... args){
724  flush(args...);
725  return *this;
726  };
727 
728 
729  static bool TIMING; // = false;
730  static char MARKER;
731 
732  bool timing;
733 
735  //Logger & timestamp(const std::string & label);
736 
740  inline
741  void startTiming(){
742  if (TIMING && !timing){
743  initTiming(this->prefix);
744  }
745  };
746 
750  template<typename ... TT>
751  void startTiming(const TT &... args){
752  if (TIMING && !timing){ // consider error if already timing?
753  initTiming(args...);
754  }
755  };
756 
757  //template<typename ... TT>
758  //void endTiming(const TT &... args){
759  void endTiming(){
760  if (timing){
761  time = monitor.getMilliseconds() - time;
762  std::cerr << "TIMING:" << MARKER << "</div> ";
763  //describeTiming(args...); // STORE timing label?
764  // << ": "
765  std::cerr << "<b>" << (static_cast<float>(time)/1000.0f) << "</b>" << "<br/>" << '\n';
766  /*
767  std::cerr << "TIMING:" << MARKER << "</ol> ";
768  //describeTiming(args...); // STORE timing label?
769  // << ": "
770  std::cerr << "<b>" << (static_cast<float>(time)/1000.0f) << "</b>" << "</li>" << '\n';
771  */
772  timing = false;
773  }
774  }
775 
776 
777 public:
778 
779 
781  // Logger & timestamp();
782 
783 
785 
786  Logger &operator<<(const std::ostream & sstr) {
787  // TODO if (!message.empty())
788  if (level <= monitor.getVerbosity())
789  message << sstr.rdbuf();
790  return *this;
791  }
792 
793 
794 
795  template <class T>
796  Logger &operator<<(const T & x) {
797  //cerr << "source input:" << x << '\n';
798  if (level <= monitor.getVerbosity())
799  message << x;
800  return *this;
801  }
802 
803  typedef void * oper;
804  static oper endl;
805 
806 
807  inline
808  void end(){
809  monitor.flush(level, *notif_ptr, prefix, message);
810  }
811 
813  inline
814  Logger &operator<<(oper op){
815  monitor.flush(level, *notif_ptr, prefix, message);
816  return *this; // <- drop this?
817  }
818 
820  inline
821  Logger &operator<<(const Logger & l){
822 
823  if (&l != this){
824  message << " NOTE: Logger" << __FUNCTION__ << " flush with non-this Logger";
825  }
826  monitor.flush(level, *notif_ptr, prefix, message);
827  return *this;
828  }
829 
830  inline
831  int getVerbosity() const {
832  return monitor.getVerbosity();
833  };
834 
835 protected:
836 
837  Log & monitor;
838 
839  std::string prefix;
840 
841  level_t level;
842  time_t time;
843 
844  const Notification * notif_ptr;
845 
846 protected:
847 
848  template<typename ... TT>
849  void initTiming(const TT &... args){
850  timing = true; // consider error if already timing?
851  std::cerr << "TIMING:" << MARKER; // << "<li>";
852  describeTiming(args...);
853  // std::cerr << " [" << prefix << "] <ol>" << '\n';
854  //std::cerr << " <ol>" << '\n';
855  std::cerr << " <div>" << '\n';
856  time = monitor.getMilliseconds();
857  };
858 
859 
860  template<typename T, typename ... TT>
861  void describeTiming(const T & arg, const TT &... args){
862  std::cerr << arg;
863  describeTiming(args...);
864  };
865 
866  inline
867  void describeTiming(){
868  };
869 
878 
885  template<typename ... TT>
886  inline
887  //void setPrefix(const char * filename, const char * func_name, const TT &... args){
888  void setPrefix(const char * filename, const TT &... args){
889 
890  std::stringstream sstr;
891 
892  if (filename){
893 
894  if (*filename != '\0'){
895 
896  const char * s2 = strrchr(filename, '/');
897  if (s2 == nullptr)
898  s2 = filename;
899  else
900  ++s2;
901 
903  const char * s3 = strrchr(s2, '.');
904  if (s3 == nullptr)
905  sstr << s2;
906  //prefix.assign(s2);
907  else
908  //prefix.assign(s2, s3-s2);
909  sstr.write(s2, size_t(s3-s2));
910  // prefix.append(":");
911  // sstr << ':';
912  }
913  }
914  // NEW sstr << func_name << ": ";
915  //appendPrefix(sstr, func_name, args...);
916  appendPrefix(sstr, args...);
917  prefix = sstr.str();
918  }
919 
920  /*
921  template<typename T, typename ... TT>
922  inline
923  void setPrefix(const TT &... args){
924  std::stringstream sstr;
925  appendPrefix(sstr, args...);
926  prefix = sstr.str();
927  }
928  */
929 
930 
931  inline
932  void appendPrefix(std::stringstream & sstr){
933  }
934 
935  template<typename T, typename ... TT>
936  void appendPrefix(std::stringstream & sstr, const T & arg, const TT &... args){
937  sstr << ":" << arg;
938  appendPrefix(sstr, args...);
939  }
940 
941  template <level_t L>
942  Logger & initMessage(const Notification & notif){
943  this->notif_ptr = & notif;
944  this->level = L;
945  this->message.str("");
946  return *this;
947  }
948  //void initMessage(level_t level);
949 
950  /*
951  template <level_t L>
952  Logger & initMessage(){
953 
954  static
955  const Notification & notif = Log::getDict()[L];
956 
957  this->notif_ptr = &notif;
958  this->level = L;
959  this->message.str("");
960  return *this;
961  }
962  */
963 
965  Logger & initMessage(level_t level);
966 
967  /*
968  inline
969  Logger & initMessage(level_t level){
970  static const Notification notif(__FUNCTION__); // TextStyle::DIM, TextStyle::ITALIC);
971  this->notif_ptr = & notif; // Log::getDict()[level];
972  this->level = level;
973  this->message.str("");
974  return *this;
975  }
976  */
977 
978  template<typename T, typename ... TT>
979  inline
980  Logger & flush(const T & arg, const TT &... rest){
981  //*this << arg;
982  append(arg);
983  flush(rest...);
984  return *this;
985  };
986 
987  template<typename T>
988  inline
989  Logger & flush(const T & arg){
990  // *this << arg;
991  append(arg);
992  monitor.flush(level, *notif_ptr, prefix, message);
993  return *this;
994  };
995 
996  inline
997  Logger & flush(){
998  return *this;
999  };
1000 
1001  template<typename T>
1002  inline
1003  void append(const T & arg){
1004  *this << arg;
1005  }
1006 
1007  /*
1008  inline
1009  Logger & flush(){
1010  monitor.flush(level, *notif_ptr, prefix, message);
1011  return *this;
1012  };
1013  */
1014 
1015 
1016 };
1017 
1018 
1019 template <>
1020 inline
1021 void Logger::append(const TextStyle::Colour & colour){
1022  *this << "<color>";
1023 }
1024 
1025 
1026 template <typename ... TT>
1027 Logger::Logger(const char *filename, const TT & ...args):
1028  message(*this),
1029  timing(false),
1030  monitor(getLog()),
1031  level(LOG_NOTICE),
1032  time(getLog().getMilliseconds()),
1033  notif_ptr(NULL){
1034  setPrefix(filename, args...);
1035 }
1036 
1037 template <typename ... TT>
1038 Logger::Logger(Log &log, const char *filename, const TT & ...args):
1039  message(*this),
1040  timing(false),
1041  monitor(log),
1042  level(LOG_NOTICE),
1043  time(log.getMilliseconds()),
1044  notif_ptr(NULL){
1045  setPrefix(filename, args...);
1046 }
1047 //std::ostream &operator<<(std::ostream &ostr, const Log &error);
1048 
1049 
1050 }
1051 
1052 //const std::string FEELU(__FILE__);
1053 
1054 #endif /* DEBUG_H_ */
1055 
1056 // Drain
Definition: Log.h:288
Handler for notifications sent by a Logger.
Definition: Log.h:147
unsigned short level_t
Log verbosity level type.
Definition: Log.h:152
Log(std::ostream &ostr=std::cerr, int verbosityLevel=LOG_WARNING)
Definition: Log.h:168
void close()
Closes internal ofstr, if used. External ofstream will not be closed.
Definition: Log.h:214
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:310
Logger & deprecating(const TT &... args)
Feature will be removed. Special type of Logger::note().
Definition: Log.h:519
Logger & pending(const TT &... args)
Report a conditional accept/reject, to be completed next.
Definition: Log.h:594
Logger & success(const TT &... args)
Some processing step has completed with desired result.
Definition: Log.h:620
Logger & error(const TT &... args)
Echoes.
Definition: Log.h:414
bool isDebug(level_t l=0)
Returns true, if the debug level of the monitor is at least l.
Definition: Log.h:356
Logger & accept(const TT &... args)
Some input has been accepted, for example by a syntax.
Definition: Log.h:580
Logger & critical(const TT &... args)
Quits immediately, dumps pending messages.
Definition: Log.h:397
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition: Log.h:474
Logger & quit(const TT &... args)
Quits immediately, dumps pending messages.
Definition: Log.h:377
Logger & special(const TT &... args)
Other useful information.
Definition: Log.h:529
Logger & fail(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition: Log.h:451
Logger & operator<<(const Logger &l)
NEW: sending "mout" insread of "mout.endl" Handling flush operator.
Definition: Log.h:821
Logger & reject(const TT &... args)
Some input has been rejected, for example by a syntax.
Definition: Log.h:608
void setPrefix(const char *filename, const TT &... args)
Sets a label that starts every line in the log.
Definition: Log.h:888
void startTiming(const TT &... args)
Definition: Log.h:751
void startTiming()
Send a short [INFO] preceded with a time stamp.
Definition: Log.h:741
Logger & operator<<(oper op)
Handling flush operator.
Definition: Log.h:814
bool isLevel(level_t l)
Returns true, if the log monitor level is at least l.
Definition: Log.h:346
Logger & alert(const TT &... args)
Quits immediately, dumps pending messages.
Definition: Log.h:387
Logger & obsolete(const TT &... args)
Feature has been removed. Special type of Logger::warn().
Definition: Log.h:463
Logger(const char *filename, const TT &...args)
Start logging,.
Definition: Log.h:1027
Logger & operator<<(const std::ostream &sstr)
Send a longer [INFO] preceded with a time stamp.
Definition: Log.h:786
Logger & discouraged(const TT &... args)
Warning on user's convention or action that can potentially cause errors or confusions.
Definition: Log.h:439
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition: Log.h:509
Logger & note(const TT &... args)
For top-level information.
Definition: Log.h:487
Logger & start(const TT &... args)
General.
Definition: Log.h:366
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:428
Logger & debug(const TT &... args)
Public, yet typically used "internally", when TIMING=true.
Definition: Log.h:678
Logger & hint(const TT &... args)
Like advice, but weaker.
Definition: Log.h:632
Logger & suspicious(const TT &... args)
A weak warning about something going possibly wrong.
Definition: Log.h:498
Logger & debug2(const TT &... args)
Debug information.
Definition: Log.h:688
Definition: StreamBuilder.h:59
Definition: StringBuilder.h:58
Definition: TextStyleVT100.h:45
Definition: DataSelector.cpp:1277
Definition: Log.h:95