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 
302 
304 
307 //class Logger : public std::stringstream {
308 class Logger : public StreamBuilder<0> {
309 
310  std::stringstream & message;
311 
312 public:
313 
314 
315 
316  typedef Log::level_t level_t;
317 
319 
323  template <typename ... TT>
324  Logger(const char *filename, const TT & ...args);
325  //Logger(const char *filename, const std::string & name = "");
326 
328 
332  template <typename ... TT>
333  Logger(Log &log, const char *filename, const TT & ...args); //const char *className = NULL);
334  //Logger(Log &log, const char *filename, const std::string & name = ""); //const char *className = NULL);
335 
336  ~Logger();
337 
339 
343  inline
344  bool isLevel(level_t l){
345  return (monitor.getVerbosity() >= l);
346  };
347 
349 
353  inline
354  bool isDebug(level_t l=0){
355  return isLevel(LOG_DEBUG+l);
356  //return (monitor.getVerbosity() >= (LOG_DEBUG+l));
357  };
358 
359 
360 
362  template <int L, typename ... TT>
363  inline
364  Logger & start(const TT &... args){
365  static const Notification notif(__FUNCTION__, TextStyle::DIM); //, TextStyle::BOLD
366  initMessage<L>(notif);
367  flush(args...);
368  return *this;
369  };
370 
371 
373  template<typename ... TT>
374  inline
375  Logger & quit(const TT &... args){
376  static const Notification notif(__FUNCTION__, TextStyle::PURPLE, TextStyle::REVERSE, TextStyle::BOLD);
377  initMessage<LOG_EMERG>(notif);
378  flush(args...);
379  return *this;
380  };
381 
383  template<typename ... TT>
384  inline
385  Logger & alert(const TT &... args){
386  static const Notification notif(__FUNCTION__, TextStyle::PURPLE, TextStyle::BOLD);
387  initMessage<LOG_ALERT>(notif);
388  flush(args...);
389  return *this;
390  };
391 
393  template<typename ... TT>
394  inline
395  Logger & critical(const TT &... args){
396  static const Notification notif(__FUNCTION__, TextStyle::RED, TextStyle::REVERSE);
397  initMessage<LOG_CRIT>(notif);
398  flush(args...);
399  return *this;
400  };
401 
403  /*
404  inline
405  Logger & error(){
406  return initMessage<LOG_ERR>();
407  };
408  */
409 
410  template<typename ... TT>
411  inline
412  Logger & error(const TT &... args){
413  static const Notification notif(__FUNCTION__, TextStyle::RED, TextStyle::BOLD);
414  // error();
415  initMessage<LOG_ERR>(notif);
416  flush(args...);
417  return *this;
418  };
419 
420 
421  // LOG_WARNING
422 
424  template<typename ... TT>
425  inline
426  Logger & warn(const TT &... args){
427  // warn();
428  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::BOLD);
429  initMessage<LOG_WARNING>(notif);
430  flush(args...);
431  return *this;
432  };
433 
435  template<int L=LOG_WARNING,typename ... TT>
436  inline
437  Logger & discouraged(const TT &... args){
438  //static const Notification notif(__FUNCTION__, 35);
439  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM);
440  initMessage<L>(notif);
441  flush(args...);
442  return *this;
443  };
444 
445 
447  template<int L=LOG_WARNING,typename ... TT>
448  inline
449  Logger & fail(const TT &... args){
450  //static const Notification notif(__FUNCTION__, 33);
451  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM);
452  initMessage<L>(notif);
453  flush(args...);
454  return *this;
455  };
456 
458  // Valid alternative should be displayed.
459  template<int L=LOG_WARNING,typename ... TT>
460  inline
461  Logger & obsolete(const TT &... args){
462  //static const Notification notif(__FUNCTION__, 35);
463  static const Notification notif(__FUNCTION__, TextStyle::PURPLE, TextStyle::DIM, TextStyle::UNDERLINE);
464  initMessage<L>(notif);
465  flush(args...);
466  return *this;
467  };
468 
470  template<int L=LOG_WARNING,typename ... TT>
471  inline
472  Logger & attention(const TT &... args){
473  static const Notification notif(__FUNCTION__, TextStyle::CYAN, TextStyle::REVERSE, TextStyle::DIM); // 46);
474  initMessage<L>(notif);
475  flush(args...);
476  return *this;
477  };
478 
479 
480  // LOG_NOTICE
481 
483  template<typename ... TT>
484  inline
485  Logger & note(const TT &... args){
486  static const Notification notif(__FUNCTION__, TextStyle::BOLD);
487  initMessage<LOG_NOTICE>(notif);
488  //initMessage<LOG_NOTICE>();
489  flush(args...);
490  return *this;
491  };
492 
494  template<int L=LOG_NOTICE,typename ... TT>
495  inline
496  Logger & suspicious(const TT &... args){
497  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM);
498  initMessage<L>(notif);
499  flush(args...);
500  return *this;
501  };
502 
503 
505  template<int L=LOG_NOTICE,typename ... TT>
506  inline
507  Logger & unimplemented(const TT &... args){
508  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::OVERLINE); // , 35);
509  initMessage<L>(notif);
510  flush(args...);
511  return *this;
512  };
513 
515  template<int L=LOG_NOTICE,typename ... TT>
516  inline
517  Logger & deprecating(const TT &... args){
518  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM, TextStyle::UNDERLINE); //33);
519  initMessage<L>(notif);
520  flush(args...);
521  return *this;
522  };
523 
525  template<int L=LOG_NOTICE,typename ... TT>
526  inline
527  Logger & special(const TT &... args){
528  static const Notification notif(__FUNCTION__, TextStyle::CYAN); //36);
529  initMessage<L>(notif);
530  flush(args...);
531  return *this;
532  };
533 
534 
535  template<int L=LOG_NOTICE,typename ... TT>
536  inline
537  Logger & experimental(const TT &... args){
538  static const Notification notif(__FUNCTION__, TextStyle::CYAN, TextStyle::REVERSE); // 94);
539  initMessage<L>(notif);
540  flush(args...);
541  return *this;
542  };
543 
544  template<int L=LOG_NOTICE,typename ... TT>
545  inline
546  Logger & advice(const TT &... args){
547  static const Notification notif(__FUNCTION__, TextStyle::UNDERLINE);// 40);
548  initMessage<L>(notif);
549  flush(args...);
550  return *this;
551  };
552 
553 
554  // LOG_INFO
555 
556  template<typename ... TT>
557  inline
558  Logger & info(const TT &... args){
559  static const Notification notif(__FUNCTION__, TextStyle::WHITE); //32);
560  initMessage<LOG_INFO>(notif);
561  // initMessage<LOG_INFO>();
562  flush(args...);
563  return *this;
564  };
565 
566  template<int L=LOG_INFO,typename ... TT>
567  inline
568  Logger & ok(const TT &... args){
569  static const Notification notif(__FUNCTION__, TextStyle::GREEN); //32);
570  initMessage<L>(notif);
571  flush(args...);
572  return *this;
573  };
574 
576  template<int L=LOG_INFO,typename ... TT>
577  inline
578  Logger & accept(const TT &... args){
579  //static const Notification notif(__FUNCTION__, 42);
580  static const Notification notif(__FUNCTION__, TextStyle::GREEN, TextStyle::REVERSE, TextStyle::DIM);
581  initMessage<L>(notif);
582  flush(args...);
583  return *this;
584  };
585 
587 
590  template<int L=LOG_INFO,typename ... TT>
591  inline
592  Logger & pending(const TT &... args){
593  //static const Notification notif(__FUNCTION__, 42);
594  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::REVERSE, TextStyle::DIM);
595  initMessage<L>(notif);
596  flush(args...);
597  return *this;
598  };
599 
601 
604  template<int L=LOG_INFO,typename ... TT>
605  inline
606  Logger & reject(const TT &... args){
607  // static const Notification notif(__FUNCTION__, 41);
608  static const Notification notif(__FUNCTION__, TextStyle::RED, TextStyle::REVERSE, TextStyle::DIM);
609  initMessage<L>(notif);
610  flush(args...);
611  return *this;
612  };
613 
614 
616  template<int L=LOG_INFO,typename ... TT>
617  inline
618  Logger & success(const TT &... args){
619  // static const Notification notif(__FUNCTION__, 92);
620  static const Notification notif(__FUNCTION__, TextStyle::GREEN, TextStyle::DIM);
621  initMessage<L>(notif);
622  flush(args...);
623  return *this;
624  };
625 
626 
628  template<int L=LOG_INFO,typename ... TT>
629  inline
630  Logger & hint(const TT &... args){
631  static const Notification notif(__FUNCTION__, TextStyle::CYAN, TextStyle::DIM, TextStyle::UNDERLINE);
632  initMessage<L>(notif);
633  flush(args...);
634  return *this;
635  };
636 
637 
638  template<int L=LOG_INFO,typename ... TT>
639  inline
640  Logger & revised(const TT &... args){
641  static const Notification notif(__FUNCTION__, TextStyle::YELLOW, TextStyle::DIM);
642  initMessage<L>(notif);
643  flush(args...);
644  return *this;
645  };
646 
648  /*
649  template<typename ... TT>
650  inline
651  Logger & timing(const TT &... args){
652  static const Notification notif(__FUNCTION__, 7);
653  if (TIMING){ // ok here (also?)
654  initMessage<LOG_WARNING>(notif); // can be low, say WARNING level, because restricted with TIMING
655  flush(args...);
656  //std::cerr << args...;
657  };
658  return *this;
659  };
660  */
661 
662 
664 
674  template<typename ... TT>
675  inline
676  Logger & debug(const TT &... args){
677  static const Notification notif(__FUNCTION__, TextStyle::DIM);
678  initMessage<LOG_DEBUG>(notif);
679  flush(args...);
680  return *this;
681  };
682 
684  template<typename ... TT>
685  inline
686  Logger & debug2(const TT &... args){
687  static const Notification notif(__FUNCTION__, TextStyle::DIM, TextStyle::ITALIC);
688  initMessage<LOG_DEBUG+1>(notif);
689  flush(args...);
690  return *this;
691  };
692 
693  template<typename ... TT>
694  inline
695  Logger & debug3(const TT &... args){
696  static const Notification notif(__FUNCTION__, TextStyle::CYAN, TextStyle::DIM, TextStyle::ITALIC);
697  initMessage<LOG_DEBUG+2>(notif);
698  flush(args...);
699  return *this;
700  };
701 
702 
703  /*
704  inline
705  Logger & debug(level_t level){
706  static const Notification notif("DEBUG*", 49);
707  return initMessage<LOG_DEBUG+1>(notif); // obsolete
708  //return *this;
709  };
710  */
711 
712  inline
713  Logger & log(level_t level){
714  initMessage(level); // avoid
715  return *this;
716  };
717 
718  // Experimental! For mout.log(level)(args); !
719  template<typename ... TT>
720  inline
721  Logger & operator()(const TT &... args){
722  flush(args...);
723  return *this;
724  };
725 
726 
727  static bool TIMING; // = false;
728  static char MARKER;
729 
730  bool timing;
731 
733  //Logger & timestamp(const std::string & label);
734 
738  inline
739  void startTiming(){
740  if (TIMING && !timing){
741  initTiming(this->prefix);
742  }
743  };
744 
748  template<typename ... TT>
749  void startTiming(const TT &... args){
750  if (TIMING && !timing){ // consider error if already timing?
751  initTiming(args...);
752  }
753  };
754 
755  //template<typename ... TT>
756  //void endTiming(const TT &... args){
757  void endTiming(){
758  if (timing){
759  time = monitor.getMilliseconds() - time;
760  std::cerr << "TIMING:" << MARKER << "</div> ";
761  //describeTiming(args...); // STORE timing label?
762  // << ": "
763  std::cerr << "<b>" << (static_cast<float>(time)/1000.0f) << "</b>" << "<br/>" << '\n';
764  /*
765  std::cerr << "TIMING:" << MARKER << "</ol> ";
766  //describeTiming(args...); // STORE timing label?
767  // << ": "
768  std::cerr << "<b>" << (static_cast<float>(time)/1000.0f) << "</b>" << "</li>" << '\n';
769  */
770  timing = false;
771  }
772  }
773 
774 
775 public:
776 
777 
779  // Logger & timestamp();
780 
781 
783 
784  Logger &operator<<(const std::ostream & sstr) {
785  // TODO if (!message.empty())
786  if (level <= monitor.getVerbosity())
787  message << sstr.rdbuf();
788  return *this;
789  }
790 
791 
792 
793  template <class T>
794  Logger &operator<<(const T & x) {
795  //cerr << "source input:" << x << '\n';
796  if (level <= monitor.getVerbosity())
797  message << x;
798  return *this;
799  }
800 
801  typedef void * oper;
802  static oper endl;
803 
804 
805  inline
806  void end(){
807  monitor.flush(level, *notif_ptr, prefix, message);
808  }
809 
811  inline
812  Logger &operator<<(oper op){
813  monitor.flush(level, *notif_ptr, prefix, message);
814  return *this; // <- drop this?
815  }
816 
818  inline
819  Logger &operator<<(const Logger & l){
820 
821  if (&l != this){
822  message << " NOTE: Logger" << __FUNCTION__ << " flush with non-this Logger";
823  }
824  monitor.flush(level, *notif_ptr, prefix, message);
825  return *this;
826  }
827 
828  inline
829  int getVerbosity() const {
830  return monitor.getVerbosity();
831  };
832 
833 protected:
834 
835  Log & monitor;
836 
837  std::string prefix;
838 
839  level_t level;
840  time_t time;
841 
842  const Notification * notif_ptr;
843 
844 protected:
845 
846  template<typename ... TT>
847  void initTiming(const TT &... args){
848  timing = true; // consider error if already timing?
849  std::cerr << "TIMING:" << MARKER; // << "<li>";
850  describeTiming(args...);
851  // std::cerr << " [" << prefix << "] <ol>" << '\n';
852  //std::cerr << " <ol>" << '\n';
853  std::cerr << " <div>" << '\n';
854  time = monitor.getMilliseconds();
855  };
856 
857 
858  template<typename T, typename ... TT>
859  void describeTiming(const T & arg, const TT &... args){
860  std::cerr << arg;
861  describeTiming(args...);
862  };
863 
864  inline
865  void describeTiming(){
866  };
867 
876 
883  template<typename ... TT>
884  inline
885  //void setPrefix(const char * filename, const char * func_name, const TT &... args){
886  void setPrefix(const char * filename, const TT &... args){
887 
888  std::stringstream sstr;
889 
890  if (filename){
891 
892  if (*filename != '\0'){
893 
894  const char * s2 = strrchr(filename, '/');
895  if (s2 == nullptr)
896  s2 = filename;
897  else
898  ++s2;
899 
901  const char * s3 = strrchr(s2, '.');
902  if (s3 == nullptr)
903  sstr << s2;
904  //prefix.assign(s2);
905  else
906  //prefix.assign(s2, s3-s2);
907  sstr.write(s2, size_t(s3-s2));
908  // prefix.append(":");
909  // sstr << ':';
910  }
911  }
912  // NEW sstr << func_name << ": ";
913  //appendPrefix(sstr, func_name, args...);
914  appendPrefix(sstr, args...);
915  prefix = sstr.str();
916  }
917 
918  /*
919  template<typename T, typename ... TT>
920  inline
921  void setPrefix(const TT &... args){
922  std::stringstream sstr;
923  appendPrefix(sstr, args...);
924  prefix = sstr.str();
925  }
926  */
927 
928 
929  inline
930  void appendPrefix(std::stringstream & sstr){
931  }
932 
933  template<typename T, typename ... TT>
934  void appendPrefix(std::stringstream & sstr, const T & arg, const TT &... args){
935  sstr << ":" << arg;
936  appendPrefix(sstr, args...);
937  }
938 
939  template <level_t L>
940  Logger & initMessage(const Notification & notif){
941  this->notif_ptr = & notif;
942  this->level = L;
943  this->message.str("");
944  return *this;
945  }
946  //void initMessage(level_t level);
947 
948  /*
949  template <level_t L>
950  Logger & initMessage(){
951 
952  static
953  const Notification & notif = Log::getDict()[L];
954 
955  this->notif_ptr = &notif;
956  this->level = L;
957  this->message.str("");
958  return *this;
959  }
960  */
961 
963  Logger & initMessage(level_t level);
964 
965  /*
966  inline
967  Logger & initMessage(level_t level){
968  static const Notification notif(__FUNCTION__); // TextStyle::DIM, TextStyle::ITALIC);
969  this->notif_ptr = & notif; // Log::getDict()[level];
970  this->level = level;
971  this->message.str("");
972  return *this;
973  }
974  */
975 
976  template<typename T, typename ... TT>
977  inline
978  Logger & flush(const T & arg, const TT &... rest){
979  //*this << arg;
980  append(arg);
981  flush(rest...);
982  return *this;
983  };
984 
985  template<typename T>
986  inline
987  Logger & flush(const T & arg){
988  // *this << arg;
989  append(arg);
990  monitor.flush(level, *notif_ptr, prefix, message);
991  return *this;
992  };
993 
994  inline
995  Logger & flush(){
996  return *this;
997  };
998 
999  template<typename T>
1000  inline
1001  void append(const T & arg){
1002  *this << arg;
1003  }
1004 
1005  /*
1006  inline
1007  Logger & flush(){
1008  monitor.flush(level, *notif_ptr, prefix, message);
1009  return *this;
1010  };
1011  */
1012 
1013 
1014 };
1015 
1016 
1017 template <>
1018 inline
1019 void Logger::append(const TextStyle::Colour & colour){
1020  *this << "<color>";
1021 }
1022 
1023 
1024 template <typename ... TT>
1025 Logger::Logger(const char *filename, const TT & ...args):
1026  message(*this),
1027  timing(false),
1028  monitor(getLog()),
1029  level(LOG_NOTICE),
1030  time(getLog().getMilliseconds()),
1031  notif_ptr(NULL){
1032  setPrefix(filename, args...);
1033 }
1034 
1035 template <typename ... TT>
1036 Logger::Logger(Log &log, const char *filename, const TT & ...args):
1037  message(*this),
1038  timing(false),
1039  monitor(log),
1040  level(LOG_NOTICE),
1041  time(log.getMilliseconds()),
1042  notif_ptr(NULL){
1043  setPrefix(filename, args...);
1044 }
1045 //std::ostream &operator<<(std::ostream &ostr, const Log &error);
1046 
1047 
1048 }
1049 
1050 //const std::string FEELU(__FILE__);
1051 
1052 #endif /* DEBUG_H_ */
1053 
1054 // 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:308
Logger & deprecating(const TT &... args)
Feature will be removed. Special type of Logger::note().
Definition: Log.h:517
Logger & pending(const TT &... args)
Report a conditional accept/reject, to be completed next.
Definition: Log.h:592
Logger & success(const TT &... args)
Some processing step has completed with desired result.
Definition: Log.h:618
Logger & error(const TT &... args)
Echoes.
Definition: Log.h:412
bool isDebug(level_t l=0)
Returns true, if the debug level of the monitor is at least l.
Definition: Log.h:354
Logger & accept(const TT &... args)
Some input has been accepted, for example by a syntax.
Definition: Log.h:578
Logger & critical(const TT &... args)
Quits immediately, dumps pending messages.
Definition: Log.h:395
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition: Log.h:472
Logger & quit(const TT &... args)
Quits immediately, dumps pending messages.
Definition: Log.h:375
Logger & special(const TT &... args)
Other useful information.
Definition: Log.h:527
Logger & fail(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition: Log.h:449
Logger & operator<<(const Logger &l)
NEW: sending "mout" insread of "mout.endl" Handling flush operator.
Definition: Log.h:819
Logger & reject(const TT &... args)
Some input has been rejected, for example by a syntax.
Definition: Log.h:606
void setPrefix(const char *filename, const TT &... args)
Sets a label that starts every line in the log.
Definition: Log.h:886
void startTiming(const TT &... args)
Definition: Log.h:749
void startTiming()
Send a short [INFO] preceded with a time stamp.
Definition: Log.h:739
Logger & operator<<(oper op)
Handling flush operator.
Definition: Log.h:812
bool isLevel(level_t l)
Returns true, if the log monitor level is at least l.
Definition: Log.h:344
Logger & alert(const TT &... args)
Quits immediately, dumps pending messages.
Definition: Log.h:385
Logger & obsolete(const TT &... args)
Feature has been removed. Special type of Logger::warn().
Definition: Log.h:461
Logger(const char *filename, const TT &...args)
Start logging,.
Definition: Log.h:1025
Logger & operator<<(const std::ostream &sstr)
Send a longer [INFO] preceded with a time stamp.
Definition: Log.h:784
Logger & discouraged(const TT &... args)
Warning on user's convention or action that can potentially cause errors or confusions.
Definition: Log.h:437
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition: Log.h:507
Logger & note(const TT &... args)
For top-level information.
Definition: Log.h:485
Logger & start(const TT &... args)
General.
Definition: Log.h:364
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Logger & debug(const TT &... args)
Public, yet typically used "internally", when TIMING=true.
Definition: Log.h:676
Logger & hint(const TT &... args)
Like advice, but weaker.
Definition: Log.h:630
Logger & suspicious(const TT &... args)
A weak warning about something going possibly wrong.
Definition: Log.h:496
Logger & debug2(const TT &... args)
Debug information.
Definition: Log.h:686
Definition: StreamBuilder.h:59
Definition: StringBuilder.h:58
Definition: TextStyleVT100.h:45
Definition: DataSelector.cpp:1277
Definition: Log.h:95